docker: installation and getting started
Update (20140610): Docker 1.0 has come out. The installation has changed since I wrote this post. Please refer to https://docs.docker.com/installation/ubuntulinux/ for up-to-date information.
Docker is an open-source project to easily create lightweight, portable, self-sufficient containers from any application. (source)
Docker extends a common container format called Linux Containers (LXC) with a high-level API providing a lightweight virtualization solution that runs processes in isolation. Docker utilizes LXC, cgroups, and the Linux kernel itself. Unlike traditional virtual machines, a Docker container does not include a separate operating system, instead it relies on the operating system’s functionality provided by the underlying infrastructure. (via wikipedia)
In the following, I want to concentrate on how to install Docker and how to make it run on Ubuntu. To learn more about Docker (what is it good for, what can it do for you, etc.), you will have to do some research on your own. But I also plan to make more blog posts on Docker where I want to write about its use cases.
This entry is based on this post, written by Csaba Okrona. For more info check out his excellent post.
At the time of writing docker was not supported on 32 bit machines. Installing the prerequisites and docker on x86_64
machines:
$ sudo apt-get install linux-image-extra-$(uname -r) software-properties-common $ sudo sh -c "wget -qO- https://get.docker.io/gpg | apt-key add -" $ sudo sh -c "echo deb http://get.docker.io/ubuntu docker main > /etc/apt/sources.list.d/docker.list" $ sudo apt-get update $ sudo apt-get install lxc-docker
Let’s try it. Pull down an ubuntu base image:
$ sudo docker pull ubuntu Pulling repository ubuntu ...
Let’s execute a command inside docker:
$ sudo docker run ubuntu /bin/echo hello from docker hello from docker
The echo
command was executed in the docker container, it produced an output, and this output was returned to the host (your machine).
Execute docker as non-root
As you noticed, docker
must be executed with sudo
. If you want to execute it with your non-root account, here is what to do:
# create the 'docker' group $ sudo groupadd docker # probably it already exists # add your user to the 'docker' group $ sudo gpasswd -a USER docker # replace USER with your user name # restart the service $ sudo service docker restart
You will have to log out and log back in to make the group settings active on your account. After that you can launch docker
without sudo
:
$ docker images REPOSITORY TAG ID CREATED SIZE ubuntu 12.04 8dbd9e392a96 4 months ago 131.5 MB (virtual 131.5 MB) ubuntu 12.10 b750fe79269d 5 months ago 24.65 kB (virtual 180.1 MB) ubuntu latest 8dbd9e392a96 4 months ago 131.5 MB (virtual 131.5 MB) ubuntu precise 8dbd9e392a96 4 months ago 131.5 MB (virtual 131.5 MB) ubuntu quantal b750fe79269d 5 months ago 24.65 kB (virtual 180.1 MB)
Connect to a container
# start a container (and save its ID in an env. variable) $ DOCK=$(docker run -d -i -t ubuntu /bin/bash) # it's in the list $ docker ps CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES fe650a3d214f ubuntu:12.04 /bin/bash 2 minutes ago Up 2 minutes sharp_archimede # attach to the container $ docker attach $DOCK root@fe650a3d214f:/#
Install some packages in the container
In order to install arbitrary packages, let’s enable the multiverse repos:
root@fe650a3d214f:/# cat > /etc/apt/sources.list deb http://archive.ubuntu.com/ubuntu precise main universe multiverse root@fe650a3d214f:/# apt-get update root@fe650a3d214f:/# apt-get install python-pip root@fe650a3d214f:/# pip install virtualenv root@fe650a3d214f:/# apt-get install libpq-dev python-dev root@fe650a3d214f:/# apt-get install vim ...
However! Any changes you do in your container, they are not permanent! That is, if you log out and you attach to it again, all your changes will be lost and you get back the same vanilla container that you saw upon your first connect. But don’t worry! Changes can be committed, i.e. changes can be made permanent.
This behaviour is actually useful. You can do anything in the container, you can try anything inside, you can’t f* it up. Just log out and log back in, and everything is back. Imagine the possibilities: you can build a secure sandboxed environment easily where you can run any untrusted code.
Committing changes
You made some changes in your vanilla ‘ubuntu’ container and you want to commit them, i.e. you want to see these changes after a relogin. Let’s commit the changes to a new container called ‘pyenv’ for instance.
You are connected to ‘ubuntu’ in a terminal. Don’t logout, otherwise you lose your changes. Open a new terminal and execute these commands:
$ docker ps CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES fe650a3d214f ubuntu:12.04 /bin/bash 22 minutes ago Up 22 minutes sharp_archimede $ docker commit fe650a3d214f pyenv f538ae2eb2562bf2ab669d7e04cf9fa49b66814d871bcbc0662deedfdcce73ab
Now you can log out of ‘ubuntu’ and you can log in to ‘pyenv’. From now on you can commit new changes to ‘pyenv’. If you need a new vanilla container, just fork ‘ubuntu’ again.
When you commit changes, docker stores just the diffs, and when you connect to a container, it puts the necessary diffs together.
Sharing a folder between the host and the container
If you want to copy files from the host to the container, the easiest way is to create a shared folder:
$ DOCK=$(docker run -d -i -t -v /tmp/shared.folder:/shared.folder ubuntu /bin/bash) $ docker attach $DOCK
The folder /tmp/shared.folder
on the host will be mounted in the container as /shared.folder
. The shared folder must exist on the host.
Hands off best guide for a quick’n dirty Docker startup, thank you!