One of the things that makes Docker so useful is how easy it is to pull ready-to-use images from a central location, Docker’s Central Registry. It is just as easy to push your own image (or collection of tagged images as a repository) to the same public registry so that everyone can benefit from your newly Dockerized service.
But sometimes you can’t share your repository with the world because it contains proprietary code or confidential information. Today we are introducing an easy way to share repositories on your own registry so that you can control access to them and still share them among multiple Docker daemons. You can decide if your registry is public or private.
You’ll need the latest version of Docker (>=0.5.0) to use this new feature, and you must run this version as both the daemon and the client. You’ll also need the Docker registry code.
Using Push and Pull
The default way of pushing and pulling repositories from the Central Registry has not changed:
# Pull the ubuntu base image: docker pull ubuntu # Push the Hipache image (if you're samalba!) docker push samalba/hipache
Implicitly that push
and pull
each access the Central Registry at index.docker.io
, so nothing has changed with the default behavior and all the examples still work.
Now the new feature! To push to or pull from your own registry, you just need to add the registry’s location to the repository name. It will look like my.registry.address:port/repositoryname
.
Let’s say I want to push the repository “ubuntu” to my local registry, which runs on my local machine, on the port 5000:
# First, make sure you have the "ubuntu" repository: docker pull ubuntu # Then, find the image id that corresponds to the ubuntu repository docker images | grep ubuntu | grep latest ubuntu latest 8dbd9e392a96 12 weeks ago 263 MB (virtual 263 MB) # Almost there! # Tag to create a repository with the full registry location. # The location becomes a permanent part of the repository name. docker tag 8dbd9e392a96 localhost.localdomain:5000/ubuntu # Finally, push the new repository to its home location. docker push localhost.localdomain:5000/ubuntu
Obviously, the push will fail if no registry server answer locally on the port 5000. We’ll briefly show how to start your own registry server at the end of this blog post.
It’s important to note that we’re using a domain containing a “.” here, i.e. localhost.domain
. Docker looks for either a “.” (domain separator) or “:” (port separator) to learn that the first part of the repository name is a location and not a user name. If you just had localhost
without either .localdomain
or :5000
(either one would do) then Docker would believe that localhost
is a username, as in localhost/ubuntu
or samalba/hipache
. It would then try to push to the default Central Registry. Having a dot or colon in the first part tells Docker that this name contains a hostname and that it should push to your specified location instead.
Install your Registry (on your server or locally)
Docker-Registry is a simple Python app, installing it is straight-forward:
git clone https://github.com/dotcloud/docker-registry.git cd docker-registry cp config_sample.yml config.yml pip install -r requirements.txt gunicorn --access-logfile - --log-level debug --debug -b 0.0.0.0:5000 -w 1 wsgi:application
Your Registry is now running on localhost (port 5000) in a development flavor and using local storage. Obviously, in a production environment, you might want to run the Registry on port 443 (or 80 on a local network) and make it accessible on a hostname like “registry.domain.tld”, and point it to use S3 or other storage.
14 Responses to “How to use your own Registry”
chris-rock
Dear Sam, great article. I am a little bit confused with registry and index. On a fresh build it looks as follows
docker push localhost.localdomain:5000/ubuntu
Username (): user
Password:
Email (): user@pass.com
2013/07/29 22:20:28 Error: Registration: "Password is too short (4), needs to be at least 5 characters"
Do I need to set a registry? Where do I need to register?
Thatcher Peskens
Hi Chris,
You would do better off asking this type of question on IRC or StackOverflow. That being said. here it looks like you are prompted to create a user and password, but your input is too short.
Javier
By default it uses docker.com authentication
Jun Zhang
I encountered problem installing docker-retistry when I issue the command (at Mac Yosemite)
pip install -r requirements/main.txt (couldn’t find the file requirements.txt)
……………
swig -python -I/System/Library/Frameworks/Python.framework/Versions/2.7/include/python2.7 -I/usr/include -I/usr/include/openssl -includeall -modern -o SWIG/_m2crypto_wrap.c SWIG/_m2crypto.i
:3: Error: Unable to find ‘python.swg’
error: command ‘swig’ failed with exit status 1
Carlos Suarez
check under requirements folder when you download the repo.
Victor Liu
Just “sudo apt-get install swig ” on Ubuntu or relevant on other linux flavour.
Cheers
Javier Arauz
Currently trying to set up my own docker registry on Ubuntu 14.04 LTS. After sorting out the errors in the snippet above, I find myself in a dead end. Even if it’s not mentioned I assume I must use python3 (using python2 thows a “pyconfig.h” compilation error when pip-installing the required modules). However, module M2Crypto, required from requirements/main.txt has not been ported to Python3.
What can I do? Anyone else has met problems when pip-installing the requirements?
Javier Arauz
Never mind, I was missing the python-dev package (noob mistake 🙂
Javier Arauz
I’ve got the registry installed (docker-registry 1.1.0 from GitHub), but when I start it I get an error related to missing docker_registry.core package:
Traceback (most recent call last):
File “/usr/local/lib/python2.7/dist-packages/gunicorn/arbiter.py”, line 507, in spawn_worker
worker.init_process()
File “/usr/local/lib/python2.7/dist-packages/gunicorn/workers/base.py”, line 114, in init_process
self.wsgi = self.app.wsgi()
File “/usr/local/lib/python2.7/dist-packages/gunicorn/app/base.py”, line 66, in wsgi
self.callable = self.load()
File “/usr/local/lib/python2.7/dist-packages/gunicorn/app/wsgiapp.py”, line 65, in load
return self.load_wsgiapp()
File “/usr/local/lib/python2.7/dist-packages/gunicorn/app/wsgiapp.py”, line 52, in load_wsgiapp
return util.import_app(self.app_uri)
File “/usr/local/lib/python2.7/dist-packages/gunicorn/util.py”, line 356, in import_app
__import__(module)
File “/home/ecejjar/git/docker-registry/docker_registry/wsgi.py”, line 19, in
from .app import app # noqa
File “/home/ecejjar/git/docker-registry/docker_registry/app.py”, line 8, in
from . import toolkit
File “/home/ecejjar/git/docker-registry/docker_registry/toolkit.py”, line 18, in
from docker_registry.core import compat
ImportError: No module named core
I’ve checked the docker_registry folder and there’s no core package or module in it. Has anybody else met this problem?
Daniel @ Status Page
Hi Sam,
Thank you for sharing this detailed information it helped me a lot.
chakku
raise HaltServer(reason, self.WORKER_BOOT_ERROR)
gunicorn.errors.HaltServer:
How can I fix this issue?
Richard Gomes
There's Registry 2.0 which is apparently required in case you are using Docker 1.6.0 or above.
More info:
https://docker.github.io/registry/
Marcos
Hi buddy,
Great post!
Do you know how to make my own registry implicit in my setup?
I don't want to be typing it before the images names all the time.
Reason: migration from docker.cloud to local private repo.
Thanks a lot!
Nick Mellor
Great article. "You’ll also need the Docker registry code." is pointing to deprecated code