Railway

Deploy Docker Registry

A private server for storing and sharing container images

Deploy Docker Registry

Just deployed

/data

Just deployed

registry-storage

Bucket

Just deployed

Deploy and Host Docker Registry on Railway

Docker Registry is the reference implementation of the OCI Distribution Specification, the server behind docker push and docker pull. Maintained by the CNCF as distribution/distribution, it gives a team its own image store rather than an account on a shared one, so proprietary images stay private, CI stops hitting Docker Hub rate limits, and build artifacts live where you choose.

Self-host Docker Registry on Railway and the template wires up three services. registry runs registry:3 and serves the /v2/ API on a public HTTPS domain — the endpoint you point docker login at. Railway terminates TLS for you, so no insecure-registries entry is needed on any client. registry-ui runs joxit/docker-registry-ui, a browsable catalog of everything you have pushed; it proxies the registry over the private network, so one login covers both. Redis holds distribution's shared blob-descriptor cache, which lets the registry run more than one replica coherently. Every layer, manifest and tag goes to a Railway object storage bucket rather than a disk, so nothing is pinned to a single container.

Diagram of the registry, registry-ui and Redis services on Railway

Getting Started with Docker Registry on Railway

Set REGISTRY_PASSWORD at deploy time — that, with the optional REGISTRY_USERNAME (default admin), is the one account the registry accepts. There are no default credentials and anonymous access is rejected, so a fresh deployment is closed the moment it is live. Open the registry-ui URL first: the browser shows a basic-auth prompt from the registry itself, and signing in gets you an empty catalog. Now log in from your terminal against the registry URL, tag a local image with that hostname and push it:

docker login registry-production.up.railway.app -u admin
docker tag alpine:3.23 registry-production.up.railway.app/base/alpine:3.23
docker push registry-production.up.railway.app/base/alpine:3.23

Refresh the UI and the repository appears with its tag count. Click into it for creation date, size, content digest and architecture, and the history icon for layer commands, entrypoint and environment. To confirm reads, docker pull the same tag elsewhere.

Docker Registry UI listing four pushed image repositories

Tag table for web/nginx showing size, digest and architecture

Image history panel with the nginx layer commands and environment

About Hosting Docker Registry

A container registry is a content-addressable store: clients upload layers by digest, then a manifest naming them, then a tag pointing at the manifest. Docker Registry implements exactly that and nothing more, which is why it is small and fast. Teams self-host when images hold source, models or customer data that should not sit in a third-party account, or when CI pulls enough that public rate limits bite.

  • Full OCI Distribution Specification v1.1 support: Docker, Podman, BuildKit, containerd, Skopeo, ORAS and Helm all work unchanged
  • Username and password auth on every request, catalog reads included
  • Object-storage backend, so image data is not tied to one container's disk
  • Tag deletion through the API and the web UI, plus Prometheus metrics privately
  • Stores any OCI artifact, not only images — Helm charts, WASM modules, SBOMs

The split is clean: the registry owns the API and all storage access, the UI is a static app plus a small reverse proxy holding no state, and Redis caches blob descriptors so repeated lookups skip object storage.

Why Deploy Docker Registry on Railway

Railway removes the parts of running a registry that are not about images:

  • HTTPS is provisioned automatically, which Docker clients require
  • Object storage is attached in the same project, credentials as references
  • Redis is one managed service, not a second thing to operate
  • The private network keeps the UI-to-registry hop off the internet
  • More replicas is a slider, because no service owns local state

Common Use Cases

  • Private images for a team — build in CI, push here, pull from staging and production, no per-seat cost
  • Your organisation's golden base images — so builds stop depending on public registry availability
  • Kubernetes or Nomad clusters — pulls stay inside your own infrastructure
  • OCI artifact storage — Helm charts, WASM modules and SBOMs, addressed by digest

Dependencies for Docker Registry

  • registrygridalpha/docker-registry-railway, a thin layer on the official registry:3 image that generates the bcrypt password file and storage configuration at startup
  • registry-uijoxit/docker-registry-ui:latest, web catalog and reverse proxy
  • Redis — managed Redis, distribution's blob-descriptor cache
  • Object storage — a bucket holding every layer, manifest and tag

Environment Variables Reference

VariableServicePurpose
REGISTRY_PASSWORDregistryPassword docker login accepts. Required
REGISTRY_USERNAMEregistryAccount name, defaults to admin
REGISTRY_HTTP_SECRETregistrySigns upload state; identical on every replica
PORTregistry5001, the private port the health check probes; the API stays on 5000
S3_BUCKET, S3_ENDPOINT, S3_ACCESS_KEY_ID, S3_SECRET_ACCESS_KEY, S3_REGIONregistryBucket credentials, as references
REDIS_HOST, REDIS_PORT, REDIS_USER, REDIS_PASSWORDregistryBlob-descriptor cache; unset them for an in-process one
NGINX_PROXY_PASS_URLregistry-uiPrivate address of the registry
DELETE_IMAGESregistry-uiWhether the UI offers tag deletion

Anything not listed can be set with distribution's own REGISTRY_ overrides, layered on top of the generated configuration file.

Deployment Dependencies

Hardware Requirements for Self-Hosting Docker Registry

The registry is a single Go binary streaming bytes, so it is bound by bandwidth, not CPU.

ResourceMinimumRecommended
CPU0.5 vCPU1–2 vCPU
RAM256 MB512 MB–1 GB
StorageObject storage, grows with imagesObject storage; no volume needed
RuntimeGo 1.25 binary in an Alpine imageSame, plus Redis for multi-replica

Self-Hosting Docker Registry with Docker

The smallest useful local instance keeps images on a mounted volume and has no password:

docker run -d -p 5000:5000 --name registry \
  -v registry-data:/var/lib/registry \
  registry:3

Anything reachable from another machine needs TLS and a password. Generate a bcrypt entry — the only format distribution accepts — and point the registry at it:

htpasswd -Bbn admin 'your-password' > auth/htpasswd
docker run -d -p 5000:5000 --name registry \
  -v "$PWD/auth:/auth" -v registry-data:/var/lib/registry \
  -e REGISTRY_AUTH=htpasswd \
  -e REGISTRY_AUTH_HTPASSWD_REALM="Docker Registry" \
  -e REGISTRY_AUTH_HTPASSWD_PATH=/auth/htpasswd \
  registry:3

Swapping the filesystem backend for S3-compatible object storage means replacing the storage.filesystem block in config.yml with a storage.s3 block; the two cannot both be present. On Railway that file is generated at boot.

Is Docker Registry Free?

Docker Registry is open source under the Apache 2.0 licence, free for any use including commercial, with no seat count, image limit or paid tier. On Railway you pay only for what the deployment consumes: two small containers, managed Redis, and object storage billed by the gigabyte.

FAQ

What is Docker Registry?

The open-source server that stores and distributes container images, implementing the OCI Distribution Specification. Every docker push and docker pull speaks its API, whether the far end is Docker Hub or your own instance.

What does this Railway template deploy?

Three services: the registry on a public HTTPS domain, a web UI for browsing repositories and tags, and managed Redis for the blob-descriptor cache. Image data lives in a Railway object storage bucket.

Why does the template include Redis and object storage?

Object storage keeps image data off any container's disk, so the registry stays stateless and survives redeploys. Redis holds the blob-descriptor cache all replicas share, which is what makes running more than one correct.

Can I create more than one user in self-hosted Docker Registry?

The password-file backend has no per-user permissions — anyone who can pull can also push and delete. For separate read-only and read-write identities, distribution supports a token authentication server via its auth.token settings.

How do I reclaim space after deleting images from Docker Registry?

Deleting a tag removes the reference immediately, but the layers are freed by a separate registry garbage-collect pass, which upstream requires you to run against a read-only registry.


Template Content

More templates in this category

View Template
Garage S3 Storage
Ultra-light S3 server: fast, open-source, plug-and-play.

PROJETOS
8
View Template
Redis
Self Host Latest Redis with Railway

2
View Template
EasyImg
Simple self-hostable Nuxt.js personal image hosting system.

Muhammad Bilal
0