FreeBSD’s support for Amazon Web Services (AWS) is better than ever. This short tutorial shows you how to create a FreeBSD 10 instance (VM) on Amazon Elastic Cloud Compute (EC2) and use it to serve web pages. This tutorial assumes basic Unix knowledge and familiarity with ssh. All AWS prices mentioned are correct as of September 2015, but are obviously subject to change,

Launching FreeBSD on AWS

Log into the AWS console: You will be prompted to create an account if you don’t have one. Once you’ve logged in you’ll be presented with the AWS dashboard. Select “EC2”: it should be under “Compute” at the top left of the screen.

Step 1: Choose an Amazon Machine Image (AMI)

Select “AWS Marketplace” on the left-hand side of the screen and search for “FreeBSD”. Select “FreeBSD 10 sold by Colin Percival” (see screenshot, below):

The first time you select FreeBSD you’ll get a marketplace overview page for it. There is no cost for using it beyond what Amazon charges for running on their infrastructure. Scroll to the bottom and click “Continue”.

Step 2: Choose an Instance Type

On the this screen you’ll be given a choice of instance type. This determines the CPU, ram, I/O and cost of your instance. If you’re just experimenting then the t2.micro type is ideal. t2.micro instances are free tier eligible or around 1¢ per hour otherwise. Select the instance type then click “Next: Configure Instance Details”.

Step 3: Configure Instance Details

All the defaults on this step should be fine. You can click on “Next: Add Storage”.

Step 4: Add Storage

Change the storage size to 10 GB. This gives a decent amount of space to experiment. Leave the other settings as they are and select “Next: Tag Instance”.

Step 5: Tag Instance

Add a name for your instance to make it easy to identify in the AWS console, for example “FreeBSD Web Server”. In production you would probably set this to be the same as your hostname, but there’s no reason it has to be.

Step 6: Configure Security Group

AWS security groups provide a firewall between your server and the Internet. By default all access is blocked. To enable ssh (port 22) and web (port 80) we need to add two rules. Select “Create a new security group” and add a name and description. Next add the two rules, one for SSH and one for HTTP (see screenshot, below).

Ideally the SSH rule should be for your specific IP or network, whilst the HTTP rule can use “Anywhere” as the source. If you’re on a dynamic IP and just experimenting you can select “Anywhere” for SSH access (for production servers make sure you restrict access).

### Step 7: Review Instance Launch

This screen summarises your choices. Read through it and make sure you’re happy with your settings. Click on the “Launch” button. You will be prompted to create/select a key (it should have the .pem extension). If you create a key be sure to save it in a safe place: you’ll need it to connect to your server.

You will then see a screen with “Initiating Instance Launches” (the first time you use a given marketplace image this step may take a minute or so). This will then switch to a “Launch Status” screen where it says “Your instances are now launching”. Click on the ID of your instance in the message (it looks like i-1a2b3c4d) and it will take you to your instance in the AWS console.

Connecting to Your FreeBSD Server

To connect to your server you need the SSH key (created above) and the server’s public IP address from the AWS console (see screenshot, above). Connect with the following command (replacing KEY_NAME.pem and IP_ADDRESS as appropriate):

ssh -i KEY_NAME.pem ec2-user@IP_ADDRESS

Once connected you’ll find yourself at a shell prompt. If ssh hangs when trying to connect you should check the rule in your security group for SSH. You can change rules in “Security Groups” on the left-hand side of the EC2 page in the AWS console.

The shell prompt is from the Bourne shell (sh); not the most friendly of shells for interactive use. We’re going to install Bash using the FreeBSD package management system. To install packages we need to become root using su. We then make use of the pkg command:

$ su -
root@ip:~ # pkg install bash

You’ll be prompted to confirm installation then advised to enable fdescfs. Run the mount command:

root@ip:~ # mount -t fdescfs fdesc /dev/fd 

This applies until the next boot. If you’re keeping your instance around you should update /etc/fstab as described in the message from pkg.

We can now run bash and check some details on our system:

root@ip:~ # bash

[root@ip ~]# freebsd-version 

[root@ip ~]# df -h
Filesystem         Size    Used   Avail Capacity  Mounted on
/dev/gpt/rootfs    9.7G    1.1G    7.8G    12%    /
devfs              1.0K    1.0K      0B   100%    /dev
fdescfs            1.0K    1.0K      0B   100%    /dev/fd

[root@ip ~]# sysctl -n hw.model
Intel(R) Xeon(R) CPU E5-2670 v2 @ 2.50GHz

[root@ip ~]# sysctl -n hw.ncpu

[root@ip ~]# sysctl -n hw.realmem

In this case our server we are running FreeBSD 10.2 with patch -p2. The 10 GiB disk we created has 7.8 GiB available. The server has one Xeon E5-2670 v2 core and 1 GiB ram (1073741824 bytes). To learn a bit more about your system try the following commands:

  • top
  • pkg info
  • ifconfig

If you’re familiar with Linux you should check out the FreeBSD Quickstart Guide for Linux Users.

Setting up a Web Server

We’re going to use nginx to serve web pages. First we need to install the package:

[root@ip ~]# pkg install nginx

Then start nginx with:

[root@ip ~]# service nginx onestart

You can now browse your server at http://IP_ADDRESS

You should see a “Welcome to nginx!” page.

You can stop nginx with:

[root@ip ~]# service nginx onestop

To enable nginx at boot you add the following line to the bottom of /etc/rc.conf:


NB. The vi editor is available in the base system. If you’d rather use another editor you can easily install it with pkg install nano or similar.

Once enabled you can start/stop nginx with:

[root@ip ~]# service nginx start

[root@ip ~]# service nginx stop

For this tutorial I’m not going to look into the details of configuring your own web site with nginx. For that I recommend you try the nginx configuration primer. As nginx is a package (not part of the base system) its configuration files are in /usr/local/etc/nginx on FreeBSD.

Stopping, Starting and Terminating

You can use the shutdown command to stop your server (be sure to use the -p to fully stop your VM or Amazon will keep charging you):

[root@ip ~]# shutdown -p "Powering off for now. This server is being stopped."

In this state your server disk is saved and you pay for storage costs ($1/month for 10 GB), but not the hourly charge to run it.

To start your server again, go to EC2 in the AWS console and select your server. Under “Actions > Instance State” choose “Start”. NB. Each time you start your server it will get a different IP address! It’s easy to get caught out by this, so be careful (rebooting won’t change your IP though).

To permanently terminate your server you need to select it in the AWS console, then under “Actions > Instance State” choose “Terminate”. This will permanently remove you server and its disk.

## Updating

FreeBSD is updated via two separate mechanisms. The base system is updated with freebsd-update and the packages with pkg. On AWS your FreeBSD base system will have been updated when you first booted it. If you later need to apply updates you run:

[root@ip ~]# freebsd-update fetch
[root@ip ~]# freebsd-update install

Then reboot your system with:

[root@ip ~]# shutdown -r "Rebooting server to apply patches."

To update your packages run:

[root@ip ~]# pkg upgrade

There is no need to reboot, but you may need to restart services (e.g. restart nginx if it’s updated).

For more details on updating see the FreeBSD handbook.

NB. Prior to FreeBSD 10 it wasn’t possible to update AWS instances with freebsd-update as it didn’t use the GENERIC kernel. This is no longer the case and you can safely use freebsd-update on AWS.


I hope you’ve found this brief introduction useful. For general advice on using FreeBSD the best place to look is the handbook. I’ll be writing more about FreeBSD on AWS over the coming months, so stay tuned. Finally, special thanks to Colin Percival for making FreeBSD on AWS possible.