'How to put docker registry read only (in order to safely garbage collect)?

https://docs.docker.com/registry/garbage-collection/ indicates

"Note: You should ensure that the registry is in read-only mode or not running at all. If you were to upload an image while garbage collection is running, there is the risk that the image’s layers are mistakenly deleted leading to a corrupted image."

But if I stop the registry container, then I cannot execute the garbage collection. I do not see how I can switch to read only mode.

Here is how I start the garbage collection:

docker exec registry bin/registry garbage-collect --delete-untagged /etc/docker/registry/config.yml

And how the registry is started:

docker run -d --restart=always --name registry \
        -e REGISTRY_HTTP_ADDR=0.0.0.0:5000 \
        -e "ENABLE_CORS=true" \
        -e REGISTRY_HTTP_HEADERS_Access-Control-Allow-Origin='["*"]' \
        -p 5000:5000 \
        -v /registry-storage:/var/lib/registry registry:2


Solution 1:[1]

There's a readonly configuration option, so you could restart the registry with:

docker run -d --restart=always --name registry \
        -e REGISTRY_HTTP_ADDR=0.0.0.0:5000 \
        -e REGISTRY_MAINTENANCE_READONLY_ENABLED=true \
        -e "ENABLE_CORS=true" \
        -e REGISTRY_HTTP_HEADERS_Access-Control-Allow-Origin='["*"]' \
        -p 5000:5000 \
        -v /registry-storage:/var/lib/registry registry:2

Or you could just mount the volume as read-only:

docker run -d --restart=always --name registry \
        -e REGISTRY_HTTP_ADDR=0.0.0.0:5000 \
        -e "ENABLE_CORS=true" \
        -e REGISTRY_HTTP_HEADERS_Access-Control-Allow-Origin='["*"]' \
        -p 5000:5000 \
        -v /registry-storage:/var/lib/registry:ro registry:2

If you go with the latter option, or just decide to shutdown the registry, GC can be run in a separate container, it's not required to use an exec:

docker run --rm \
    -v /registry-storage:/var/lib/registry \
    --entrypoint /bin/sh \
    registry:2 bin/registry garbage-collect --delete-untagged /etc/docker/registry/config.yml

Make sure to test --delete-untagged before using it in any production environment. Last time I looked at the code, I think it was to aggressive with multi-platform images. At some point I'd like to rewrite it to be safe on running servers, and maybe just run periodically in the background instead of being a separate job.

Sources

This article follows the attribution requirements of Stack Overflow and is licensed under CC BY-SA 3.0.

Source: Stack Overflow

Solution Source
Solution 1 BMitch