Skip to content

Docker - Private Registries

While Docker Hub is excellent for public images, organizations often need a private registry to store proprietary or sensitive container images. Docker provides an official registry image that you can run as a container to host your own private registry.

Running the Official Docker Registry Container

Section titled “Running the Official Docker Registry Container”

Step 1: Use docker run to start the registry container.

docker run -d -p 5000:5000 --restart=always --name local-registry registry:2

Explanation of the command:

  • -d: Run the container in detached mode (background).
  • -p 5000:5000: Map port 5000 on the Docker host to port 5000 inside the container (the default port the registry listens on).
  • --restart=always: Ensure the registry container restarts automatically if it stops or the Docker daemon restarts.
  • --name local-registry: Assign a convenient name to the container.
  • registry:2: Specifies the official Docker registry image, version 2 (latest stable).

Step 2: Verify the registry container is running using docker ps.

docker ps

You should see the local-registry container listed.

To use your private registry, you need to tag your images appropriately and then push them.

Step 3: Tag an existing image for your private registry. Let’s assume you have a local image named my-app:1.0.

# Tag 'my-app:1.0' to point to 'localhost:5000/my-private-app:1.0'
docker tag my-app:1.0 localhost:5000/my-private-app:1.0

The format for tagging for a private registry is: <registry-host>:<registry-port>/<image-name>:<tag>. Since our registry is running on the same host and listening on port 5000, we use localhost:5000.

Step 4: Push the tagged image to your private registry.

docker push localhost:5000/my-private-app:1.0

Docker will upload the image layers to your running local-registry container.

Step 5: To test pulling, first remove the local copies of the image (optional).

# Remove the specific tag pointing to the private registry
docker rmi localhost:5000/my-private-app:1.0
# Optionally remove the original tag too (if no other tags point to it)
# docker rmi my-app:1.0

Step 6: Now, pull the image from your private registry.

docker pull localhost:5000/my-private-app:1.0

Docker will download the image layers from your local-registry container. You can verify it’s back using docker images.

  • Security (HTTP vs HTTPS): By default, the registry container runs over HTTP. Docker clients, by default, expect registries to use HTTPS for security. To push/pull from an insecure registry like localhost:5000, you often need to configure your Docker daemon (via /etc/docker/daemon.json on Linux or Docker Desktop settings) to trust this registry. Search for insecure-registries in the Docker documentation.
  • Storage: The basic registry:2 container stores image layers within the container’s filesystem. If the container is removed, the images are lost. For persistent storage, you should mount a volume to /var/lib/registry inside the container: docker run -d -p 5000:5000 --restart=always --name local-registry -v registry-data:/var/lib/registry registry:2 (this uses a named volume registry-data).
  • Authentication/Authorization: The default registry has no authentication. For production use, you’ll need to configure TLS (HTTPS) and likely add authentication (e.g., basic auth, token auth).
  • UI: The basic registry has no web UI. Tools like Portus, Harbor, or Docker Trusted Registry (commercial) provide UIs and additional features.
  • Network Access: If you need to access the registry from other machines, replace localhost with the Docker host’s IP address or a resolvable hostname when tagging, pushing, and pulling, and ensure firewall rules allow access to port 5000.