Playing with Private Docker

We’ve recently become interested in the future of Docker. Why? In part for its Linux container technology (similar to Warden in Cloud Foundry), and in part for its nifty social integration (docker push & pull). But the big winner for us is its solution to packaging. Each docker repository contains a base Linux distro, all the dependencies pre-installed, and the target project(s) installed.

This is exciting for several reasons. One is that you build Docker repositories (by hand if you really want) once, and reuse that artifact again and again. The other is that your system no longer has any remote dependencies. Never again will your CI build fail because RubyGems or GitHub is down.

Third, you can create your Docker repositories on your personal computer, with access to the public Internet, and then take them into your private data center which is deprived of Internet access.

The core of this solution is to run your own standalone private Docker registry. How do you run a private registry? How do you push repositories (and the images that make them up) to one? How do you pull the images back down to a fresh Docker server and run them?

I’m glad you asked. The tutorial that follows assumes you’re on a Linux machine with the docker CLI available in your path. It doesn’t assume that you have a docker server running already. We’ll run new ones.

Running local fresh docker in a terminal:

mkdir -p /home/core/docker1
sudo docker -d -g /home/core/docker1 -p /var/run/docker1.pid -H tcp://127.0.0.1:5011

Pulling ubuntu image from public registry into that docker (in another terminal):

$ docker -H tcp://localhost:5011 pull ubuntu:13.04
Pulling repository ubuntu
eb601b8965b8: Download complete
511136ea3c5a: Download complete
f323cf34fd77: Download complete
$ docker -H tcp://localhost:5011 images
REPOSITORY          TAG                 IMAGE ID            CREATED             VIRTUAL SIZE
ubuntu              13.04               eb601b8965b8        6 days ago          166.5 MB

Run a private registry (within a docker container, hey, why not?)

git clone https://github.com/drnic/docker-registry-dockerfile.git
cd docker-registry-dockerfile
git submodule update --init
docker -H tcp://localhost:5011 build -t registry .
docker -H tcp://localhost:5011 run -p 5000:5000 -v $(pwd)/cache:/registry registry

Note, the stored files of this private registry is on the host machine and so will survive restarts of the docker-registry docker container.

Tag and push the downloaded image to the private registry:

$ docker -H tcp://localhost:5011 tag ubuntu:13.04 localhost:5000/ubuntu-13.04
$ docker -H tcp://localhost:5011 push localhost:5000/ubuntu-13.04
The push refers to a repository [localhost:5000/ubuntu-13.04] (len: 1)
Sending image list
Pushing repository localhost:5000/ubuntu-13.04 (1 tags)
511136ea3c5a: Image successfully pushed
f323cf34fd77: Image successfully pushed
eb601b8965b8: Image successfully pushed
Pushing tags for rev [eb601b8965b8] on {http://localhost:5000/v1/repositories/ubuntu-13.04/tags/latest}

Running local fresh docker in another terminal:

mkdir -p /home/core/docker2
sudo docker -d -g /home/core/docker2 -p /var/run/docker2.pid -H tcp://127.0.0.1:5012

Now, you can run a new container in the new docker daemon based on the private registry image:

$ docker -H tcp://localhost:5012 run localhost:5000/ubuntu-13.04 echo hello world
Unable to find image 'localhost:5000/ubuntu-13.04' (tag: latest) locally
Pulling repository localhost:5000/ubuntu-13.04
f323cf34fd77: Download complete
511136ea3c5a: Download complete
eb601b8965b8: Download complete
hello world

Now the fresh docker daemon has the private localhost:5000/ubuntu-13.04 repository downloaded and can be reused again quickly:

$ docker -H tcp://localhost:5012 run localhost:5000/ubuntu-13.04 echo hello world
hello world

Spread the word

twitter icon facebook icon linkedin icon