Serverless Container Registry Proxy
This project offers a very simple reverse proxy that lets you expose your public
or private Docker registries (such as Google Container
Registry gcr.io
, Google
Artifact Registry (*.pkg.dev
) or
Docker Hub account) as a public registry on your own domain name.
You can also fork this project and customize as a middleware and deploy to
Cloud Run or somewhere else since it’s a generic docker registry proxy.
![Run on Google Cloud](https://storage.googleapis.com/cloudrun/button.png)
For example, if you have a public registry, and offering images publicly with
names such as:
docker pull gcr.io/ahmetb-public/foo
# or
docker pull us-central1-docker.pkg.dev/ahmetb-demo/ahmetb-demo/foo
you can use this proxy, and instead offer your images in a ✨fancier way✨ on a
custom domain, such as:
docker pull r.ahmet.dev/foo
This project is a stateless reverse proxy, and can be deployed to a managed
compute platform such as Cloud Run. It works by reverse proxying the
Docker Registry API v2 requests
to the underlying registry:
![architecture diagram](./docs/img/diagram.svg)
It does not support "pushing"; however, as you push images to the underlying
registry, you can serve them on your custom domain.
You are also free to fork this project and use it as a "customizable middleware"
in front of your container image registry.
Building
Download the source code, and build as a container image:
docker build --tag gcr.io/[YOUR_PROJECT]/gcr-proxy .
Then, push to a registry like:
docker push gcr.io/[YOUR_PROJECT]/gcr-proxy
Deploying (to Google Cloud Run) for Google Container Registry (gcr.io
)
You can easily deploy this as a serverless container to Google Cloud Run.
This handles many of the heavy-lifting for you.
- Build and push docker images (previous step)
- Deploy to Cloud Run.
- Configure custom domain for Cloud Run service.
- Create domain mapping
- Verify domain ownership
- Update your DNS records
- Have fun!
To deploy this to Cloud Run, replace [GCP_PROJECT_ID]
with the project
ID of the GCR registry you want to expose publicly:
gcloud run deploy gcr-proxy \
--allow-unauthenticated \
--image "[IMAGE]" \
--set-env-vars "REGISTRY_HOST=gcr.io" \
--set-env-vars "REPO_PREFIX=[GCP_PROJECT_ID]"
This will deploy a publicly accessible registry for your
gcr.io/[GCP_PROJECT_ID]
, which also needs to be
public.
If your GCR registry is private, see the section below on "Exposing private
registries".
Then create a domain mapping by running (replace the --domain
value):
gcloud run domain-mappings create \
--service gcr-proxy \
--domain [YOUR_DOMAIN]
This command will require verifying ownership of your domain name, and have you
set DNS records for your domain to point to Cloud Run. Then, it will take
some 15-20 minutes to actually provision TLS certificates for your domain name.
Pricing Note: Cloud Run has a generous free tier. When serving from GCR using
this proxy, the layer blobs will not be served through this proxy (as they're
downloaded from a signed GCS URL). This saves you a lot of "billable time" and
"egress networking" costs.
Deploying (to Google Cloud Run) for Google Artifact Registry (*.pkg.dev
)
Same instructions as GCR listed above. You need to just configure these
environment variables differently:
REGISTRY_HOST
: your regional AR domain (e.g. us-central1-docker.pkg.dev
)
REPO_PREFIX
: project ID + AR Repository name (e.g.
ahmetb-demo/prod-images
)
Warning: When using Artifact Registry, the layer blobs are downloaded
through this proxy, and therefore will incur more
costs on Cloud Run such as networking
egress and longer execution times leading to higher "billable time".
Deploying (elsewhere)
...is much harder. You need to deploy the application to an environment like
Kubernetes, obtain a valid TLS certificate for your domain name, and make it
publicly accessible.
Using with other Docker Registries
If you set REGISTRY_HOST
and REGISTRY_PREFIX
environment variables, you can
also use this proxy for other docker registries.
For example, to proxy docker pull ahmet/example
to Docker Hub, specify
environment variables:
REGISTRY_HOST=index.docker.io
REPO_PREFIX=ahmet
Note: This is not tested with registries other than Docker Hub and GCR/AR.
If you can make it work with Azure Container Registry or AWS Elastic Container
Registry, contribute examples here.
Exposing private registries publicly (GCR.io)
⚠️ This will make images in your private GCR registries publicly accessible on
the internet.
-
Create an IAM Service
Account.
-
Give it
permissions
to access the GCR registry GCS Bucket. (Or simply, you can give it the
project-wide Storage Object Viewer
role.)
-
Copy your service account JSON key into the root of the repository as
key.json
.
-
(Not ideal, but whatever) Rebuild the docker image with your service account
key JSON in it. This will require editing Dockerfile
to add COPY
and
ENV
directives like:
COPY key.json /app/key.json
ENV GOOGLE_APPLICATION_CREDENTIALS /app/key.json
ENTRYPOINT [...]
You need to rebuild and deploy the updated image.
Configuration
While deploying, you can set additional environment variables for customization:
Key |
Value |
REGISTRY_HOST |
specify hostname for target registry, e.g. gcr.io . |
DISABLE_BROWSER_REDIRECTS |
if you set this variable to any value, visiting example.com/image on this browser will not redirect to [REGISTRY_HOST]/[REPO_PREFIX]/image to allow your users to browse the image on GCR. If you're exposing private registries, you might want to set this variable. |
AUTH_HEADER |
The Authentication: [...] header’s value to authenticate to the target registry |
GOOGLE_APPLICATION_CREDENTIALS |
(For gcr.io ) Path to the IAM service account JSON key file to expose the private GCR registries publicly. |
This is not an official Google project. See LICENSE.