This repository runs a private Docker registry using Docker Compose.
- Starts a self-hosted Docker registry on port
5000by default - Uses
htpasswdbasic authentication - Persists image data in
./data - Stores auth credentials in
./auth/htpasswd - Reads server-specific ports, usernames, passwords, and UI secrets from
.env - Enables image deletion and stale upload cleanup
- Docker
- Docker Compose
This repo is intended to be pushed to GitHub and deployed on multiple servers.
- Commit the code,
docker-compose.yml,config.yml, and.env.example - Do not commit
.env,auth/htpasswd, ordata/ - Each server keeps its own
.env, auth file, and image data locally - A future
git pullupdates the code, but does not overwrite that server's local.envor stored registry data
- Create a server-local environment file:
cp .env.example .env- Edit
.envfor that server:
REGISTRY_PORT=5000
REGISTRY_UI_PORT=8101
REGISTRY_LOGIN_HOST=registry.example.com
REGISTRY_USERNAME=your-registry-user
REGISTRY_PASSWORD=your-registry-password
APP_AUTH_USERNAME=operator
APP_AUTH_PASSWORD=your-ui-password
APP_SESSION_SECRET=use-a-long-random-secret- Create the auth file and required directories:
./scripts/setup-auth.shThe script reads REGISTRY_USERNAME and REGISTRY_PASSWORD from .env. Positional arguments still override them:
./scripts/setup-auth.sh <username> <password>- Start the registry:
docker compose up -d- Log in:
docker login <your-server-host>:<your-registry-port>- Tag and push an image:
docker pull nginx:alpine
docker tag nginx:alpine <your-server-host>:<your-registry-port>/nginx:alpine
docker push <your-server-host>:<your-registry-port>/nginx:alpine.
|-- .env.example
|-- config.yml
|-- docker-compose.yml
`-- scripts/
`-- setup-auth.sh
Start:
docker compose up -dStop:
docker compose downView logs:
docker compose logs -f registryList stored repositories:
curl -u <username>:<password> http://<your-server-host>:<your-registry-port>/v2/_catalogdocker-compose.ymluses.envfor deployment-specific values such as ports, credentials, container names, and UI secrets..env.exampleis the tracked template. Real.envfiles stay local on each server.docker-compose.ymlrunsregistry:2.7as UID/GID1000:1000by default.config.ymlenables delete operations and upload purging.- The registry is configured for plain HTTP on port
5000. For external exposure, put it behind TLS termination or a reverse proxy.
.envcontains per-server runtime settings and should never be committed.auth/htpasswdcontains the registry credentials.data/contains pushed image layers and manifests.- All three are intentionally ignored from version control.
To rotate credentials, rerun:
./scripts/setup-auth.shThen restart the service:
docker compose restart registryIf you change .env, run:
docker compose up -dThat reapplies the new environment configuration without replacing your local .env, auth/, or data/.