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
- Login to your AWS Management Console
- Choose EC2 – the virtual servers in the Cloud on the Web Services Overview.
- On the next screen, we are going to create a new instance via „Launch instance“.
- You may choose any of the images presented there, but I will go for the Ubuntu Server 14.04 with LTS. Press „Select“ here.
- 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.
- 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.
- 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.
- 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.
- 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.
- 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.
- After pressing “Launch instances”, open your Current running instances. You will see your currently set-up instance initializing.
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.
- Open Putty Gen and Select „File -> Open“. When selecting your Key, you will see the following notice:
- I strongly advise you to add a key phrase here to enhance security. After that select „Save Private Key“
- 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).
- In the SSH – Auth settings, load your private key file
- Now switch to the session settings and enter add your public IP address and save the session for later use.
- Choose “open” and accept the following 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.
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 docker.io package.1234567891011121314151617181920ubuntu@ip-172-31-18-33:~$ sudo apt-get updateIgn http://eu-west-1.ec2.archive.ubuntu.com trusty InReleaseIgn http://eu-west-1.ec2.archive.ubuntu.com trusty-updates InReleaseGet:1 http://eu-west-1.ec2.archive.ubuntu.com trusty Release.gpg [/fusion_builder_column][fusion_builder_column type="1_1" background_position="left top" background_color="" border_size="" border_color="" border_style="solid" spacing="yes" background_image="" background_repeat="no-repeat" padding="" margin_top="0px" margin_bottom="0px" class="" id="" animation_type="" animation_speed="0.3" animation_direction="left" hide_on_mobile="no" center_content="no" min_height="none"][933 B]Get:2 http://eu-west-1.ec2.archive.ubuntu.com trusty-updates Release.gpg [933 B]Get:3 http://eu-west-1.ec2.archive.ubuntu.com trusty Release [58.5 kB]Get:4 http://eu-west-1.ec2.archive.ubuntu.com trusty-updates Release [58.5 kB]Ign http://security.ubuntu.com trusty-security InReleaseGet:5 http://eu-west-1.ec2.archive.ubuntu.com trusty/main Sources [1,064 kB]Get:6 http://security.ubuntu.com trusty-security Release.gpg [933 B]Get:7 http://eu-west-1.ec2.archive.ubuntu.com trusty/universe Sources [6,399 kB]Get:8 http://security.ubuntu.com trusty-security Release [58.5 kB]Get:9 http://security.ubuntu.com trusty-security/main Sources [20.6 kB]Get:10 http://eu-west-1.ec2.archive.ubuntu.com trusty/main amd64 Packages [1,350 kB]Get:11 http://security.ubuntu.com trusty-security/universe Sources [4,727 B]Get:12 http://security.ubuntu.com trusty-security/main amd64 Packages [61.3 kB]Get:13 http://eu-west-1.ec2.archive.ubuntu.com trusty/universe amd64 Packages [5,859 kB]Get:14 http://security.ubuntu.com trusty-security/universe amd64 Packages [21.5 kB]Get:15 http://security.ubuntu.com trusty-security/main Translation-en [29.9 kB]Get:16 http://security.ubuntu.com trusty-security/universe Translation-en [11.3 kB]
Running this command will additionaly load some other packages that are needed to get Docker running:12345678910111213141516ubuntu@ip-172-31-18-33:~$ sudo apt-get install docker.ioReading package lists... DoneBuilding dependency treeReading state information... DoneThe following extra packages will be installed:aufs-tools cgroup-lite git git-man liberror-perlSuggested packages:btrfs-tools debootstrap lxc rinse git-daemon-run git-daemon-sysvinit git-docgit-el git-email git-gui gitk gitweb git-arch git-bzr git-cvs git-mediawikigit-svnThe following NEW packages will be installed:aufs-tools cgroup-lite docker.io git git-man liberror-perl0 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 docker.io to the docker executable1ubuntu@ip-172-31-18-33:~$ sudo ln -sf /usr/bin/docker.io /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:1ubuntu@ip-172-31-18-33:~$ sudo sed -i '$acomplete -F _docker docker' /etc/bash_completion.d/docker.io
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.12345ubuntu@ip-172-31-18-33:~$ sudo docker run -i -t ubuntu /bin/bashUnable to find image 'ubuntu' locallyPulling repository ubuntu[…]root@ffed5fefcca3:/#
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:123456ubuntu@ip-172-31-18-33:/data$ sudo git clone https://github.com/orchardup/docker-nginxCloning 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“.12345678910ubuntu@ip-172-31-18-33:/data/docker-nginx$ sudo docker build -t nginx-test .Uploading context 92.16 kBUploading contextStep 0 : FROM stackbrew/ubuntu:12.04Pulling repository stackbrew/ubuntu[…]---> ebe4be4dd427Step 1 : MAINTAINER Ben Firshman "email@example.com"---> Running in 6e8fde334b78---> 7d592d26526a
After that building process, we can run the server:1234567891011ubuntu@ip-172-31-18-33:/data/docker-nginx$ sudo docker run -p 80:80 -d nginx-test8cb2e531f2d49fbef4487571290af0be72c1734883b6b95ebbb0457eaf153896ubuntu@ip-172-31-18-33:/data/docker-nginx$ curl localhost<html><head><title>500 Internal Server Error</title></head><body bgcolor="white"><center><h1>500 Internal Server Error</h1></center><hr><center>nginx/1.1.19</center></body></html>ubuntu@ip-172-31-18-33:/data/docker-nginx$
If you connect to your machine, it will look like the following, as no content was added to the /var/www directory:
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.1ubuntu@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 -i123ubuntu@ip-172-31-18-33:/data/docker-nginx$ sudo docker psCONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES8cb2e531f2d4 nginx-test:latest nginx About an hour ago Up About an hour 0.0.0.0:80->80/tcp pensive_turing12ubuntu@ip-172-31-18-33:/data/docker-nginx$ sudo docker stop 8cb2e531f2d48cb2e531f2d41234567891011121314151617181920212223242526272829303132333435363738ubuntu@ip-172-31-18-33:/data/docker-nginx$ sudo docker build -t nginx-test .Uploading context 92.16 kBUploading contextStep 0 : FROM stackbrew/ubuntu:12.04---> ebe4be4dd427Step 1 : MAINTAINER Ben Firshman "firstname.lastname@example.org"---> Using cache---> 7d592d26526aStep 2 : RUN apt-get update -qq && apt-get -y install nginx---> Using cache---> 0ccfb0aefe91Step 3 : RUN echo "daemon off;" >> /etc/nginx/nginx.conf---> Using cache---> b697a3929004Step 4 : RUN mkdir /etc/nginx/ssl---> Using cache---> 9b1c9a72de25Step 5 : ADD default /etc/nginx/sites-available/default---> Using cache---> 51eb0c8540f6Step 6 : ADD default-ssl /etc/nginx/sites-available/default-ssl---> Using cache---> 1316ef1cac80Step 7 : RUN mkdir /var/www---> Using cache---> 3fdb134dea09Step 8 : RUN echo "test page running on docker" > /var/www/index.html---> Using cache---> 6ab8f01d7674Step 9 : EXPOSE 80---> Running in 991eb7949c4a---> ff123b5ce755Step 10 : CMD ["nginx"]---> Running in 84110614b631---> 7bbe60073b4dSuccessfully built 7bbe60073b4dRemoving intermediate container 991eb7949c4aRemoving intermediate container 84110614b63112ubuntu@ip-172-31-18-33:/data/docker-nginx$ sudo docker run -p 80:80 -d nginx-testc4ad018d822cd3d641878f5d004a778d38a4ebbfcd6ab38bf16d19ee7721973d12ubuntu@ip-172-31-18-33:/data/docker-nginx$ curl localhosttest page running on docker
Im conclusion to this tutorial, we set-up a micro server instance on Amazon EC2 service and installed Docker.io there. In addition we launched an simple nginx web server, serving a static html file.