In my previous blog post, I used skopeo to mirror upstream images to my local Docker Registry. This worked well, as long as I didn't need multi-arch images. Some images, like for log collection, need to be run on multiple architectures in my homelab, so this became a blocking issue.

Introducing regsync

Regsync is tool to work with local and remote container images. It has an option to copy an image from one registry to another. This is what we need to mirror images. On top of that, the multi-arch support worked way better than with skopeo. It works with a .yaml configuration file that contains all the images to mirror.

Automating the mirroring

In my Homelab, I'm running a Woodpecker server, so I'm going to use this to mirror the images in an automated way.

I have one simple .txt file containing all images I want to mirror. A bash loop creates the yaml configuration file.

#!/usr/bin/env bash

set -e

# Read every line in image_list.txt
while IFS= read -r line; do
  # Split on first '/' and copy with Skopeo
  IFS='/' read -r registry image <<< "$line"
  cat <<EOF >> config.yaml
  - source: ${registry}/${image}
    target: registry.service.tcassaert.com/${image}
    type: image
EOF
done < image_list.txt

An example .woodpecker.yaml file can look like this:

---
platform: linux/amd64
pipeline:
  generate_yaml:
    image: alpine:3.15.4
    commands:
      - apk add bash
      - /bin/bash create_yaml.sh
  mirror:
    image: regclient/regsync:v0.4.1-alpine
    commands:
      - regsync once -c config.yaml

This is all stored in a git repository. Every new commit will trigger a pipeline run and mirror the new images to our local Docker registry.

The main disadvantage to a pull-through registry is the need to add a new image manually to a list. But at the same time, this can be a nice way of documenting the different images used in your environment.

An additional step could be to delete all the unused images in your Docker registry.