Container: - Dockerfile → Containerfile; drop gosu, entrypoint, PUID/PGID user-switching - HOME=/config so Path.home()/.aws resolves to runtime-mounted credentials - docker-compose.yml → compose.yml with userns_mode: keep-id for Podman rootless - .dockerignore → .containerignore - boto3 unpinned from 1.34.0 to >=1.34.0 CI: - Remove Woodpecker (.woodpecker.yml, .woodpecker/) - Add Forgejo Actions (.forgejo/workflows/ci.yml, publish.yml) - CI: syntax check, security scan, container lint (hadolint), build test - Publish: build and push to Quay.io on main push and version tags Cleanup: - Remove entrypoint.sh (no longer needed) - Remove scripts/build-and-push.sh and PUBLISHING.md (superseded by CI) - All docker → podman command references updated Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
8.5 KiB
8.5 KiB
Building and Publishing to Quay.io
This guide covers how to build and publish SGO container images to Quay.io.
Prerequisites
- Quay.io account: Create account at https://quay.io
- Repository created: Create a repository (e.g.,
yourusername/sgo) - Docker or Podman installed: For building and pushing images
Manual Build and Push
Step 1: Login to Quay.io
# Using Docker
docker login quay.io
# Using Podman
podman login quay.io
# You'll be prompted for:
# Username: your_quay_username
# Password: your_quay_password (or robot account token)
Step 2: Build the Image
cd /home/eduardo_figueroa/Dev/sgo
# Build with Docker
docker build -t quay.io/yourusername/sgo:latest .
# Build with Podman
podman build -t quay.io/yourusername/sgo:latest .
Step 3: Tag for Version (Optional)
# Tag with version number
docker tag quay.io/yourusername/sgo:latest quay.io/yourusername/sgo:v1.0.0
# Tag with git commit
docker tag quay.io/yourusername/sgo:latest quay.io/yourusername/sgo:$(git rev-parse --short HEAD)
Step 4: Push to Quay.io
# Push latest tag
docker push quay.io/yourusername/sgo:latest
# Push version tag
docker push quay.io/yourusername/sgo:v1.0.0
# Push all tags
docker push quay.io/yourusername/sgo --all-tags
Using Robot Accounts (Recommended for CI/CD)
Robot accounts provide scoped credentials for automation.
Create Robot Account
- Go to your repository on Quay.io
- Click Settings → Robot Accounts
- Click Create Robot Account
- Name it (e.g.,
sgo_builder) - Grant Write permissions
- Save the credentials (username and token)
Login with Robot Account
# Format: quay.io+username+robotname
docker login quay.io
Username: yourusername+sgo_builder
Password: <robot-token>
Automated Build with Woodpecker CI
Step 1: Add Secrets to Woodpecker
Add these secrets to your Woodpecker CI configuration:
QUAY_USERNAME- Your quay.io username or robot accountQUAY_PASSWORD- Your quay.io password or robot token
Step 2: Create Woodpecker Pipeline
Create .woodpecker/docker-publish.yml:
pipeline:
docker-build-and-push:
image: docker:dind
volumes:
- /var/run/docker.sock:/var/run/docker.sock
environment:
- QUAY_USERNAME
- QUAY_PASSWORD
commands:
# Login to Quay.io
- echo "$QUAY_PASSWORD" | docker login quay.io -u "$QUAY_USERNAME" --password-stdin
# Build image
- docker build -t quay.io/yourusername/sgo:latest .
- docker tag quay.io/yourusername/sgo:latest quay.io/yourusername/sgo:${CI_COMMIT_SHA}
# Push images
- docker push quay.io/yourusername/sgo:latest
- docker push quay.io/yourusername/sgo:${CI_COMMIT_SHA}
when:
branch:
- main
event:
- push
- tag
Step 3: Update Main Woodpecker Config
Add to .woodpecker.yml:
when:
event: [push, pull_request, tag]
pipeline:
dependencies:
image: python:3.11-slim
commands:
- pip install -r requirements.txt
syntax-check:
image: python:3.11-slim
commands:
- python -m py_compile app.py
- python -m py_compile import_from_aws.py
- python -m py_compile import_data.py
docker-build:
image: docker:dind
volumes:
- /var/run/docker.sock:/var/run/docker.sock
commands:
- docker build -t sgo:${CI_COMMIT_SHA} .
security-scan:
image: python:3.11-slim
commands:
- pip install bandit safety
- bandit -r . -ll || true
- safety check --file requirements.txt || true
# Only push on main branch
publish-to-quay:
image: docker:dind
volumes:
- /var/run/docker.sock:/var/run/docker.sock
secrets: [quay_username, quay_password]
commands:
- echo "$QUAY_PASSWORD" | docker login quay.io -u "$QUAY_USERNAME" --password-stdin
- docker build -t quay.io/yourusername/sgo:latest .
- docker tag quay.io/yourusername/sgo:latest quay.io/yourusername/sgo:${CI_COMMIT_SHA}
- docker push quay.io/yourusername/sgo:latest
- docker push quay.io/yourusername/sgo:${CI_COMMIT_SHA}
when:
branch: main
event: push
Multi-Architecture Builds
Build for multiple architectures (amd64, arm64):
Using Docker Buildx
# Create builder
docker buildx create --name multiarch --use
# Build and push multi-arch image
docker buildx build \
--platform linux/amd64,linux/arm64 \
-t quay.io/yourusername/sgo:latest \
--push \
.
Using Podman
# Build for amd64
podman build --platform linux/amd64 -t quay.io/yourusername/sgo:latest-amd64 .
# Build for arm64
podman build --platform linux/arm64 -t quay.io/yourusername/sgo:latest-arm64 .
# Create and push manifest
podman manifest create quay.io/yourusername/sgo:latest
podman manifest add quay.io/yourusername/sgo:latest quay.io/yourusername/sgo:latest-amd64
podman manifest add quay.io/yourusername/sgo:latest quay.io/yourusername/sgo:latest-arm64
podman manifest push quay.io/yourusername/sgo:latest
Tagging Strategy
Recommended Tags
# Latest - always points to newest build
quay.io/yourusername/sgo:latest
# Version tags - for releases
quay.io/yourusername/sgo:v1.0.0
quay.io/yourusername/sgo:v1.0
quay.io/yourusername/sgo:v1
# Git commit SHA - for specific commits
quay.io/yourusername/sgo:abc1234
# Branch name - for development branches
quay.io/yourusername/sgo:dev
quay.io/yourusername/sgo:feature-xyz
Applying Multiple Tags
IMAGE_NAME="quay.io/yourusername/sgo"
VERSION="v1.0.0"
COMMIT=$(git rev-parse --short HEAD)
# Build once
docker build -t ${IMAGE_NAME}:${VERSION} .
# Apply multiple tags
docker tag ${IMAGE_NAME}:${VERSION} ${IMAGE_NAME}:latest
docker tag ${IMAGE_NAME}:${VERSION} ${IMAGE_NAME}:${COMMIT}
# Push all tags
docker push ${IMAGE_NAME}:${VERSION}
docker push ${IMAGE_NAME}:latest
docker push ${IMAGE_NAME}:${COMMIT}
Verifying the Published Image
Pull and Test
# Pull the image
docker pull quay.io/yourusername/sgo:latest
# Test it works
docker run --rm \
-e AWS_CONFIG_PATH=/tmp/aws-host \
-e PUID=1000 \
-e PGID=1000 \
-v $HOME/.aws:/tmp/aws-host:ro \
-v sgo-data:/app/data \
-p 5000:5000 \
quay.io/yourusername/sgo:latest
Check Image Details
# Inspect image
docker inspect quay.io/yourusername/sgo:latest
# Check image size
docker images quay.io/yourusername/sgo
# View image history
docker history quay.io/yourusername/sgo:latest
Making Repository Public
By default, Quay.io repositories are private.
To make public:
- Go to repository on Quay.io
- Click Settings
- Change Repository Visibility to Public
- Click Save
Updating docker-compose.yml for Quay.io
Users can pull from Quay.io by updating their docker-compose.yml:
services:
sgo:
image: quay.io/yourusername/sgo:latest
# rest of configuration...
Or pull specific version:
services:
sgo:
image: quay.io/yourusername/sgo:v1.0.0
# rest of configuration...
Troubleshooting
Authentication Failed
# Clear old credentials
rm ~/.docker/config.json
# Login again
docker login quay.io
Push Denied
- Verify repository exists on Quay.io
- Check robot account has Write permissions
- Ensure you're logged in to correct account
Build Fails
# Check Dockerfile syntax
docker build --no-cache -t test .
# View build logs
docker build -t test . 2>&1 | tee build.log
Image Too Large
# Check image size
docker images quay.io/yourusername/sgo
# Use .dockerignore to exclude files
# Already configured in project
# Use multi-stage builds (if applicable)
# Current Dockerfile is already optimized
Complete Build Script
Create scripts/build-and-push.sh:
#!/bin/bash
set -e
# Configuration
REGISTRY="quay.io"
USERNAME="yourusername"
REPO="sgo"
IMAGE="${REGISTRY}/${USERNAME}/${REPO}"
# Get version from git tag or use dev
VERSION=$(git describe --tags --abbrev=0 2>/dev/null || echo "dev")
COMMIT=$(git rev-parse --short HEAD)
echo "Building ${IMAGE}:${VERSION}"
# Build image
docker build -t ${IMAGE}:${VERSION} .
# Tag with multiple tags
docker tag ${IMAGE}:${VERSION} ${IMAGE}:latest
docker tag ${IMAGE}:${VERSION} ${IMAGE}:${COMMIT}
echo "Pushing to ${REGISTRY}"
# Push all tags
docker push ${IMAGE}:${VERSION}
docker push ${IMAGE}:latest
docker push ${IMAGE}:${COMMIT}
echo "Successfully pushed:"
echo " - ${IMAGE}:${VERSION}"
echo " - ${IMAGE}:latest"
echo " - ${IMAGE}:${COMMIT}"
Make it executable:
chmod +x scripts/build-and-push.sh
Run it:
./scripts/build-and-push.sh