All Projects → jpetazzo → Registrish

jpetazzo / Registrish

Dirty hack to run a read-only, public Docker registry on almost any static file hosting service (e.g. NGINX, Netlify, S3...)

Programming Languages

shell
77523 projects

Projects that are alternatives of or similar to Registrish

Distribution
The toolkit to pack, ship, store, and deliver container content
Stars: ✭ 6,445 (+5315.97%)
Mutual labels:  registry, containers
Trow
Container Registry and Image Management for Kubernetes Clusters
Stars: ✭ 453 (+280.67%)
Mutual labels:  registry, containers
Pipeline
Banzai Cloud Pipeline is a solution-oriented application platform which allows enterprises to develop, deploy and securely scale container-based applications in multi- and hybrid-cloud environments.
Stars: ✭ 1,445 (+1114.29%)
Mutual labels:  containers
Kontena
The developer friendly container and micro services platform. Works on any cloud, easy to setup, simple to use.
Stars: ✭ 1,480 (+1143.7%)
Mutual labels:  containers
Labs
This is a collection of tutorials for learning how to use Docker with various tools. Contributions welcome.
Stars: ✭ 10,443 (+8675.63%)
Mutual labels:  containers
Reg
Docker registry v2 command line client and repo listing generator with security checks.
Stars: ✭ 1,485 (+1147.9%)
Mutual labels:  containers
Lxc Ci
LXC continuous integration and build scripts
Stars: ✭ 110 (-7.56%)
Mutual labels:  containers
Npm
🚢 semantic-release plugin to publish a npm package
Stars: ✭ 103 (-13.45%)
Mutual labels:  registry
Bitnami Docker Mysql
Bitnami MySQL Docker Image
Stars: ✭ 116 (-2.52%)
Mutual labels:  containers
Cas Webapp Docker
Apereo CAS Server web application running inside a docker container.
Stars: ✭ 107 (-10.08%)
Mutual labels:  containers
Dockle
Container Image Linter for Security, Helping build the Best-Practice Docker Image, Easy to start
Stars: ✭ 1,713 (+1339.5%)
Mutual labels:  containers
Selinux
common selinux implementation
Stars: ✭ 107 (-10.08%)
Mutual labels:  containers
Image Spec
OCI Image Format
Stars: ✭ 1,851 (+1455.46%)
Mutual labels:  containers
Bitnami Docker Node
Bitnami Node.js Docker Image
Stars: ✭ 111 (-6.72%)
Mutual labels:  containers
Ouroboros
Automatically update running docker containers with newest available image
Stars: ✭ 1,474 (+1138.66%)
Mutual labels:  containers
Ruby Lxc
ruby bindings for liblxc
Stars: ✭ 115 (-3.36%)
Mutual labels:  containers
Karn
Simplifying Seccomp enforcement in containerized or non-containerized apps
Stars: ✭ 104 (-12.61%)
Mutual labels:  containers
Minideb
A small image based on Debian designed for use in containers
Stars: ✭ 1,561 (+1211.76%)
Mutual labels:  containers
Docker Slim
DockerSlim (docker-slim): Don't change anything in your Docker container image and minify it by up to 30x (and for compiled languages even more) making it secure too! (free and open source)
Stars: ✭ 11,712 (+9742.02%)
Mutual labels:  containers
Lastbackend
System for containerized apps management. From build to scaling.
Stars: ✭ 1,536 (+1190.76%)
Mutual labels:  containers

Registrish

This is kind of a Docker registry, but with many restrictions:

  • it's read-only (you can pull but you cannot push)
  • it only supports public access (no authentication)
  • it only supports Image Manifest Version 2, Schema 2
  • it probably doesn't support multi-arch images

However, it can be deployed without running the registry code, using almost any static file hosting service. For instance:

  • a plain NGINX server (without LUA, JSX, or whatever custom module)
  • the Netlify CDN
  • an object store like S3, or a compatible one like Scaleway

Example

The following commands will run an Alpine image hosted on various locations, thanks to registrish.

Netlify:

docker run registrish.netlify.app/alpine echo hello there

S3:

docker run registrish.s3.amazonaws.com/alpine echo hello there

Scaleway object store:

docker run registrish.s3.fr-par.scw.cloud/alpine echo hello there

How to use this

Quick example. You need to have either a local Docker Engine, or Skopeo installed, to pull images.

# First, fetch an image (or a few).
# If you have a Docker Engine running locally:
./fetch-image-from-docker-hub-with-intermediate-registry.sh alpine latest
# Or, if you have Skopeo:
./fetch-image-from-docker-hub-with-skopeo.sh alpine latest

# If you want to be able to pull directly from containerd, run this:
./link-manifests-by-sha.sh
# (For each manifest, it will create a copy named sha256:xxxxxxxx...)

# Check that image was correctly downloaded.
./list-images.sh

# Start NGINX in a local Docker container. (It will be on port 5555.)
docker-compose up -d
# Run image from the registry.
docker run localhost:5555/alpine echo hello there

