Basic Docker

Previously on the Docker Channel: Docker Theory

Ubuntu and Debian include a version of Docker, but it's considerably behind that available from Docker themselves. I used the instructions here for Ubuntu and here for Debian. Note that to use it without root privileges, you'll have to add your user to the "docker" group.

Docker provides a huge number of images, pre-built Docker machines that you can use or build on. A good first step:

$ docker run hello-world
Unable to find image 'hello-world:latest' locally
latest: Pulling from library/hello-world
c04b14da8d14: Pull complete
Digest: sha256:0256e8a36e2070f7bf2d0b0763dbabdd67798512411de4cdcf9431a1feb60fd9
Status: Downloaded newer image for hello-world:latest

Hello from Docker!
This message shows that your installation appears to be working correctly.

To generate this message, Docker took the following steps:
 1. The Docker client contacted the Docker daemon.
 2. The Docker daemon pulled the "hello-world" image from the Docker Hub.
 3. The Docker daemon created a new container from that image which runs the
    executable that produces the output you are currently reading.
 4. The Docker daemon streamed that output to the Docker client, which sent it
    to your terminal.

To try something more ambitious, you can run an Ubuntu container with:
 $ docker run -it ubuntu bash


I'll assume you've read what it said: it's useful.

To find out what pre-made images are available:

$ docker search debian
NAME                           DESCRIPTION                                     STARS     OFFICIAL   AUTOMATED
debian                         Debian is a Linux distribution that's comp...   1620      [OK]
neurodebian                    NeuroDebian provides neuroscience research...   28        [OK]
armbuild/debian                ARMHF port of debian                            8                    [OK]

There are quite a few more matches, as there are matches for "centos," "fedora," and "ubuntu." Note the "OFFICIAL" designation (and the partially matching "STARS" rating): as I understand it, these are images of well-known OSes built either by the OS maker or by Docker (which I'm not sure about) - other images are built by other users. To get a local copy to work with:

$ docker pull debian
Using default tag: latest
latest: Pulling from library/debian
8ad8b3f87b37: Pull complete
Digest: sha256:2340a704d1f8f9ecb51c24d9cbce9f5ecd301b6b8ea1ca5eaba9edee46a2436d
Status: Downloaded newer image for debian:latest

The pulled image does NOT show up in your current directory. In fact, the folder it's parked in isn't visible to a normal user - not even one who's part of the "docker" group. The folder is /var/lib/docker/:

# ls /var/lib/docker/aufs/diff/e76a9de905d7a58ddee9075c24767a2b6755a535632a9289c3d6554e978e6414/
bin   dev  home  lib64  mnt  proc  run   srv  tmp  var
boot  etc  lib   media  opt  root  sbin  sys  usr

(I found the specific folder by using du -sh /var/lib/docker/ repeatedly on subfolders until I found out where the new 137MB of space was being used.)

Check what images we have available locally:

$ docker images
REPOSITORY          TAG                 IMAGE ID            CREATED             SIZE
debian              latest              031143c1c662        5 days ago          125.1 MB
hello-world         latest              c54a2cc56cbb        9 weeks ago         1.848 kB

Check if we have any containers running:

$ docker ps
CONTAINER ID        IMAGE               COMMAND             CREATED             STATUS              PORTS               NAMES
$ docker ps -a
CONTAINER ID        IMAGE               COMMAND             CREATED             STATUS                   PORTS               NAMES
4c3759227eed        hello-world         "/hello"            3 hours ago         Exited (0) 3 hours ago                       backstabbing_goodall

So I don't have any containers running at the moment, but I did run "hello-world" a while ago. To run the Debian image I've pulled: docker run -ti 031143c1c662, where "-t" means "Allocate a pseudo-TTY" and "-i" means "Keep STDIN open even if not attached". This will put you at a prompt - but you're now inside the container. You can do normal Linuxy stuff, including installing packages - but after you type exit, the container will shut down and if you restart it, you'll find the package you installed isn't there anymore.

I've used the terms image and container a little bit. Docker's choice of phraseology is that an image is the software bundle you downloaded, and a container is an instantiated version of an image. I'm not sure I agree with their naming choices, but the best thing to do is get on with getting used to it. So let's look at the previously run instances again:

$ docker ps -a
CONTAINER ID        IMAGE               COMMAND             CREATED             STATUS                      PORTS               NAMES
a099dc16e422        031143c1c662        "/bin/bash"         4 minutes ago       Exited (0) 27 seconds ago                       goofy_franklin
4c3759227eed        hello-world         "/hello"            4 hours ago         Exited (0) 4 hours ago                          backstabbing_goodall

The "NAMES," while bizarre, can be very handy: it's easily more memorable, and on Ubuntu tab completion on the names works. I can restart a previously run container with:

$ docker start goofy_franklin
$ docker ps
CONTAINER ID        IMAGE               COMMAND             CREATED             STATUS              PORTS               NAMES
a099dc16e422        031143c1c662        "/bin/bash"         9 minutes ago       Up 8 seconds                            goofy_franklin
$ docker attach goofy_franklin

docker start <container-name> doesn't attach you to the container, but once it's running we can see it shows up in the docker ps listing. To attach, use docker attach <container-name>. You'll find that any changes you made are still in place: this is because you used docker start to start an existing container rather than docker run to start fresh from the downloaded image. Whether the container is running or not, you can use docker diff goofy_franklin to see a list of files that have changed from the source image.

With the installation of nginx (or any package), another hexadecimal-named folder has appeared in /var/lib/docker/aufs/diff/, and it contains what appears to be the files nginx and its deps would have installed on top of an already existing Debian filesystem. To remove non-running (and possibly running - I haven't checked) containers, use docker rm goofy_franklin backstabbing_goodall. This removes them from the listing in docker ps -a and removes the diff/ folder that goes with it.

If - as I do - you have a relatively small partition for your operating system, you should be mindful of the disc usage. Particularly when we get into building your own images, but even now, the /var/lib/docker/ folder is growing.