You can run a private Docker registry using Cloudflare R2 as your storage backend, in this tutorial we're going to configure it in a Kubernetes cluster.
First, we need to create a R2 bucket where we'll store the Docker images. We also need an API access key and secret key to access the bucket.
Once we have created the bucket and have both keys, we create a secret.
vi registry-secrets.yaml
apiVersion: v1
kind: Secret
metadata:
name: r2-secret
type: Opaque
data:
ACCESS_KEY_ID: <your access key in base64>
ACCESS_SECRET_KEY: <your secret key in base64>
And we apply the configuration.
kubectl apply -f registry-secrets.yaml
Once we've applied the secrets, we create the Registry deployment.
vi registry-deployment.yaml
Here is an example of the deployment, you should change some values to make it work in your cluster.
apiVersion: apps/v1
kind: Deployment
metadata:
name: r2-registry
spec:
replicas: 1
selector:
matchLabels:
app: r2-registry
template:
metadata:
labels:
app: r2-registry
spec:
restartPolicy: Always
containers:
- name: registry
image: registry:2
env:
- name: REGISTRY_HEALTH_STORAGEDRIVER_ENABLED
value: "false"
- name: REGISTRY_STORAGE_DELETE_ENABLED
value: "true"
- name: REGISTRY_STORAGE
value: s3
- name: REGISTRY_STORAGE_S3_REGION
value: auto
- name: REGISTRY_STORAGE_S3_REGIONENDPOINT
value: https://<account id>.r2.cloudflarestorage.com
- name: REGISTRY_STORAGE_S3_ENCRYPT
value: "false"
- name: REGISTRY_STORAGE_S3_SECURE
value: "true"
- name: REGISTRY_STORAGE_S3_CHUNKSIZE
value: "104857600"
- name: REGISTRY_STORAGE_S3_BUCKET
value: <bucket name>
- name: REGISTRY_STORAGE_S3_ACCESSKEY
valueFrom:
secretKeyRef:
name: r2-secret
key: ACCESS_KEY_ID
- name: REGISTRY_STORAGE_S3_SECRETKEY
valueFrom:
secretKeyRef:
name: r2-secret
key: ACCESS_SECRET_KEY
Once we've modified the deployment file, we apply it.
kubectl apply -f registry-deployment.yaml
To access the registry, we might want to create a service and an ingress resource.
The registry exposes at port 5000, so we create a service to that port.
vi registry-service.yaml
apiVersion: v1
kind: Service
metadata:
name: r2-registry
spec:
type: ClusterIP
ports:
- port: 5000
targetPort: 5000
protocol: TCP
selector:
app: r2-registry
And we apply it.
kubectl apply -f registry-service.yaml
Next, we create an ingress resource so we can access the registry using our own domain or subdomain.
vi registry-ingress.yaml
apiVersion: networking.k8s.io/v1
kind: Ingress
metadata:
name: r2-registry
annotations:
nginx.ingress.kubernetes.io/proxy-body-size: "0"
spec:
rules:
- host: registry.binarycomet.net
http:
paths:
- path: /
pathType: Prefix
backend:
service:
name: r2-registry
port:
number: 5000
And we apply it.
kubectl apply -f registry-ingress.yaml
Now we have a working Docker registry that can be accessed via our own domain or subdomain, but it's not production-ready yet.
You should add authentication so only the users authorized can access the registry.
Also, it might be interesting to create an SSL certificate, so we don't have to register it as an insecure-registries
everywhere we want to use it.