You are on page 1of 8

Docker: A how-to

Over Christmas/New Years I had a fair amount of spare time for relaxation; so naturally this was
spent tinkering around with various bits of software and kit I havent had time to play with during
the past few months. One of the things I wanted to test and try in anger was Docker; a
wrapper/software suite that wraps LXC into something a bit more usable. There is a video below
that explains what Docker is and how it works:
One of the biggest benefits of Docker is with a bit of skill, it allows you to satisfy your tech
curiosity without compromising your production environments / home environments, i.e. Oh
cock, I spent 2 hours playing around with X and getting it working and its actually not very
good; now i have to go remove databases, apache entries, etc. In Docker, you can simply just
spin up a new ubuntu container (instance; like a virtual machine essentially if you think
abstract), play around and develop for a few hours, then either save it, or crash and burn it
without any impact to your underlying server.
This is perfect for those of us who can spend 8+ hours testing out redis across 5 servers, or
elasticsearch with packetbeat, etc yet dont want to spend 30 minutes making a new virtual
machine (KVM ftw), or even worse running it on our stable kit.
Therefore the purpose of this blog is give you all the tools and commands to turn Docker into
something useful that you can use on a daily basis. So, lets begin!
1. Getting started
At home I run Ubuntu 14.04 as my operating system of choice, therefore all instructions
pertaining to the installation of Docker are for Ubuntu (Debian too, I imagine) if you require
RHEL/Centos then follow the guide here.
For detailed instructions (and per platform instructions), follow the Docker on Ubuntu
installation guides here but for brevitys sake, here are the steps you need to take in order to get
docker ready to roll on Ubuntu 14.04:
1
2
3
4
5
6

apt-get install apt-transport-https


sudo apt-key adv --keyserver hkp://keyserver.ubuntu.com:80 --recv-keys
36A1D7869245C8950F966E92D8576A8BA88D21E9
sudo sh -c "echo deb https://get.docker.com/ubuntu docker main\
> /etc/apt/sources.list.d/docker.list"
sudo apt-get update
sudo apt-get install lxc-docker

To test that everything worked, run:


1 docker ps -as
This should return the following:

1 root@server:/home/sam# docker ps -as


2 CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES SIZE
3 root@server:/home/sam#
If you get:
1 root@server:/home/sam# docker ps -as
2 FATA[0000] Cannot connect to the Docker daemon. Is 'docker -d' running on this host?
Then the Docker service isnt running. On Ubuntu, run service docker start, and re run docker
ps -as, and it should now work.
2. Using Docker
So now youve got Docker, how do you actually use it!?
Docker works using containers which are essentially your virtual machines, if you are
familiar with virtualization. You can view all your containers by running docker ps -as, as
below:
1 root@server:/home/sam# docker ps -as
2 CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES SIZE
3 283ac561a135 centos:centos7 "/bin/bash" 14 seconds ago Up 3 seconds CentosBox 5 B
4 root@server:/home/sam#
As you can see, I have a single container called CentosBox running that is of the type
centos:centos7. The container ID is 283ac561a135, which can be used if you dont give your
container a human name (i.e. CentosBox!).
So how did i get a Centos container and how does it work? Docker works using something called
images, which are essentially templates (like virtual appliances, essentially). You can create
your own image, share it with others, and vice versa, use other peoples images on your box. To
find an image you can run the command:
1 docker search <imagename>
See below for an example:
1 root@server:/home/sam# docker search debian
2 NAME DESCRIPTION STARS OFFICIAL AUTOMATED
3 debian (Semi) Official Debian base image. 291 [OK]
4 google/debian 30 [OK]
5 hanswesterbeek/google-debian-oracle-jdk Oracle's JDK installed on top of Google's ... 4

6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28

[OK]
neurodebian NeuroDebian provides neuroscience research... 4 [OK]
shuron/debian-openjdk-7 Open JDK 7 64x on plain debian (Jessie) La... 2 [OK]
webhippie/cedarish-debian Heroku cedar-ish base images for Docker bu... 2 [OK]
jesselang/debian-vagrant Stock Debian Images made Vagrant-friendly ... 1 [OK]
maxexcloo/debian Docker base image built on Debian with Sup... 1 [OK]
tutum/debian Debian image with SSH access. For the root... 1 [OK]
mschuerig/debian-subsonic Subsonic 5.0 on Debian/wheezy. 1 [OK]
fike/debian-postgresql PostgreSQL 9.4 beta until 9.0 version runn... 1 [OK]
jprjr/debian-nginx 1 [OK]
icco/simple-debian A debian build with Ruby 2.1 installed and... 1 [OK]
calebj/debian 0 [OK]
eboraas/debian Debian base images, for all currently-avai... 0 [OK]
thedutchselection/debian 0 [OK]
yaronr/debian-wheezy Debian Wheezy, 85mb, with a few extras 0 [OK]
aostanin/debian 0 [OK]
razmo/debian Debian base 0 [OK]
takeshi81/debian-wheezy-php Debian wheezy based PHP repo. 0 [OK]
tianon/debian-devel 0 [OK]
etna/drone-debian 0 [OK]
essembeh/debian My own Debian Jessie image 0 [OK]
kalabox/debian Kalabox Debian Wheezy image for all the ot... 0 [OK]
reinblau/debian Debian with usefully default packages for ... 0 [OK]
root@server:/home/sam#