# Deploy to Netlify.
# (This assumes that you have installed and configured the Netlify CLI.)
netlify deploy
# Run image from the registry.
docker run deployed-site-name.netlify.app/alpine echo hello there

# Deploy to an S3 bucket.
# (This assumes that your AWS credentials have been set up correctly,
# e.g. through AWS_ACCESS_KEY_ID and AWS_SECRET_ACCESS_KEY variables.)
BUCKETNAME=bucketname
aws s3 sync --acl public-read v2/ s3://$BUCKETNAME/v2/
aws s3 cp   --acl public-read v2/ s3://$BUCKETNAME/v2/  \
    --recursive --exclude '*' --include '*/manifests/*' \
    --content-type application/vnd.docker.distribution.manifest.v2+json  \
    --metadata-directive REPLACE
# Run image from the registry.
docker run $BUCKETNAME.s3.amazonaws.com/alpine echo hello there

# Deploy to an S3-compatible object store, e.g. Scaleway.
# (This assumes that your credentials have been set up correctly.)
BUCKETNAME=bucketname
ENDPOINT=s3.fr-par.scw.cloud
aws s3 sync --acl public-read v2/ s3://$BUCKETNAME/v2/  \
    --endpoint-url https://$ENDPOINT
aws s3 cp   --acl public-read v2/ s3://$BUCKETNAME/v2/  \
    --recursive --exclude '*' --include '*/manifests/*' \
    --content-type application/vnd.docker.distribution.manifest.v2+json  \
    --metadata-directive REPLACE \
    --endpoint-url https://$ENDPOINT
# Run image from the registry.
docker run $BUCKETNAME.$ENDPOINT/alpine echo hello there

How it works

The Docker Registry is almost a static web server. When the Docker Engine pulls an image, it will download /v2/<imagename>/manifests/<tag>, for instance /v2/busybox/manifests/latest. This is a JSON file that contains references to a number of blobs. One of these blobs will be a JSON file containing the configuration of the image (entry point, command, volumes, etc.) and the other ones will be the layers of the images. The blobs are stored in /v2/<imagename>/blobs/sha256:<sha-of-the-blob>.

There is one tiny twist: when serving the image manifest, the Content-Type HTTP header should be application/vnd.docker.distribution.manifest.v2+json. Otherwise, the Docker Engine will interpret the manifest as a different format, will fail to verify its signature, and will give you the error missing signature key.

Docker-Content-Digest

A while ago (at some point in 2018, maybe?) I tried to implement this but didn't succeed. I don't know exactly what happened, but I had the impression that the Docker-Content-Digest header was mandatory. So when I tried again in August 2020, the first thing I did was to generate Docker-Content-Digest headers for both manifests and blobs. This is the job of the scripts generate-netlify-headers.sh and generate-nginx-config.sh. It looks like this is, in fact, not necessary. I've kept these scripts here just in case. (I tried to pull from registrish, without Docker-Content-Digest headers, using an old version of the Docker Engine - 18.03 - and it worked anyway, so I don't know what I got wrong back then?)

It might be the case that when using an older version of the manifest format, that header becomes mandatory.

Pull manifests by SHA

When pulling an image with the Docker Engine, it will simply get the manifest at /v2/<repository>/manifests/<tag>.

However, when pulling an image with containerd, it looks like it will get that manifest, compute its SHA256, then fetch it again at /v2/<repository>/manifests/sha256:<sha>.

To ensure that this works correctly, there is a script link-manifests-by-sha.sh to copy each manifest to its sha256:<sha> counterpart.

Note 1: perhaps having the correct HTTP headers would prevent this, I don't know.

Note 2: the problem appears only when using "pure" containerd, not when using containerd with Docker. It looks like Docker has its own logic to pull images, and doesn't rely on containerd for that, since the images pulled by Docker don't show up in ctr --namespace=moby images list, for instance. (At least, not on my Linux machine.)

Notes

As mentioned above, this probably doesn't work with multiarch images. It may or may not be easy to adapt.

Netlify is very fast to serve web pages, but not so much to serve binary blobs. (I suspect that they throttle them on purpose to prevent abuse, but that's just an intuition.)

Their terms of service state the following (in August 2020):

Users must exercise caution when hosting large downloads (>10MB). Netlify reserves the right to refuse to host any large downloadable files.

Providers and object stores that might not work

I've tried to use OVHcloud object storage, but it doesn't seem to be easy to do so. OVHcloud storage buckets have very long URLs like https://storage.gra.cloud.ovh.net/v1/AUTH_xxx-long-tenant-id-xxx/bucketname and the Docker registry protocol doesn't support uppercase characters in image names.

It's possible to use custom domain names, but then there are certificate issues. If you know an easy way to make it work, let me know!

Similar work and prior art

Note that the project description data, including the texts, logos, images, and/or trademarks, for each open source project belongs to its rightful owner. If you wish to add or remove any projects, please contact us at [email protected].