Docker with VirtualBox - some notes
This is not a tutorial, but some notes to help me remember what I did and what I learned.
Use a 64 bit Linux as a docker host
I chose Ubuntu 14.10 LTS as the VM container host. It is important to use the 64 bit/AMD version! Docker doesn't work well with 32 bit, because the prefabricated containers you will pull, are all 64 bit and you get strange exec errors!
Assume I have Ubuntu 14.10 installed at this point.
Then for shell access to the Ubuntu VM host, I went into the VirtualBox settings of that VM. In Network/Adapter 1/Port Forwarding I add a new port forwarding
SSH TCP 127.0.0.1 2022 10.0.2.15 22
Now I can
ssh -p 2022 email@example.com from OS X into
the Ubuntu VM, which is much more convenient than dicking around in
the Virtual Box window.
It could be simpler, but I have to type all this :)
apt-get install docker.io
Get a first container going
Use debian as the container OS just for kicks (it's also smaller than ubuntu)
docker run -i -t debian /bin/bash
will present you after some downloading with the following
A root shell in the container. Yay.
uname still gives ubuntu, because this is a
container and not a true VM..
root@482791e6cc1a: uname -a Linux ubuntu-14 3.13.0-32-generic #57-Ubuntu SMP Tue Jul 15 03:51:08 UTC 2014 x86_64 x86_64 x86_64 GNU/Linux
Aborting docker downloads
When I tried to pull another OS
docker pull ubuntu
I paniced, because it downloaded a lot of different ubuntu versions, which I didn't want so I hit CTRL-C. But no dice, docker kept on downloading in the background. I needed to kill docker with
service docker.io restart
I think it's better to specify the ubuntu version I want with
docker pull ubuntu:14.10, but then maybe not. I always
need to specify ubuntu:14.10 then, because otherwise
docker starts downloading all ancient ubuntu versions too :(
Containers are ephemeral
docker run creates a container, configures it and
runs a command in it. You need to run to configure
a container, every run creates a new container. So a lot of
containers will be generated. Observe them with
-a. You will want to periodically clean up all the cruft
A container is not a VM, it doesn't start any services or run init.d, as far as I can tell. The command you give it is crucial. Think of it more like an application wrapper, than a VM.
When you need to reconfigure a container, you need to "commit" it. That creates an image out of the container, that can then be reconfigured with a new run command. There is no other way. For a container, especially with networking configured, expect to do a lot of commits and runs.
In general all data or logs in the container, are easily perishable. You save them by doing a commit, which is fairly costly.
Map data to persist in, via -v
root@host:~# mkdir /usr/local/test root@host:~# touch /usr/local/test/FROM_HOST root@host:~# docker run -i -t -v /usr/local/test:/tmp/test debian /bin/bash root@ec08690b183a:/# mount ... /dev/disk/by-uuid/77fb49ed-b208-4709-9a68-9cd6e6b3d7f4 on /tmp/test type ext4 (rw,relatime,errors=remount-ro,data=ordered) root@ec08690b183a:/# ls /tmp/test/ FROM_HOST root@ec08690b183a:/# touch /tmp/test/FROM_CONTAINER root@ec08690b183a:/# ^P^Q root@ubuntu-14:~# ls /usr/local/test/ FROM_CONTAINER FROM_HOST
Typical thinking errors
The container stops, when the shell stops
root@host:~# docker run -i -t -p 127.0.0.1:8081:80 debian /bin/bash root root@26e40f043fbb: apt-get update ... root@26e40f043fbb: apt-get install apache2 root@26e40f043fbb: apachectl start root@26e40f043fbb: ^D root@host:~# telnet 127.0.0.1 8081 Trying 127.0.0.1... telnet: Unable to connect to remote host: Connection refused
Use CTRL-P CTRL-Q to step out of the container shell and keep
the shell running. Reattach with
docker run -i -t -p 127.0.0.1:8082:80 debian /bin/bash root@26e40f043fbb: apt-get update ... root@26e40f043fbb: apt-get install apache2 root@26e40f043fbb: apachectl start root@26e40f043fbb: ^P^Q root@26e40f043fbb:/# root@ubuntu-14:~# telnet 127.0.0.1 8082 Trying 127.0.0.1... Connected to 127.0.0.1. Escape character is '^]' GET / ... root@ubuntu-14:~# docker attach 26e40f043fbb root@26e40f043fbb:
The container is a different container, even if run with the same parameters again
root@host: docker run -i -t -p 127.0.0.1:8081:80 debian /bin/bash root@9f716f2329eb:/# apachectl start bash: apachectl: command not found
The container's previous processes are gone after start
root@host:~# docker ps -a CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES 9f716f2329eb debian:latest /bin/bash About a minute ago Exited (127) 10 seconds ago suspicious_davinci 26e40f043fbb debian:latest /bin/bash 4 minutes ago Exited (0) 2 minutes ago berserk_mcclintock root@host:~# docker start 26e40f043fbb 26e40f043fbb root@26e40f043fbb:~# apachectl stop apache2: Could not reliably determine the server's fully qualified domain name, using 172.17.0.8 for ServerName httpd (pid 740?) not running
I haven't figured out, what stop and start are really useful for, it seems you will usually want to run anyway.
Update: start and stop become useful once you have a container configured to your liking. Then it's like starting or stopping a service
Getting rid of unused images
docker rmi $(docker images --filter dangling=true
You can't get too fine grained though
root@host:~# time for i in `docker run --rm debian /bin/ls`; do docker run --rm debian /bin/ls -ld "$i"; done drwxr-xr-x 2 root root 4096 Nov 5 21:37 bin drwxr-xr-x 2 root root 4096 Sep 21 18:17 boot drwxr-xr-x 4 root root 340 Nov 30 21:50 dev drwxr-xr-x 32 root root 4096 Nov 30 21:50 etc drwxr-xr-x 2 root root 4096 Sep 21 18:17 home drwxr-xr-x 7 root root 4096 Jun 22 2012 lib drwxr-xr-x 2 root root 4096 Nov 5 21:33 lib64 drwxr-xr-x 2 root root 4096 Nov 5 21:31 media drwxr-xr-x 2 root root 4096 Sep 21 18:17 mnt drwxr-xr-x 2 root root 4096 Nov 5 21:31 opt dr-xr-xr-x 101 root root 0 Nov 30 21:50 proc drwx------ 2 root root 4096 Nov 5 21:31 root drwxr-xr-x 5 root root 4096 Nov 5 21:37 run drwxr-xr-x 2 root root 4096 Nov 5 21:37 sbin drwxr-xr-x 2 root root 4096 Jun 10 2012 selinux drwxr-xr-x 2 root root 4096 Nov 5 21:31 srv dr-xr-xr-x 13 root root 0 Nov 30 21:51 sys drwxrwxrwt 2 root root 4096 Nov 5 21:37 tmp drwxr-xr-x 10 root root 4096 Nov 5 21:31 usr drwxr-xr-x 11 root root 4096 Nov 5 21:31 var real 0m6.206s user 0m0.105s sys 0m0.095s
I don't think it will be a good idea to push individual php scripts through a docker run command.
The --rm options removes the ephemeral container.