dockerminikubedocker-registrydocker-volume

How to locally backup the images of a local Docker-registry?



Local Docker registry with persisted images

It should be possible to have an ephemeral registry container (and its docker volume), allowing to not download images more than once, even after the registry (or the whole Docker VM) is being throw away and recreated.

This would allow to pull just once the images, having them available when internet connectivity isn't good (or available at all); would allow also to mount a docker volume with pre-downloaded images.
It would be more convenient than having to manually docker push/docker pull onto the local registry, or to docker save/docker load each image that need to be available there.

Notes:


Solution

  • I managed it, here are the step-by-step instructions. Hopefully will make life easier to somebody else!

    Configuration

    Define first your environment variables with the desired values. See env-vars in the code below (PROXIED_REGISTRY, REGISTRY_USERNAME, REGISTRY_PASSWORD, PATH_WHERE_TO_PERSIST_IMAGES, etc.)

    On the host machine

    Minikube

    If using minikube, first bind to docker on its VM's

    eval $(minikube docker-env)
    

    or run the commands directly from inside the VM, via minikube ssh.

    Create local registry

    (note: some envs might be unnecessary; check Docker docs to see what you need)

    The -v option mounts onto the local registry the path where you want to persist the registry data (repositories folders and image layers).
    When you use Minikube, this latter will automatically mount the home folder from the host (/Users/, on macOS) onto the virtual machine where Docker is run.

    docker run -d -p 5000:5000 \
        -e STANDALONE=false \
        -e "REGISTRY_LOG_LEVEL=debug" \
        -e "REGISTRY_REDIRECT_DISABLE=true" \
        -e MIRROR_SOURCE="https://${PROXIED_REGISTRY}" \
        -e REGISTRY_PROXY_REMOTEURL="https://${PROXIED_REGISTRY}" \
        -e REGISTRY_PROXY_USERNAME="${REGISTRY_USER}" \
        -e REGISTRY_PROXY_PASSWORD="${REGISTRY_PASSWORD}" \
        -v /Users/${MACOS_USERNAME}/${PATH_WHERE_TO_PERSIST_IMAGES}/docker/registry:/var/lib/registry \
        --restart=always \
        --name local-registry \
        registry:2
    

    Login to your local registry

    echo -n "${REGISTRY_PASSWORD}" | docker login -u "${REGISTRY_USER}" --password-stdin "localhost:5000"
    

    (optional) Verify that the persist directories are present

    docker exec registry ls -la /var/lib/registry/docker/registry
    ll /Users/${MACOS_USERNAME}/${PATH_WHERE_TO_PERSIST_IMAGES}/docker/registry/docker/registry
    

    Try to pull one image from your private registry

    (to see it proxied through the repository localhost:5000)

    docker pull localhost:5000/${REPOSITORY}/${IMAGE}:${IMAGE_TAG}
    

    (optional) Verify the image data has been synced on local host, where desired

    docker exec registry ls -la /var/lib/registry/docker/registry
    ll /Users/${MACOS_USERNAME}/${PATH_WHERE_TO_PERSIST_IMAGES}/docker/registry/docker/registry
    

    If using Kubernetes

    change the deployment spec container image to:

    localhost:5000/${REPOSITORY}/${IMAGE}:${IMAGE_TAG}
    

    Et voila!
    You now can keep the images downloaded from your repository stored onto your host machine!
    If internet is available, the local registry will ensure to have the most recent version of your pulled images, requesting it to the proxied registry (private, or the the Docker hub).

    And you will have a last resort backup to run your container also when your internet connection is too slow for re-downloading everything you need, or is unavailable altogether!
    (really useful with Minikube, when you need to destroy your docker virtual machine)


    References: