Automatically delete old images in a private Docker registry according to rules in simple YAML. Useful for keeping small Docker registries from consuming too much disk space. Use at your own risk and make sure you can recreate any mission-critical images!
This utility doesn't actually free any disk space until you run Docker's garbage collection, which you should research and run separately. The main caveat is that if you run it while an image is being uploaded, it can corrupt the new image.
If you're running your registry in Kubernetes, here's an example script you could run on a cron job. (You might need substitute appropriate values for the namespace and configuration path.)
#!/bin/bash
pod=$(kubectl get pods -n docker-registry | tail -n 1 | awk '{ print $1 }')
kubectl exec -n docker-registry $pod -- bin/registry garbage-collect /etc/docker/registry/config.yml
You can define a rule for any number of repositories as follows:
registry: registry.example.com
policies:
- repository: my-image
maxTags: 5
preserveChannels: true # optional
The environmental variable CONFIG_PATH
should point to this file on disk.
This setting instructs retention-manager to make sure at least image per "channel" is preserved. In the tag 1.1.0-staging
, the channel name is "staging".
This enables a deployment pattern that works well with Keel for building images on different code branches, for example.
For a drop-in solution, check the
helm/
directory!
A typical use case is a daily cron job. No additional Kubernetes permissions are required, but you do need to pass in your Docker registry credentials.
# create secret with credentials (don't forget to base64-encode)
apiVersion: v1
kind: Secret
metadata:
name: secret-env
data:
REGISTRY_PASSWORD: ...
REGISTRY_USERNAME: ...
---
# create ConfigMap with config yaml
apiVersion: v1
kind: ConfigMap
metadata:
name: retention-manager
data:
config.yaml: |
registry: registry.example.com
policies:
- repository: my-image
maxTags: 5
---
# create CronJob referencing both of the following resources
apiVersion: batch/v1beta1
kind: CronJob
metadata:
name: retention-manager
spec:
# sometime overnight in California
schedule: "0 11 * * *"
jobTemplate:
spec:
template:
spec:
restartPolicy: OnFailure
volumes:
- name: config
configMap:
name: retention-manager
items:
- key: config.yaml
path: config.yaml
containers:
- name: retention-manager
image: jeffstephens/retention-manager:1.1.1
imagePullPolicy: IfNotPresent
env:
- name: CONFIG_PATH
value: /retention-manager/config.yaml
- name: REGISTRY_PASSWORD
valueFrom:
secretKeyRef:
name: secret-env
key: REGISTRY_PASSWORD
- name: REGISTRY_USERNAME
valueFrom:
secretKeyRef:
name: secret-env
key: REGISTRY_USERNAME
volumeMounts:
- name: config
mountPath: /retention-manager
readOnly: true