A step-by-step guide for team members to authenticate with GitHub Container Registry (GHCR) and push Docker images to the organisation namespace.
- Docker Desktop installed and running
- A GitHub account that is a member of
BredaUniversityADSAI - A Dockerfile at the project root
- The project cloned locally
Each team member needs their own PAT. Do not share tokens.
- Go to GitHub -> Settings -> Developer Settings -> Personal Access Tokens -> Tokens (classic)
- Click "Generate new token (classic)"
- Give it a name, e.g.
ghcr-push - Set an expiration date
- Check the
write:packagesscope - Click "Generate token"
- Copy the token immediately — GitHub will not show it again
Create a .env file at the project root:
GITHUB_PAT=your_token_here
GITHUB_USERNAME=bredauniversityadsai
GITHUB_PERSONAL_USERNAME=your_personal_github_usernameAdd .env to .gitignore immediately:
echo ".env" >> .gitignoreNever commit the .env file. Your PAT is a secret.
Bash
source .env
echo $GITHUB_PAT | docker login ghcr.io -u $GITHUB_PERSONAL_USERNAME --password-stdinCMD
for /f "tokens=1,2 delims==" %i in (.env) do set %i=%j
echo %GITHUB_PAT% | docker login ghcr.io -u %GITHUB_PERSONAL_USERNAME% --password-stdin
PowerShell
Get-Content .env | ForEach-Object { $k, $v = $_ -split '=', 2; Set-Item "env:$k" $v }
$env:GITHUB_PAT | docker login ghcr.io -u $env:GITHUB_PERSONAL_USERNAME --password-stdin
Git Bash
source .env
echo $GITHUB_PAT | docker login ghcr.io -u $GITHUB_PERSONAL_USERNAME --password-stdin
You should see Login Succeeded.
Build for all platforms and push to the org namespace in one step:
Bash
source .env
docker buildx create --use
docker buildx build --platform linux/amd64,linux/arm64 \
-t ghcr.io/$GITHUB_USERNAME/thalianacv:latest \
--push .CMD
for /f "tokens=1,2 delims==" %i in (.env) do set %i=%j
echo %GITHUB_PAT% | docker login ghcr.io -u %GITHUB_PERSONAL_USERNAME% --password-stdin
docker buildx create --use
docker buildx build --platform linux/amd64,linux/arm64 -t ghcr.io/%GITHUB_USERNAME%/thalianacv:latest --push .
PowerShell
Get-Content .env | ForEach-Object { $k, $v = $_ -split '=', 2; Set-Item "env:$k" $v }
$env:GITHUB_PAT | docker login ghcr.io -u $env:GITHUB_PERSONAL_USERNAME --password-stdin
docker buildx create --use
docker buildx build --platform linux/amd64,linux/arm64 -t ghcr.io/$env:GITHUB_USERNAME/thalianacv:latest --push .
Git Bash
source .env
echo $GITHUB_PAT | docker login ghcr.io -u $GITHUB_PERSONAL_USERNAME --password-stdin
docker buildx create --use
docker buildx build --platform linux/amd64,linux/arm64 \
-t ghcr.io/$GITHUB_USERNAME/thalianacv:latest \
--push .
Platform coverage:
| Platform | Covers |
|---|---|
linux/amd64 |
Intel/AMD Linux, Windows (Docker Desktop), Intel Macs |
linux/arm64 |
Apple Silicon Macs (M1/M2/M3/M4) |
The --push flag builds and pushes directly to GHCR. No separate push step is needed.
Go to:
https://github.com/orgs/BredaUniversityADSAI/packages
You should see thalianacv listed. Click on it to confirm both linux/amd64 and
linux/arm64 are present.
Packages published to the org namespace are private by default. A lecturer or org Owner needs to make the package public before teammates can pull it without authenticating.
This is a one-time step. If the package is still private, contact your lecturer.
Once the package is public, anyone with Docker Desktop can run it with two commands:
curl -O https://raw.githubusercontent.com/BredaUniversityADSAI/2025-26d-fai2-adsai-group-computervision8/main/docker-compose.yml
docker compose upDocker pulls the image automatically. No Python, Poetry, or repo clone needed.
The project Makefile wraps the build and push steps. From the project root:
make docker-build # build for all platforms and push to GHCR
make release-patch # bump patch version, commit, push to git, build and push container
make release-minor # bump minor version, also publishes to PyPI
make release-major # bump major version, also publishes to PyPICheck all available commands:
make helpThe image was built for a single platform. Rebuild using the docker buildx command
above with both --platform linux/amd64,linux/arm64.
This is an intermittent GHCR issue. Re-run the push command — it resolves on retry.
The docker-push Makefile target requires a locally tagged image. Use docker-build
instead, which builds and pushes directly via buildx.
Your PAT may not have write:packages scope, or it may have expired. Generate a new
token at https://github.com/settings/tokens and update your .env file.