Here we can see a number of images that contain the word Debian; the one at the top has the
most stars and is also a semi official image (??), so lets use that one! To download it locally, use
the pull command as below:
1 root@server:/home/sam# docker pull debian
2 debian:latest: The image you are pulling has been verified

3 1aeada447715: Pull complete


4 479215127fa7: Pull complete
5 511136ea3c5a: Already exists
6 Status: Downloaded newer image for debian:latest
7 root@server:/home/sam#
Now lets make sure that it has been downloaded; run the images command to view all the
images stored locally on your Docker server:
1 root@server:/home/sam# docker images
2 REPOSITORY TAG IMAGE ID CREATED VIRTUAL SIZE
3 debian latest 479215127fa7 4 days ago 84.99 MB
4 root@server:/home/sam#

Now that the image has been downloaded, lets go ahead and deploy a container based on the
image so we can get cracking and start to use Debian!
1 root@server:/home/sam# docker run -it --name debserver debian /bin/bash
2 root@dc4e5b4e5311:/#
Within seconds (i.e. <3 seconds), we now have a container running Debian ontop of our Ubuntu
14.04 server, cool hey! To prove this is a Debian box and not Ubuntu, you can go ahead and
install lsb_release (apt-get update & apt-get install lsb-release), and run it:
1 root@dc4e5b4e5311:/# lsb_release -a
2 No LSB modules are available.
3 Distributor ID: Debian
4 Description: Debian GNU/Linux 7.7 (wheezy)
5 Release: 7.7
6 Codename: wheezy
7 root@dc4e5b4e5311:/#
Cool huh! Now, you can go ahead and tinker to your hearts content, set stuff up, install apache,
etc and its all safely contained within Docker. To shutdown the container, simply exit the shell:
1 root@dc4e5b4e5311:/# exit
2 exit

3
4
5
6
7

root@server:/home/sam# docker ps -as


CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES SIZE
dc4e5b4e5311 debian:latest "/bin/bash" 3 minutes ago Exited (0) 1 seconds ago debserver 39.1
MB
283ac561a135 centos:centos7 "/bin/bash" 12 minutes ago Up 11 minutes CentosBox 5 B
root@server:/home/sam#

You can then restart it using the command docker start, as below:
1 root@server:/home/sam# docker start debserver
2 debserver
3 root@server:/home/sam# docker ps -as
4 CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES SIZE
5 dc4e5b4e5311 debian:latest "/bin/bash" 3 minutes ago Up 1 seconds debserver 39.1 MB
6 283ac561a135 centos:centos7 "/bin/bash" 12 minutes ago Up 12 minutes CentosBox 5 B
7 root@server:/home/sam#
And if you want to view the IP address without having to go into the container, run the
command:
1 root@server:/home/sam# docker inspect debserver | grep IPAddress
2 "IPAddress": "172.17.0.8",
3 root@server:/home/sam#
If you do wish to connect to the console again, run the attach command:
1 root@server:/home/sam# docker attach debserver
2 root@dc4e5b4e5311:/#
One of the coolest things about Docker, in my opinion, is the ability to save your containers
locally for re-use in the future.
Say for example, I wanted to install my companies software / configure a series of packages and
software on my Debian box and then save it locally so i can quickly deploy it in the future.
After installing apache2, mysql-server, and configuring so your super happy with your Debian
container, you can use the commit command to save the container locally:
1 root@server:/home/sam# docker commit debserver smnet
2 34c640602df03c496e67e64d51c557255f6206a521570bd9d22812ae0736124a

3 root@server:/home/sam# docker images


4 REPOSITORY TAG IMAGE ID CREATED VIRTUAL SIZE
5 smnet latest 34c640602df0 9 seconds ago 124.1 MB
6 debian latest 479215127fa7 4 days ago 84.99 MB
7 root@server:/home/sam#
Here we have saved debserver as an image, and called that image smnet. I can then go and
delete that container safely, as below:
1
2
3
4
5
6
7
8
9
10
11
12

root@server:/home/sam# docker ps -as


CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES SIZE
dc4e5b4e5311 debian:latest "/bin/bash" 9 minutes ago Exited (0) 4 minutes ago debserver
39.1 MB
283ac561a135 centos:centos7 "/bin/bash" 17 minutes ago Up 17 minutes CentosBox 5 B
root@server:/home/sam# docker stop debserver
debserver
root@server:/home/sam# docker rm debserver
debserver
root@server:/home/sam# docker ps -as
CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES SIZE
283ac561a135 centos:centos7 "/bin/bash" 18 minutes ago Up 17 minutes CentosBox 5 B
root@server:/home/sam#

Then, in a minute, or years time, i can easily redeploy that Debian container that i installed lsbrelease on, using the command:
1 root@server:/home/sam# docker run -it --name debserver2 smnet /bin/bash
2 root@614ede51e5f8:/# lsb_release -a
3 No LSB modules are available.
4 Distributor ID: Debian
5 Description: Debian GNU/Linux 7.7 (wheezy)
6 Release: 7.7
7 Codename: wheezy

8 root@614ede51e5f8:/#
Very cool! This is so powerful for a development and testing perspective as it allows you to
RAPIDLY spin up a large number of platforms (Ubuntu, RHEL, you name it) and configure
them as you like. You can then rapidly and safely tear them down, or save them locally to be
redeployed back onto the same box, or sent to other servers to be deployed there very
awesome.
One final thing removing images! Say you dont like smnet anymore, you can simply remove it
using the command rmi (ReMove Image):
1 root@server:/home/sam# docker images
2 REPOSITORY
3 smnet

TAG
latest

4 opsview46-trusty latest
5 debian

latest

IMAGE ID
34c640602df0

CREATED
30 minutes ago

d761a27fa999
479215127fa7

3 days ago
4 days ago

VIRTUAL SIZE
124.1 MB
1.029 GB

84.99 MB

6 root@server:/home/sam# docker rmi smnet


7 Untagged: smnet:latest
8 Deleted: 34c640602df03c496e67e64d51c557255f6206a521570bd9d22812ae0736124a
9 root@server:/home/sam#
And cest tout, its gone!
3. Even cooler stuff
There are even cooler things that be done with Docker.
For example, you can expose container ports via the public IP of the underlying server. What
does that mean? Well, say for example I have apache2 running on debserver, i can currently only
access it via http://172.17.0.9. What Docker allows you to do is essentially NAT ports from the
host server through to the container, so I can say:
If anyone hits http://192.168.0.2:8082, redirect the traffic to http://172.17.0.9 i.e. if anyone goes
to ubuntu:8082, theyll get apache on the Debian container. To do this, simply run the command:
1 docker run -it --name debserver3 smnet -p 8082:80 /bin/bash
Then you can get your browser and go to http://192.168.0.2:8082 and voila, you have an apache
box!
One of the other neat things you can do is quickly deploy and link containers, similar to Ubuntu
Juju (see my write-up from 18 months ago here: http://www.everybodyhertz.co.uk/ubuntu-juju/).
One example Ive tested which works a treat is to deploy a mysql container, and deploy a
wordpress container, and link them together using just 2 commands:

root@server:/home/sam# docker run --name some-mysql -e


MYSQL_ROOT_PASSWORD=mysqlroot -d mysql
1 09dc2f70808fb1c18ba3b553461886c1b131788583de29006eb37cd7dfe3fd09
2 root@server:/home/sam# docker run --name some-wordpress --link some-mysql:mysql -p
8084:80 -d wordpress
3
37f632a8f447e309da106934beaf7e0fca5efa21e765c85ae45f14389dec3f59
4
root@server:/home/sam# docker ps -as
5
CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES SIZE
6
37f632a8f447 wordpress:latest "/entrypoint.sh apac 6 seconds ago Up 2 seconds
7
0.0.0.0:8084->80/tcp some-wordpress 0 B
8
09dc2f70808f mysql:latest "/entrypoint.sh mysq 13 seconds ago Up 11 seconds 3306/tcp
9 some-mysql 943 B
10 614ede51e5f8 smnet:latest "/bin/bash" 17 minutes ago Exited (0) 12 minutes ago debserver2
219 B
283ac561a135 centos:centos7 "/bin/bash" 36 minutes ago Up 36 minutes CentosBox 5 B
Then, hit your host server IP address:8084 in your browser and voila:
4. Gotchas / Limitations
So far I have found a few limitations of Docker, namely that is ignorant of sysv/upstart and an
ordered startup. The real world impact of this (mainly) is that your services dont start when you
docker start debserver'; i.e. if i installed apache2 on my debserver and used svc to tell it to run
on start, it wouldnt be running when i started that container as docker doesnt listen to svc.
This is a pain in the arse, but the way around it (at the moment at least) is to modify
/etc/bash.bashrc to contain the startup commands you need to execute via bash, i.e.:
service apache2 start
This should startup apache2 for you when the container starts, so you can simply get the IP and
test apache2.
Share story

You might also like