Lightweight VMs With Docker
Posted on 2017-1-29 (æ¥) at 7:31 pm
If you wanted to use Docker for very lightweight VMs for e.g. testing different Linux or BSD distributions, I will describe here one method of doing so.
First step is to install Docker, this is pretty straightforward, it is available for Linux, Windows and Mac.
Don't forget to go into the preferences and set the amount of RAM and number of CPUs you want available to your containers. If you are going to be e.g. compiling things, this is especially important.
Since the base images are very lightweight and don't run services or a GUI, you can get away with using less RAM then you would with a traditional VM.
Create the Image
Let's use Debian as an example, first pull the version you want, the format <dist>:<release>, so we are going to get Debian Jessie:
docker pull debian:jessie
Now we need to set it up, open a root shell with:
docker run --name debian-vm -h debian-vm --detach-keys="ctrl-@" -it debian:jessie bash
This runs the image in a container with the hostname set to debian-vm
, and
the detach key set to ctrl-shift-2
, and opens an interactive session with
bash as the command.
Instead of debian:jessie
you can use e.g. ubuntu:trusty
or just about
anything, look on Docker Hub for available images.
From here you want to use adduser
to create your user, install some essential
packages like sudo, vim, tmux, etc., and set up your home directory, etc. When
you are done exit the shell, and we are going to save the image.
docker commit debian-vm rkitover/debian:jessie docker rm debian-vm
Here rkitover
is my user name and Docker ID on Docker Hub and
rkitover/debian:jessie
will be the full name of the image.
Launching the Container
Now let's make a handy bash function to launch the container and automatically
commit our work when done. Put something like this in your ~/.bashrc
:
debian-vm() { docker run --name debian-vm -h debian-vm --detach-keys="ctrl-@" -it -u rkitover rkitover/debian:jessie bash -l docker commit debian-vm rkitover/debian:jessie docker rm debian-vm }
Here the user I created in the image is rkitover
and it will launch bash as that user as a login shell. When the shell exits, it will commit changes in the filesystem back to the image.
If you use ctrl-shift-2
to detach from the container, you can reattach back
to your terminal session with docker attach <name>
.
NOTE: the above function doesn't handle detaching and reattaching to containers, if you do that, you will need to commit it to your image manually.
If you want to make a "snapshot", just commit the name to another image name.
Configuration Notes
For the user in your container, my ~/.profile
looks something like this:
cd $HOME export SHELL=/bin/bash . "$HOME/.bashrc"
And since the base images are bare and universal, you'll want to set your time zone and locale information at the top of ~/.bashrc
, e.g.:
export LANG=en_US.UTF-8 export TZ=PST8PDT
You may need to install a locales
package, edit /etc/locale.gen
and run
locale-gen
so that the locale you want is available.
Cleanup Cron Job
It's a good idea to have something to clean up unused containers and dangling images, I have a nightly cron job the script for which looks like this:
#!/bin/sh docker inspect -f '{{if not .State.Running}}{{.Id}} {{ end }}' $(docker ps -aq) | grep -Ev '^$' | \ xargs docker rm >/dev/null 2>&1 docker image prune -f >/dev/null 2>&1
Last modified: 2018-8-9 (æ¨) at 3:05 am