Docker Registry
Store container images from Docker Registry in RustFS.
This guide connects the open-source Docker Registry (distribution) to RustFS as its S3 storage backend. You will run a registry that stores all layers and manifests in a RustFS bucket, then push and pull an image. The workflow was verified with registry:2 against rustfs/rustfs-x86-musl:v2.3.1.
You need Docker on the registry host.
Architecture
The registry stores every blob (layers and configs) and manifest as objects under docker/registry/v2/ in the bucket. The container itself is stateless, so registry nodes can be scaled horizontally against the same bucket.
Run the registry
Configure the S3 driver entirely through environment variables. REGISTRY_STORAGE_S3_REGIONENDPOINT points the AWS SDK at RustFS:
docker run -d --name registry --network oo-rustfs_default -p 5000:5000 \
-e REGISTRY_STORAGE=s3 \
-e REGISTRY_STORAGE_S3_ACCESSKEY=<your-access-key> \
-e REGISTRY_STORAGE_S3_SECRETKEY=<your-secret-key> \
-e REGISTRY_STORAGE_S3_REGION=us-east-1 \
-e REGISTRY_STORAGE_S3_BUCKET=registry-demo \
-e REGISTRY_STORAGE_S3_REGIONENDPOINT=http://<your-rustfs-endpoint>:9000 \
registry:2Check that the v2 API is up:
curl -s -o /dev/null -w "%{http_code}\n" http://localhost:5000/v2/200Push an image
Tag any local image for the registry and push it:
docker pull alpine:3.20
docker tag alpine:3.20 localhost:5000/rustfs-demo/alpine:3.20
docker push localhost:5000/rustfs-demo/alpine:3.203.20: digest: sha256:c64c687cbea9300178b30c95835354e34c4e4febc4badfe27102879de0483b5eVerify objects in RustFS
rc ls rustfs/registry-demo/docker/registry/v2/repositories/rustfs-demo/alpine/ -r | head -4_repositories/rustfs-demo/alpine/_layers/sha256/25f1d6b1.../link
_repositories/rustfs-demo/alpine/_manifests/revisions/sha256/c64c687c.../link
_repositories/rustfs-demo/alpine/_manifests/tags/3.20/current/linkEvery _layers link points at a blob object stored in the same bucket — the image data itself lives in RustFS, not on the registry host.

Pull the image back
Remove the local copy and pull from the registry — the layers come back from RustFS:
docker rmi localhost:5000/rustfs-demo/alpine:3.20
docker pull localhost:5000/rustfs-demo/alpine:3.203.20: Pulling from rustfs-demo/alpine
Digest: sha256:c64c687cbea9300178b30c95835354e34c4e4febc4badfe27102879de0483b5e
Status: Downloaded newer image for localhost:5000/rustfs-demo/alpine:3.20Stop or reset
docker rm -f registry
rc rm rustfs/registry-demo/ --recursive --forceTroubleshooting
Push fails with unknown or empty digest
Confirm REGISTRY_STORAGE_S3_REGIONENDPOINT is set — without it the registry sends requests to real AWS. Also check the bucket exists.
InvalidAccessKeyId at push time
The access key and secret key must be passed with REGISTRY_STORAGE_S3_ACCESSKEY / SECRETKEY; the registry does not read the AWS credential environment chain in this driver.
Pull returns manifest unknown after the registry restarted
Manifests and blobs live in the bucket, so a restart cannot lose them — check that both registry instances point at the same REGISTRY_STORAGE_S3_BUCKET and REGIONENDPOINT.
Next steps
- Compare with the Harbor guide when you need a UI, RBAC, or replication on top of the same bucket.
- Create dedicated production credentials with Access Key Management.
- Follow the distribution documentation for storage driver tuning and proxy-caching setups.