DockerHub Mirror on Github powered by Github Actions and Crane
GitHub Actions scheduled to run daily at Midnight UTC to mirror Docker images to GHCR.io, bypassing Docker Hub rate limits.
Docker Hub enforces rate limits on image pulls:
- Anonymous users: 100 pulls per 6 hours
- Authenticated users: 200 pulls per 6 hours
For homelabs, CI/CD pipelines, or frequent container deployments, these limits can be restrictive. This project automatically mirrors commonly used images to GitHub Container Registry (GHCR.io), which has more generous rate limits.
- Daily Schedule: GitHub Actions runs at midnight UTC (can also be triggered manually)
- Smart Mirroring: Uses Crane to compare image digests - only copies when images have changed
- Efficient: Parallel processing with matrix strategy mirrors all images simultaneously
- Zero Maintenance: Add new images by simply creating a text file with tags
This repository mirrors 43 Docker images including:
- Base Images: alpine, debian, golang, node, nginx, python, rust
- Databases: postgres, mysql, mariadb, redis, elasticsearch, influxdb
- Applications: grafana, n8n, node-red, vaultwarden, vikunja, uptime-kuma
- Tools: haproxy, telegraf, chronograf, traefik-forward-auth
- And many more...
See the images/ directory for the complete list.
Instead of pulling from Docker Hub:
docker pull nginx:latestPull from GHCR.io:
docker pull ghcr.io/psarossy/nginx:latestservices:
web:
image: ghcr.io/psarossy/nginx:latest
ports:
- "80:80"apiVersion: v1
kind: Pod
metadata:
name: nginx
spec:
containers:
- name: nginx
image: ghcr.io/psarossy/nginx:latestWant to add a new image to the mirror? It's simple:
Create a file in images/ with the image name and list tags:
cat > images/redis << EOF
latest
7.2
alpine
EOFCreate a directory structure matching the image name:
mkdir -p images/hashicorp
cat > images/hashicorp/terraform << EOF
latest
1.7.0
EOFThen submit a pull request or open an issue.
Use the helper script to discover available tags for an image:
./scripts/list-tags.sh nginx
./scripts/list-tags.sh grafana/grafana 50Before committing, validate your changes:
./scripts/validate-local.shThis checks for:
- Trailing whitespace
- Missing final newlines
- Duplicate tags
- Empty files
- Invalid filenames
The mirroring process is optimized for efficiency:
- Matrix Generation: Scans
images/directory to build a list of all images - Parallel Processing: Each image/tag combination is processed simultaneously
- Digest Comparison: For each tag:
- Fetches source image digest from Docker Hub
- Fetches destination digest from GHCR.io (if exists)
- Only copies if digests differ or destination doesn't exist
- Smart Copying: Crane uses cross-repository blob mounting for fast transfers
This means:
- Bandwidth efficient: Only changed images are transferred
- Time efficient: Unchanged images are skipped in seconds
- Cost effective: Minimal GitHub Actions minutes used
dockerhub-mirror/
├── .github/
│ ├── workflows/
│ │ ├── mirror.yml # Main mirroring workflow
│ │ └── validate.yml # PR validation checks
│ ├── ISSUE_TEMPLATE/ # Issue templates
│ └── pull_request_template.md
├── images/ # Image tag definitions
│ ├── nginx # Official images (single file)
│ └── grafana/ # Namespaced images (directories)
│ └── grafana
├── scripts/ # Helper scripts
│ ├── list-tags.sh # List available tags
│ └── validate-local.sh # Local validation
├── CLAUDE.md # AI assistant guide
└── README.md # This file
Contributions are welcome! Please:
- Fork the repository
- Create a feature branch
- Add/update image files following conventions
- Run
./scripts/validate-local.shto check your changes - Submit a pull request
See CLAUDE.md for detailed development guidelines.
The mirroring workflow requires:
- GHCR_PAT: GitHub Personal Access Token with
write:packagespermission - DOCKERHUB_RO (optional): Docker Hub credentials for authenticated pulls (higher rate limits)
These are configured as repository secrets.
This project is released into the public domain under The Unlicense. Use it freely for any purpose.
- Crane - The efficient container image tool that powers this project
- All the open source projects whose images we mirror
- View workflow runs: GitHub Actions
- Check mirrored images: GHCR.io Packages