Deploy Docker Registry | (Just Updated) Private Registry With Login, Not Open to the Internet
Private Docker registry with login. Images survive redeploys, deletes work
registry
Just deployed
/var/lib/registry
Deploy and Host Docker Registry on Railway
Docker Registry is the CNCF distribution
project — the reference implementation of the OCI registry API, and the same
software Docker Hub was built on. It stores and serves container images over
docker push and docker pull, with no account, no rate limit and no pull
quota, on storage you own.
This listing runs registry:3.0.0 pinned by digest, behind basic
authentication that is configured for you on first boot.
About Hosting Docker Registry
A registry is a stateful HTTP service: layers land on disk as they are pushed, and the whole point of it is that they are still there tomorrow. Two things therefore decide whether a hosted registry is usable, and both are easy to get wrong.
The first is storage. Without a persistent volume the filesystem driver writes
into the container, so every redeploy silently discards every image that was
ever pushed. Here the volume is mounted at /var/lib/registry, and the
container refuses to start if that path is not writable — a registry that
answers its healthcheck while dropping every push is the failure that is
hardest to notice from outside.
The second is authentication. Distribution reads its entire configuration from
environment variables except credentials: REGISTRY_AUTH_HTPASSWD_PATH is a
file path, and only bcrypt hashes are accepted in it. So a registry deployed
from environment variables alone is anonymous, and on a public domain that means
anyone who finds the URL can push, pull and overwrite every tag. This image
builds that htpasswd file from REGISTRY_USERNAME and REGISTRY_PASSWORD at
boot, so the deploy is closed from its first second.
Why Deploy Docker Registry?
- It is private.
docker loginis required for every push and pull.REGISTRY_PASSWORDis generated for you at deploy time; the user name isadminunless you change it. - Images survive redeploys. The volume is mounted at the registry's own data root, and a write test runs before the port opens.
- You can actually delete things.
REGISTRY_STORAGE_DELETE_ENABLED=trueis set, so the delete API returns202instead of405and the volume is reclaimable. Without it a registry only ever grows. - The version cannot move under you. The image is pinned by digest, so a redeploy six months from now runs exactly the binary you tested against your volume — never a storage-driver change you did not ask for.
- No pull limits. Docker Hub throttles anonymous and free pulls; your CI pulling from here does not.
Common Use Cases
- A private registry for CI pipelines that build images on every commit, without paying per-seat for a hosted one.
- A cache and mirror in front of Docker Hub so builds stop failing on pull-rate limits.
- Distributing internal images to a team, a homelab, or a fleet of servers.
- Holding release artifacts for Railway services themselves — Railway can deploy from any image URL, including this one.
Dependencies for Docker Registry Hosting
Docker Registry is a single Go binary and depends on no database, cache or external service. It needs only a writable volume, which this template attaches.
Deployment Dependencies
- distribution — the upstream project.
- Registry configuration reference
- Railway wrapper image — the Dockerfile and entrypoint used here, so you can read exactly what was added to the upstream image.
After deploying
Log in with docker login , using the user name admin and the
value Railway generated for the REGISTRY_PASSWORD variable. Then:
docker tag myapp:latest /myapp:latest
docker push /myapp:latest
docker pull /myapp:latest
The catalog is at /v2/_catalog and needs the same credentials.
To reclaim space after deleting manifests, run the garbage collector from the service's shell:
registry garbage-collect --delete-untagged /etc/distribution/config.yml
Template Content