oci-registry
is an implementation of the OCI Registry spec with filesystem and S3 storage back-ends.
[[TOC]]
registry
uses approximately 130 MiB of memory to mirror docker.io; five replicas of oci-registry
combined use approximately 60 MiB to mirror everything in example.yaml, plus one private registry. CPU is negligible for both.oci-registry
only supports being a pull-through cache (a mirror) at this time. Push support is planned.oci-registry
with TLS (https) is not supported and support will not be added.
oci-registry
, that is the recommended configurationdocker
and containerd
has been performed. This is planned after push support is implemented.docker
Mirroring docker.io
is the default configuration. Start oci-registry
:
oci-registry --listen 0.0.0.0:8080 filesystem --root /tmp/oci-mirror
Configure Docker's daemon.json
to use the registry:
{
"registry-mirrors": ["http://localhost:8080"]
}
Restart Docker and it will start pulling images from docker.io
through oci-registry
.
NOTE: Mirroring registries other than docker.io
is not possible with Docker.
containerd
containerd
provides a mechanism for mirroring any registry you want, and sends the upstream registry as a querystring parameter in all its requests. This means that we can mirror any number of registries to containerd
with a single instance of oci-registry
.
cri-o
cri-o
requires defining each registry you want to mirror, but you can use a separate path for each registry to inform oci-registry
of which registry the request is for.
oci-registry
oci-registry
's default configuration is to mirror any registry for which it receives requests, connecting to upstream with HTTPS, rejecting invalid certs, and using the namespace as the upstream registry host - e.g. requests for gcr.io
images will be made to https://gcr.io/ - with the exception of docker.io
, which will be pointed to https://registry-1.docker.io
In short, oci-registry
's default configuration will work for most public registries, but can be added to with --upstream-config-file
. See example.yaml for real world examples, or the following contrived private registry example:
# namespace and host are the only two required keys
- namespace: example.com
host: registry.example.com
# Connecting with TLS is the default
tls: true
# Requiring valid TLS certs is the default
accept_invalid_certs: false
# This hypothetical registry checks the HTTP User-Agent header to make sure there's no malarkey going on, so pretend to be containerd
user_agent: "containerd/1.6.8"
# This hypothetical registry requires authentication, so let's give it our username and password
username: example
password: hunter2
# This hypothetical registry is used for active development, so let's _always_ see if we have the latest manifest for a given image
manifest_invalidation_time: 0s
# Blobs are identified by the SHA256 hash of their contents, so they probably won't change frequently, if ever
blob_invalidation_time: 30d
To avoid having to store credentials in a plaintext file, they can be set by storing a JSON map in the $UPSTREAM_CREDENTIALS
environment variable, like so:
UPSTREAM_CREDENTIALS='{"example.com": {"username": "example", "password": "hunter2"}, "docker.io": {"username": "aaa", "password": "bbb"}}'
Note that this is not exposed in the Helm chart, because the configuration is already itself mounted in from a secret.
containerd
Recent versions of containerd
(1.5+) use per-host configuration files; for older versions, config instructions can be found in the deprecated section here.
Assuming default paths, make sure your /etc/containerd/config.toml
contains the following:
[plugins."io.containerd.grpc.v1.cri".registry]
config_path = "/etc/containerd/certs.d"
Then, in /etc/containerd/certs.d
, create a directory for each registry you want to mirror and create a hosts.toml
pointing at oci-registry
:
mkdir /etc/containerd/certs.d/docker.io
cat > /etc/containerd/certs.d/docker.io/hosts.toml <<EOF
server = "https://registry-1.docker.io"
[host."http://localhost:8080"]
capabilities = ["pull", "resolve"]
EOF
mkdir /etc/containerd/certs.d/gcr.io
cat > /etc/containerd/certs.d/gcr.io/hosts.toml <<EOF
server = "https://gcr.io"
[host."http://localhost:8080"]
capabilities = ["pull", "resolve"]
EOF
The above example will configure containerd
to attempt to pull docker.io
and gcr.io
manifests and blobs from oci-registry
listening on localhost:8080
, while sticking with the original hosts for pushing, and using the original hosts if something goes wrong with oci-registry
.
cri-o
cri-o
uses the common registries.conf
configuration file to specify which registries to mirror.
Assuming default paths, simply add the following to /etc/containers/registries.conf
:
[[registry]]
location = "docker.io"
[[registry.mirror]]
location = "localhost:8080/docker.io"
insecure = true
[[registry]]
location = "gcr.io"
[[registry.mirror]]
location = "localhost:8080/gcr.io"
insecure = true
The above example will configure cri-o
to attempt to pull docker.io
and gcr.io
manifests and blobs from oci-registry
listening on localhost:8080
, while sticking with the original hosts for pushing, and using the original hosts if something goes wrong with oci-registry
.
The Github repo is a mirror. Project management is done in the main repo. In addition, there is a Matrix room.