Running Docker on Amazon EC2

As I am currently evaluating the three bigger cloud providers (Amazon AWS, Microsoft Azure and Google Cloud Platform) I came up with the idea to test how easy it would be to get Docker running on those providers. In this tutorial I deal with Amazon “AWS”, as I like them most out of the three mentioned.

On 23th of April 2014, Amazon added Docker support for their AWS Elastic Beanstalk, but this time, we will just focus on the EC2, not only due to cost issues.

The idea is to stay with the servers that are available at no charge (The so called “free tier”, which can run 24/7 for free within the first year). Of course, you can go for any other server instance as you like and need.

First we will set-up a small server instance on the EC2 service, followed by the docker set-up and the deployment of one example docker container.

Get the server instance up

  1. Login to your AWS Management Console
    The Amazon AWS Login page

    The Amazon AWS Login page

  2. Choose EC2 – the virtual servers in the Cloud on the Web Services Overview.
The service overview of Amazon AWS

The service overview of Amazon AWS

  • On the next screen, we are going to create a new instance via „Launch instance“.
  • Creating a new instance of a virtual server on Amazon EC2

    Creating a new instance of a virtual server on Amazon EC2

  •  You may choose any of the images presented there, but I will go for the Ubuntu Server 14.04 with LTS. Press „Select“ here.
  • Ubuntu Server 14.04 instance on AWS

    Ubuntu Server 14.04 instance on AWS

  • On the next screen, you can get an overview of the available instances. They are categorized in instance families, like „computing optimized“ or „memory optimized“. Just choose which one you need for your Docker host. In my case I went for the free tier eligible micro instance „t1.micro“ that is powerful enough to test web servers or even a non-powerful Tomcat instance. To configure in detail, just take the „Next: Configure Instance Details“ button here.
  • A list of instance types on AWS EC2

    A list of instance types on AWS EC2

  • In the next screen, we just select the „Protect against accidental termination“. You may also create a new subnet here, or choose one already existing, so your machines may communicate with each other through an internal network and not through the Internet.
  • AWS EC2 Instance Details

    AWS EC2 Instance Details

  • At the storage page, you can add up to30GB taken from your general purpose SSD to the machine. – Just remove the „delete on termination“, to persist the machine, even after termination. In this case, I added 10GB of space here. Be aware, that these 10 GB actually means that you have 30 IOPS. Those are the maximum input-output operations per second and they scale with the size of your disc. So this will be enough for a small webserver, but of course not for an production system.
  • Adding a Storage to your instance

    Adding a Storage to your instance

  • I left the tagging of the instance out. You can add some tags with values here, but they are not needed in this case of setting up a Docker server.
  • Step 6 – „Configure Security Group“ will need our attention. What I do here is to configure the ports 80 and 443 (for HTTP and HTTPS) to the outer world, and all other traffic only to my specific IP. This can of course be changed later on. Depending on the desired purpose you can add other specific ports here or setting a tougher security policy. I will for instance log in to the AWS console and change the security rule to my current IP address as often I need it. So, feel free to set it up as you need it and keep this settings in mind when launching Docker containers later on.
  • Setting up the EC2 Security Groups

    Setting up the EC2 Security Groups

  • After that you will see a summary, where you are able to launch your new configured instance. Just check, that everything was configured the right way and press “Launch” in the lower right corner.
  • Step 7 - Review Instance Launch

    Step 7 – Review Instance Launch

  • You will be asked about the way you would like to connect to your machine. If this is the first time, setting a machine up, you have to choose “Create a new Key Pair” here. Give it a speaking name and download the key pair to your computer to a save place and make a backup of them. You will need it every time to connect to your server instance. In my case, the key file is named MyDockerInstance.pem. I have those files stored in a encrypted container file created by Truecrypt. You might secure this file.
  • Creating a key pair for EC2

    Creating a key pair for EC2

  • After pressing “Launch instances”, open your Current running instances. You will see your currently set-up instance initializing.
  • Launching your instance

    Launching your instance

    In the table above, you will also find the currently assigned public IP through which we can connect to the machine, when the instance state is switching to “running”.

    First connection to your newly created machine

    To connect to the just created virtual machine we will utilize Putty. Depending on your operating system you might have to choose another method. As I am currently working under Windows, I went for this way. Just search for „ssh connection pem <your operating system>“ to find a proper way to connect via SSH to the machine.

    When installing Putty, also install Putty Key Generator, as this software is needed to import the OpenSSH SSH-2 private key and save it as a private key, so Putty can use this newly created connection file for the connection.

    1. Open Putty Gen and Select „File -> Open“. When selecting your Key, you will see the following notice:
    OpenSSH SSH-2 private key imported

    OpenSSH SSH-2 private key imported

  • I strongly advise you to add a key phrase here to enhance security. After that select „Save Private Key“
  • Putty - Key Generator

    Putty – Key Generator

  • In the next step, we will save the connection to Putty. First, open Putty and open Data under the Connection settings. Add „ubuntu“ as a user name here (only valid, when you have choosen Ubuntu as your template for the machine creation).
  • Putty: Auto login name

    Putty: Auto login name

  • In the SSH – Auth settings, load your private key file
  • Putty - SSH Auth Options

    Putty – SSH Auth Options

  • Now switch to the session settings and enter add your public IP address and save the session for later use.
  • Putty - Session Settings

    Putty – Session Settings

  • Choose “open” and accept the following security alert:
  • Putty: Security Alert

    Putty: Security Alert

  • In the following screen, enter your passphrase and press Enter. You are now connected to your virtual Ubuntu server running on Amazons EC2 service.
  • Putty: Connection established

    Putty: Connection established

    Setup Docker

    After the installation and first login to our newly created server it is the time to get Docker running.  First, we update the sources, followed by installing the package.

    ubuntu@ip-172-31-18-33:~$ sudo apt-get update
    Ign trusty InRelease
    Ign trusty-updates InRelease
    Get:1 trusty Release.gpg 
    [933 B] Get:2 trusty-updates Release.gpg [933 B] Get:3 trusty Release [58.5 kB] Get:4 trusty-updates Release [58.5 kB] Ign trusty-security InRelease Get:5 trusty/main Sources [1,064 kB] Get:6 trusty-security Release.gpg [933 B] Get:7 trusty/universe Sources [6,399 kB] Get:8 trusty-security Release [58.5 kB] Get:9 trusty-security/main Sources [20.6 kB] Get:10 trusty/main amd64 Packages [1,350 kB] Get:11 trusty-security/universe Sources [4,727 B] Get:12 trusty-security/main amd64 Packages [61.3 kB] Get:13 trusty/universe amd64 Packages [5,859 kB] Get:14 trusty-security/universe amd64 Packages [21.5 kB] Get:15 trusty-security/main Translation-en [29.9 kB] Get:16 trusty-security/universe Translation-en [11.3 kB]

    Running this command will additionaly load some other packages that are needed to get Docker running:

    ubuntu@ip-172-31-18-33:~$ sudo apt-get install
    Reading package lists... Done
    Building dependency tree
    Reading state information... Done
    The following extra packages will be installed:
      aufs-tools cgroup-lite git git-man liberror-perl
    Suggested packages:
      btrfs-tools debootstrap lxc rinse git-daemon-run git-daemon-sysvinit git-doc
      git-el git-email git-gui gitk gitweb git-arch git-bzr git-cvs git-mediawiki
    The following NEW packages will be installed:
      aufs-tools cgroup-lite git git-man liberror-perl
    0 upgraded, 6 newly installed, 0 to remove and 63 not upgraded.
    Need to get 7,096 kB of archives.
    After this operation, 44.2 MB of additional disk space will be used.
    Do you want to continue? [Y/n] Y

    Setting an symbolic link from to the docker executable

    ubuntu@ip-172-31-18-33:~$ sudo ln -sf /usr/bin/ /usr/local/bin/docker

    After that, we will just add the docker binary to the bash completion, so we can „tab“ through the possible parameters when typing the docker command on command line:

    ubuntu@ip-172-31-18-33:~$ sudo sed -i '$acomplete -F _docker docker' /etc/bash_completion.d/

    The next and last step will run /bin/bash terminal inside of a standard Ubuntu image. As the image wasn´t downloaded so far, it will be pulled from the repository. When this process is finished, we will directly connect to the newly created docker instance as root. To leave the instance later on, just type „exit“ on the command line and you will be back to your host system.

    ubuntu@ip-172-31-18-33:~$ sudo docker run -i -t ubuntu /bin/bash
    Unable to find image 'ubuntu' locally
    Pulling repository ubuntu

     Example of setting up a simple nginx container

    To set up a nginx web server on docker, you might create a Dockerfile by your own or (in first stage) rely on other people who already did this process for you. In this tutorial, I simple run a docker container from the user „orchardup“. You can find additional information on the docker-nginx github page.

    First, we clone the git repository to our server:

    ubuntu@ip-172-31-18-33:/data$ sudo git clone
    Cloning into 'docker-nginx'...
    remote: Reusing existing pack: 19, done.
    remote: Total 19 (delta 0), reused 0 (delta 0)
    Unpacking objects: 100% (19/19), done.
    Checking connectivity... done.

    Second, we will build the container from the newly created Dockerfile in the sub-folder „docker-nginx“.

    ubuntu@ip-172-31-18-33:/data/docker-nginx$ sudo docker build -t nginx-test .
    Uploading context 92.16 kB
    Uploading context
    Step 0 : FROM stackbrew/ubuntu:12.04
    Pulling repository stackbrew/ubuntu
     ---> ebe4be4dd427
    Step 1 : MAINTAINER Ben Firshman ""
     ---> Running in 6e8fde334b78
     ---> 7d592d26526a

    After that building process, we can run the server:

    ubuntu@ip-172-31-18-33:/data/docker-nginx$ sudo docker run -p 80:80 -d nginx-test
    ubuntu@ip-172-31-18-33:/data/docker-nginx$ curl localhost
    <head><title>500 Internal Server Error</title></head>
    <body bgcolor="white">
    <center><h1>500 Internal Server Error</h1></center>

    If you connect to your machine, it will look like the following, as no content was added to the /var/www directory:

    500 Internal Server error

    500 Internal Server error

    To change this, we will slightly change the Dockerfile and run the build process again.

    The following command will add a additional „RUN“ command to the Dockerfile. This command will add a file in the web server root directory and fill this file with content.

    ubuntu@ip-172-31-18-33:/data/docker-nginx$ sudo sed '9iRUN mkdir /var/www & echo "test page running on docker" > /var/www/index.html' Dockerfile -i

    So we are stopping the currently running container, rebuild it and than run it again in the next steps. The following command unhides the container ID, so we can stop the container after that.

    ubuntu@ip-172-31-18-33:/data/docker-nginx$ sudo docker ps
    CONTAINER ID        IMAGE               COMMAND             CREATED             STATUS              PORTS                NAMES
    8cb2e531f2d4        nginx-test:latest   nginx               About an hour ago   Up About an hour>80/tcp   pensive_turing

    Stopping the container, by knowing its ID:

    ubuntu@ip-172-31-18-33:/data/docker-nginx$ sudo docker stop 8cb2e531f2d4

    Now we are going to rebuild the container, just as before. You will recognize, that the container is created from cache with very low latency. It will be available almost instantly.

    ubuntu@ip-172-31-18-33:/data/docker-nginx$ sudo docker build -t nginx-test .
    Uploading context 92.16 kB
    Uploading context
    Step 0 : FROM stackbrew/ubuntu:12.04
     ---> ebe4be4dd427
    Step 1 : MAINTAINER Ben Firshman ""
     ---> Using cache
     ---> 7d592d26526a
    Step 2 : RUN apt-get update -qq && apt-get -y install nginx
     ---> Using cache
     ---> 0ccfb0aefe91
    Step 3 : RUN echo "daemon off;" >> /etc/nginx/nginx.conf
     ---> Using cache
     ---> b697a3929004
    Step 4 : RUN mkdir /etc/nginx/ssl
     ---> Using cache
     ---> 9b1c9a72de25
    Step 5 : ADD default /etc/nginx/sites-available/default
     ---> Using cache
     ---> 51eb0c8540f6
    Step 6 : ADD default-ssl /etc/nginx/sites-available/default-ssl
     ---> Using cache
     ---> 1316ef1cac80
    Step 7 : RUN mkdir /var/www
     ---> Using cache
     ---> 3fdb134dea09
    Step 8 : RUN echo "test page running on docker" > /var/www/index.html
     ---> Using cache
     ---> 6ab8f01d7674
    Step 9 : EXPOSE 80
     ---> Running in 991eb7949c4a
     ---> ff123b5ce755
    Step 10 : CMD ["nginx"]
     ---> Running in 84110614b631
     ---> 7bbe60073b4d
    Successfully built 7bbe60073b4d
    Removing intermediate container 991eb7949c4a
    Removing intermediate container 84110614b631

    In the last two steps, we are going to run the container and check, if the newly created index.html is available or not:

    ubuntu@ip-172-31-18-33:/data/docker-nginx$ sudo docker run -p 80:80 -d nginx-test

    With curl, we test that the web server is serving our new page.

    ubuntu@ip-172-31-18-33:/data/docker-nginx$ curl localhost
    test page running on docker


    Im conclusion to this tutorial, we set-up a micro server instance on Amazon EC2 service and installed there. In addition we launched an simple nginx web server, serving a static html file.

    2019-01-03T16:47:19+02:00Tags: , , , , |

    Share This Story, Choose Your Platform!

    Leave A Comment