We mirror upstream container images to GHCR so our CI does not depend on Docker Hub, quay.io, mcr.microsoft.com, or other registries at test time. This avoids rate limits and temporary upstream outages, and it also helps fork-based PRs because they can pull the mirrored images without needing upstream credentials.
Most mirror packages should be public today. The reason some old mirrored images are still private is historical: older workflow code had bugs and, in some cases, packages were created as private even though they should have been public. This is a one-time cleanup or migration task. Once the legacy private packages are either deleted or switched to public, current workflows should no longer recreate that problem because they publish via GITHUB_TOKEN.
Recommended option: use the cleanup workflow
Run the GitHub Actions workflow:
🧹 Images: Cleanup GHCR (Private)
Suggested steps:
- Open the repository’s Actions tab.
- Select
🧹 Images: Cleanup GHCR (Private). - Click Run workflow.
- Keep
visibility=private. - Keep
dry_run=truefor the first run. - Leave
ghcr_namespaceempty unless you want to target a different owner or organization. - Leave
ghcr_prefix=mirrorunless you want to narrow the cleanup scope. - Provide a cleanup token in the
tokenfield. - Review the dry-run output.
- Run it again with
dry_run=falseto actually delete the legacy private mirror packages.
For this repository, the workflow resolves the effective package prefix as:
<repository>/mirror
So in practice it targets packages such as:
infinito-nexus-core/mirror/...
What token is needed?
For normal mirroring, no extra secret is needed. secrets.GITHUB_TOKEN is enough.
For deleting packages, you need a classic GitHub Personal Access Token with:
delete:packages
That is the important permission for removing old private GHCR packages.
The current workflow accepts that token directly via the token input.
Alternative: manually change package visibility
If there are only a few affected packages, you can also fix them manually in GitHub:
- Open the user or organization Packages page.
- Open the affected container package.
- Click Package settings.
- Under Danger Zone, click Change visibility.
- Change the package from Private to Public.
This is useful if you want to keep the package instead of deleting it.
Important: once a package is made public, GitHub does not allow changing it back to private.
Which option should I use?
- Use the cleanup workflow if you want to remove stale legacy private mirror packages in bulk.
- Use manual visibility changes if you want to keep a small number of existing packages and simply correct their visibility.
Again, this should only be necessary once. These private mirror packages are legacy artifacts from older buggy behavior, not something that should continue to happen with the current workflow setup.