Hosting your private Docker Registry

Using docker and Amazon S3 to host you own private docker registry.
created by on 2014-10-17

If you want to keep your docker images private, local or just don’t want to use the public Docker index, you can use the ready-to-use docker container that run the registry.

Starting the registry

Docker Registry Image

To start your own registry you simply have run the registry image with the following options:

docker run \
         -e SETTINGS_FLAVOR=s3 \
         -e STORAGE_PATH=/registry \
         -e AWS_BUCKET=<name-of-your-aws-bucket> \
         -e AWS_KEY=<aws-key> \
         -e AWS_SECRET=<aws-secret> \
         -e SEARCH_BACKEND=sqlalchemy \
         -p 5000:5000 \

If you do that, you will have your private docker registry running on port 5000.
But note, the registry is not the docker index. There is no UI that comes with the docker registry.

01. Create an Amazon S3 Bucket

01. Create an Amazon S3 Bucket

02. Retrieve your AWS Key and Secret

02. Retrieve your AWS Key and Secret

03. Start the registry using docker

03. Start the registry with Docker

Pushing your first image to your registry

Once your have your own registry running for example under the domain “”, “” will become the namespace for all your images.

1. Change the namespace of your image

In order to upload an image you must first tag it with your new namespace/registry url: “”

sudo docker tag <image-name> <namespace/registry-url-and-port>/<image-name>

… otherwise the image will be uploaded the default docker registry (“”).

For example if you have an image named “ubuntu” that you want to upload to your private docker registry:

sudo docker tag ubuntu

2. Upload the image

Once you have renamed your image to include your new namespace you can simply push it.

sudo docker push

ttyrec: Push a docker image to a private registry

Once you have uploaded your first images your (new) Amazon S3 bucket will start to fill up with images and repository-definitions:


Securing your Registry / Authentication

The registry does not have a built-in authentication mechanism. The simplest way to to keep your images private is to run a Nginx as a reverse proxy and add basic authentication to it. I have created an example Nginx reverse proxy setup that you can use as a starting point:

# Clone my sample project
git clone [email protected]:andreaskoch/docker-registry-with-authentication.git
cd docker-registry-with-authentication

# Specify your AWS credentials

# Start the docker registry with your AWS Credentials and link it an reverse proxy.

If everything worked as expected you should be able to access your docker registry under: https:\\localhost

ttyred: How to build and run the private docker-registry with basic authentication

Alternatives to Basic-Authentication

Assuming your server ports are not exposed by default you can also use ssh tunneling instead of using basic authentication:

# Run the registry on the server, allow only localhost connection
docker run -p registry

# On the client, setup ssh tunneling
ssh -N -L 5000:localhost:5000 [email protected]

Registry vs. Index

The docker index is the public website that gives you user management and lets your browse all public repositories. Whereas the docker registry is “only” the storage backend service of the index.

Illustration: Docker Index vs. Docker Registry Service


A video from the developer of the Docker registry:

Docker: How to Use Your Own Private Registry


Self-Signed SSL-Certificates

If you host your registry with a self-signed SSL-certificate you will most likely get the following error when push your images:

docker push localhost/reverse-proxy

or when you login to the registry using docker login https:\\localhost

Error: Invalid Registry endpoint: Get https://localhost/v1/_ping: x509: certificate is valid for, not localhost
Error response from daemon: Invalid Registry endpoint: Get https://localhost/v1/_ping: x509: certificate signed by unknown authority

I don’t know how to prevent this other than creating a new SSL certificate that matches the hostname you are using and whose CA is trusted by your OS. If you have a better solution please let me know.


Fork allmark on GitHub