If you don't want to use Docker Inc.'s hub service to store either public images for free or private images for money, they packaged their registry application as a container image that you can use to run a private instance. It's a really good example of a containerized application that is simple yet very powerfull, and has a lot of configuration options to allow a wide range of setupds.

I want to share my experiments, problems and most importantly solutions I ran into so it may be easier for you to run one (or easier for me to run another one, later).

If you're using a local docker, then the registry will be available on localhost:5000.
If you're using boot2docker, then the registry will of course be served on port 5000 of the docker server virtual machine, and you can get its IP by running boot2docker ip 2>/dev/null.

Note

The README does not state that the --preload gunicorn option should be added, but you most probably need it.

Ensure "latest" is what you think

To make sure you're realy using the "latest" repository, I'd avise to pull explicitely, and also specify a version other than "latest".

I don't know if options exist to specify a signed version, for example, specify "701fc2aebfb2" as the correct "0.9.0" version, just in case the image maintainer change the container and release a new version under the same name. Who knows?

docker pull registry:0.9.0
docker run -p 5000:5000 registry:0.9.0

Note

It seems that first time I tried it, I got stuck running an "old latest" container. As though it was not the main reason of the problems I were facing, it can be disturbing when you realise that the hash of your current image is not the one claimed by docker hub's registry.

Errors while running migrations

Image can use a "preload" gunicorn worker to avoid race conditions of multiple workers trying to run sql migrations. I don't even know why this is not default, as the problem seems to appear systematically without (maybe it does not exist if you're using a link to another container for database, or a database server).

docker run -p 5000:5000 -e GUNICORN_OPTS=[--preload] registry

Test drive

Just curl or open in a browser your registry "/" to be sure everything is good. You should read something like ""docker-registry server"".

You can also open the "/_ping" or "/v1/_ping" path, and read a lot of information about the running environment. This is because the registry is currently running in "dev" flavor that set up DEBUG flag to True by default. Don't worry, production server won't expose anything. If you wanna try, you can run it with -e DEBUG=False and request "/_ping". Woot, nothing anymore.

Now just push something to this new local repo, because that's what we want to do at the end of the day.

If you're using docker >= 1.3.1, which you should, you won't be allowed to push right now. Please see «Allowing an insecure registry endpoint» below.

Note

Docker is using special image names to specify "remotes" (as in git terminology). There are discussions whether this is good or bad, and I hope that a real "remote" concept would be added to docker one day, but right now, that's the way, baby.

Note

I'm using 192.168.59.103:5000 as my own remote because I did use boot2docker, and the IP is docker host virtual machine. If you're running docker locally (linux box, probably), then your host will be localhost.

Allowing an insecure registry endpoint

Since docker 1.3.1, docker won't allow you to push to a repository without certificate-verified HTTPS endpoints. That's a bit harsh, but you can workaround this by explicitely allowing an "insecure endpoint". Insecure endpoints will fallback to HTTP if no HTTPS termination is found.

If you try anyway, you'll get the following message:

FATA[0005] Error: Invalid registry endpoint https://192.168.0.103:5000/v1/: Get https://192.168.0.103:5000/v1/_ping: dial tcp 192.168.0.103:5000: i/o timeout. If this private registry supports only HTTP or HTTPS with an unknown CA certificate, please add `--insecure-registry 192.168.0.103:5000` to the daemon's arguments. In the case of HTTPS, if you have access to the registry's CA certificate, no need for the flag; simply place the CA certificate at /etc/docker/certs.d/192.168.0.103:5000/ca.crt

Hopefully, an easy solution can help you workaround this until we setup the HTTPS endpoint.

For linux docker users

Open /etc/docker/default and add the following at the end:

DOCKER_OPTS="$DOCKER_OPTS --insecure-registry 192.168.0.0/16"

(of course, this is not exact as you most probably don't access your local box under the ip my virtualbox currently use for boot2docker ...)

For boot2docker users

boot2docker ssh
sudo vi /var/lib/boot2docker/profile

Add the following at the end of the file (that you may very well be creating right now):

Data storage is not persistent unless you run the container with a volume for the storage path (-v /tmp/registry:/tmp/registry). If you destroy and create your container again, you'll loose all the data.