Nat! bio photo

Nat!

Senior Mull

Twitter Github Twitch

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 nat@127.0.0.1 from OS X into the Ubuntu VM, which is much more convenient than dicking around in the Virtual Box window.

Install Docker

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

root@482791e6cc1a: 

A root shell in the container. Yay.

now 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 :(

Understanding docker

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 docker ps -a. You will want to periodically clean up all the cruft with docker rm.

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 attach.

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 --quiet)

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.


Post a comment

All comments are held for moderation; basic HTML formatting accepted.

Name:
E-mail: (not published)
Website: