Cover Image: Self-hosted Docker Registry
Photo by Fejuz on Unsplash

April 13, 2026

Self-hosted Docker Registry

development devops opensource

Self-hosting is getting more and more popular regardless if we are talking homelabs or on-premise.

I like to host a lot of my things myself for the following reasons

  • learning opportunity
  • privacy
  • costs

One service that I host my self, both in my homelab and on-premise is a Docker Registry. A docker registry is a storage option for docker images. I use docker images for multiple things, the ones being public are stored public, but I have private images too.

Setting up with Docker Compose

Setting up a Docker Registry is quite straight forward, I use docker compose for this.

If you start creating a docker-compose.yml file

services:
  registry:
    image: registry:latest
    restart: always
    ports:
    - "5000:5000"
    environment:
      REGISTRY_AUTH: htpasswd
      REGISTRY_AUTH_HTPASSWD_REALM: Registry
      REGISTRY_AUTH_HTPASSWD_PATH: /auth/registry.password
      REGISTRY_STORAGE_FILESYSTEM_ROOTDIRECTORY: /data
    volumes:
      - ./data:/data
      - ./auth:/auth

Then you need some folders for data and authentication credentials.

mkdir -p data auth

For creating the authentication file, one can use the htpasswd-tool from apache.

sudo htpasswd -c /auth/registry.password <username>

This will prompt you for a password, to be use for the <username>, this will be needed later for authentication against the registry

To have the service running with docker and docker compose, you need to set up docker first. I'll not walk you through that, but here is a link: Install Docker Engine on Debian

After that is set up, you can boot the service, still will start the service, and detach the process to run in the background

docker compose up -d 

Reverse Proxy

As Docker Registry operates under the assumption of https with an SSL certificate, you would need some kind of reverse proxy in front; this could be Nginx Proxy Manager, Traefik, Caddy or a like.

I use Nginx Proxy Manager for most of my use cases.

Use the Registry

Login

When you are using the registry from CLI, you would have to login this can be done with the command docker login it will prompt you for a username and password.

docker login https://registry.domain.tld
Username: <username>
Password: <password>

Login Succeeded

Simple Dockerfile for testing

FROM alpine:latest

Build an image

Before we can push an image, we need to build one

docker build -f Dockerfile -t registry.domain.tld/alpine:latest .

Push

Now pushing it to the registry

docker push registry.domain.tld/alpine:latest 
The push refers to repository [registry.domain.tld/alpine]
8c60ab4201db: Pushed 
589002ba0eae: Pushed 
latest: digest: sha256:2bcc88c96d34411f01d4f709420f11171df91ad651d476039f79dff25b8eb553 size: 855

Pull

We can pull it for local use, if deleted locally since building it

docker pull registry.domain.tld/alpine:latest

Watch the images

You can visit the URL of the registry with https://registry.domain.tld/v2/_catalog type in your credentials, and you will see which images are available.

Use in CI

In the Use in CI-example I'm using GitLab CI

stages:
  - Docker Images

# https://docs.gitlab.com/ee/ci/docker/using_docker_build.html#docker-in-docker-with-tls-disabled-in-the-docker-executor
variables:
  # This instructs Docker not to start over TLS.
  DOCKER_TLS_CERTDIR: ""
  DOCKER_HOST: tcp://docker:2375

before_script:
  - export DOCKER_USERNAME=$DOCKER_USERNAME
  - export DOCKER_PASSWORD=$DOCKER_PASSWORD

default:
  image: docker:29.4.0
  services:
    - name: docker:29.4.0-dind
      alias: docker
      command: ["--tls=false"]

alpine:
  stage: Docker Images
  script:
    - docker login -u $DOCKER_USERNAME -p $DOCKER_PASSWORD https://registry.domain.tld
    - docker build -f Dockerfile -t registry.domain.tld/alpine:latest .
    - docker push registry.domain.tld/alpine:latest

Have fun with your private registry.

If you find any typos or incorrect information, please reach out on GitHub so that we can have the mistake corrected.

Want to Hire Me?

I work as a freelancer in my company 7th Green. My strengths include TYPO3, PHP, DevOps and Automation.

Reach out, I'd be happy to talk about your project.