@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@
          @@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@
    @@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@
    @@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@
                  =@@@@
                  @@@@
                 @@@@
                @@@@              @@@@
               @@@@                @@@@@
              @@@@@                 @@@@@
             @@@@@                   @@@@@
            :@@@@                     *@@@@
            @@@@     :@@@@@@@@@@@@@@@@@@@@@@
      @@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@
      @@@@@@@@@@@@@@@@=                   @@@@
                                           @`
                 [deroad's  blog]
                      [home]
# 2025-04-01 | Maintaining an "offline" docker registry
{
  I am in a situation where i have a homelab which for certain reasons can be
  considered offline/internet detached/airgapped.
  I still want to deploy software using docker images using kubernetes and docker
  compose, but all the normal tools which people could use, do not work without an
  internet connection.
  So you can consider what i'm writing kinda like a guide containing all the
  information about how you would maintain an "offline" docker registry.
  Maybe i will write another blogpost about how to deploy a kubernetes cluster in
  the same offline/internet detached/airgapped environment.
  You will need some tools; the most important one is called crane and will allow
  you to download images and push them to your private registry.
  There are 3 commands that can mainly used to fetch the containers:
  crane copy SRC DST: copies a remote image from src to dst
  crane pull IMAGE TARBALL: pull remote image and saves locally into a tarball
  crane push TARBALL IMAGE: push local image (tarball) to a remote registry
  One thing must be mentioned:
  crane copy .
  The second one is the registry container.
  You can pull the image using crane:
  crane pull registry:latest registry.tar
  Then load it via docker image load -i registry.tar in the offline environment.
  Once this is done, start the docker registry on the airgapped environment and
  push the images over network using the following command:
  crane pull domain.tld/something:latest something.tar
  crane push something.tar registry.local/something:latest
  Or alternatively, if your machine is connected at the same time to the offline
  environment and to the internet, you can directly use
  crane copy domain.tld/something:latest registry.local/something:latest
  Let's make a real world example:
  My registry is hosted on a local machine and accessible via 10.0.0.8:5000 and i
  want to download grafana version 11.6.0.
  
  user@host$ crane pull grafana/grafana:11.6.0 grafana_11.6.0.tar
  user@host$ crane push grafana_11.6.0.tar 10.0.0.8:5000/grafana/grafana:11.6.0
  2025/04/01 17:24:53 pushed blob: sha256:70ca445a67c234b5ddcd15a8b32bb3f4...
  2025/04/01 17:24:53 pushed blob: sha256:f18232174bc91741fdf3da96d8501109...
  2025/04/01 17:24:53 pushed blob: sha256:2a08a00fe44664b664b9795b8cbae637...
  2025/04/01 17:24:53 pushed blob: sha256:bbb8b5218cfb0ad864924f6377ecc7c2...
  2025/04/01 17:24:53 pushed blob: sha256:5b32a5607528e289fe820d31daa67a5a...
  2025/04/01 17:24:54 10.0.0.8:5000/grafana/grafana:11.6.0: digest: ... size: 1894
  10.0.0.8:5000/grafana/grafana@sha256:bcb0b32f176f8ac74cb95d79a20c2e2d...
  
  user@host$ crane copy grafana/grafana:11.6.0 10.0.0.8:5000/grafana/grafana:11.6.0
  2025/04/01 15:18:02 Copying from grafana/grafana:11.6.0 to 10.0.0.8:5000/grafana/grafana:11.6.0
  2025/04/01 15:18:08 pushed blob: sha256:b6004df161736a5a055cbcc257e1c7e0...
  2025/04/01 15:18:08 pushed blob: sha256:b155c33e844d799826c7a565ad9b9dc4...
  2025/04/01 15:18:11 pushed blob: sha256:f428c0adaf7edd843b951831007cb2a2...
  2025/04/01 15:18:11 pushed blob: sha256:96526aa774ef0126ad0fe9e9a95764c5...
  2025/04/01 15:18:11 pushed blob: sha256:cf94ed2a3f5c175e29737c8a829aec02...
  2025/04/01 15:18:11 10.0.0.8:5000/grafana/grafana:11.6.0: digest: ... size: 1093
  The last point to talk about is regarding how to update software.
  There is a command you can use with crane to check the digest and compare them:
  crane digest domain.tld/something:latest
  This works also with the private repository, but keep in mind if you have used
  the 1st method, the digest will be always different.
}
# References:
  Google Crane
  https://github.com/google/go-containerregistry/tree/main/cmd/crane
  https://github.com/google/go-containerregistry/blob/main/cmd/crane/doc/crane.md