Your lightweight Docker registry sync engine.
SyncerD is a powerful Go tool for synchronizing Docker images from Docker Hub to other container registries (ECR, ACR, GCR, GitHub Container Registry). Automatically monitors for new versions and syncs them on a schedule.
- 🔄 Multi-Registry Support: Sync to AWS ECR, Azure ACR, Google GCR, and GitHub Container Registry
- 🔍 Automatic Version Detection: Monitors Docker Hub for new tags and automatically syncs them
- ⏰ Scheduled Syncs: Built-in cron scheduler (default: every 3 weeks)
- 🚀 GitHub Actions Ready: Use as a GitHub Action for automated syncing
- 🖥️ CLI Tool: Run from terminal for manual or scheduled syncing
- 🔒 Secure: Supports multiple authentication methods for all registries
- 📝 Configurable: YAML-based configuration with environment variable support
git clone https://github.com/clouddrove/syncerd.git
cd syncerd
go build -o syncerd ./main.gogo install github.com/clouddrove/syncerd@latestAdd SyncerD to your workflow:
- uses: clouddrove/syncerd@v1
with:
config: syncerd.yaml
once: "true"Notes:
- SyncerD reads destination registry auth from Docker credentials. In GitHub Actions, run the appropriate login steps (
docker/login-action,aws-actions/amazon-ecr-login,azure/docker-login,gcloud auth configure-docker) before SyncerD.
- Create a configuration file (
syncerd.yaml):
source:
type: dockerhub
registry: docker.io
destinations:
- name: my-ecr
type: ecr
registry: 123456789012.dkr.ecr.us-east-1.amazonaws.com
region: us-east-1
images:
- name: library/nginx
watch_tags: true- Set up authentication (via environment variables or config file):
export SYNCERD_SOURCE_USERNAME=your-dockerhub-username
export SYNCERD_SOURCE_PASSWORD=your-dockerhub-password- Run the sync:
# Run once
./syncerd sync --once
# Run continuously with cron schedule
./syncerd syncSee syncerd.yaml.example for a complete configuration example.
source:
type: dockerhub
registry: docker.io
username: your-username # Optional
password: your-password # Optional
token: your-token # Optional (preferred)destinations:
- name: my-ecr
type: ecr
registry: 123456789012.dkr.ecr.us-east-1.amazonaws.com
region: us-east-1Authentication: SyncerD reads destination credentials from your Docker credential config
(what docker login writes). In GitHub Actions, use aws-actions/amazon-ecr-login (or docker login)
before running SyncerD.
destinations:
- name: my-acr
type: acr
registry: myregistry.azurecr.ioAuthentication: use azure/docker-login (or docker login) so credentials are available to SyncerD.
destinations:
- name: my-gcr
type: gcr
registry: gcr.ioAuthentication: use gcloud auth configure-docker (or docker login) so credentials are available to SyncerD.
destinations:
- name: my-ghcr
type: ghcr
registry: ghcr.ioAuthentication: use docker/login-action to ghcr.io (or docker login) so credentials are available to SyncerD.
images:
- name: library/nginx
tags: [] # Empty = all tags (if watch_tags is true)
watch_tags: true # Monitor for new tags
- name: library/alpine
tags: # Specific tags to sync
- latest
- 3.18
- 3.19
watch_tags: false # Only sync specified tags# Cron format: minute hour day month weekday
schedule: "0 0 */21 * *" # Every 3 weeks at midnight UTC# Persistent state file (tracks which tags were already synced)
state_path: ".syncerd-state.json"slack:
enabled: true
webhook_url: "https://hooks.slack.com/services/XXX/YYY/ZZZ"
channel: "#platform-alerts" # optional
notify_on_new: true
notify_on_error: true
message_format: "compact" # "compact" | "detailed"# false = best-effort per image/tag (default)
# true = stop the whole run on first error
fail_fast: false# Run sync once and exit
syncerd sync --once
# Run continuously with cron schedule (from config)
syncerd sync
# Use custom config file
syncerd sync --config /path/to/config.yamlSee .github/workflows/syncerd.yml for an example workflow.
- name: Run syncerd
env:
SYNCERD_SOURCE_USERNAME: ${{ secrets.DOCKERHUB_USERNAME }}
SYNCERD_SOURCE_PASSWORD: ${{ secrets.DOCKERHUB_PASSWORD }}
run: |
syncerd sync --once- CI:
.github/workflows/ci.ymlrunsgofmt,go test, andgo build. - Go releases:
.github/workflows/release.ymluses GoReleaser when you push av*tag. - Docker image: the same release workflow builds & pushes to
ghcr.io/<org>/syncerd.
All configuration can be overridden via environment variables with the SYNCERD_ prefix:
SYNCERD_SOURCE_USERNAMESYNCERD_SOURCE_PASSWORDSYNCERD_SOURCE_TOKENSYNCERD_SCHEDULESYNCERD_STATE_PATHSYNCERD_SLACK_WEBHOOK_URLSYNCERD_SLACK_CHANNELSYNCERD_SLACK_MESSAGE_FORMATSYNCERD_FAIL_FAST
- Username/Password
- Personal Access Token (recommended)
SyncerD uses authn.DefaultKeychain, meaning it will pick up credentials from:
docker login(writes~/.docker/config.json)- Docker credential helpers (osxkeychain, wincred, pass, etc.)
- GitHub Actions login steps (recommended per registry)
Contributions are welcome! Please feel free to submit a Pull Request.
- Fork the repository
- Create your feature branch (
git checkout -b feature/amazing-feature) - Commit your changes (
git commit -m 'Add some amazing feature') - Push to the branch (
git push origin feature/amazing-feature) - Open a Pull Request
This project is licensed under the MIT License - see the LICENSE file for details.
- Built with go-containerregistry
- Inspired by the need to work around Docker Hub rate limits
For issues, questions, or contributions, please open an issue on GitHub.
