SGO/wiki/Building-and-Publishing.md
Eduardo Figueroa a6b2cea31f
Some checks failed
CI / syntax-check (push) Has been cancelled
CI / security-scan (push) Has been cancelled
CI / container-lint (push) Has been cancelled
CI / container-build (push) Has been cancelled
Publish / publish (push) Has been cancelled
Migrate to Podman, Forgejo Actions; clean up cruft
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>
2026-03-16 15:41:08 -07:00

406 lines
8.5 KiB
Markdown

# Building and Publishing to Quay.io
This guide covers how to build and publish SGO container images to Quay.io.
## Prerequisites
1. **Quay.io account**: Create account at https://quay.io
2. **Repository created**: Create a repository (e.g., `yourusername/sgo`)
3. **Docker or Podman installed**: For building and pushing images
## Manual Build and Push
### Step 1: Login to Quay.io
```bash
# 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
```bash
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)
```bash
# 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
```bash
# 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
1. Go to your repository on Quay.io
2. Click **Settings****Robot Accounts**
3. Click **Create Robot Account**
4. Name it (e.g., `sgo_builder`)
5. Grant **Write** permissions
6. Save the credentials (username and token)
### Login with Robot Account
```bash
# 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 account
- `QUAY_PASSWORD` - Your quay.io password or robot token
### Step 2: Create Woodpecker Pipeline
Create `.woodpecker/docker-publish.yml`:
```yaml
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`:
```yaml
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
```bash
# 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
```bash
# 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
```bash
# 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
```bash
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
```bash
# 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
```bash
# 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:
1. Go to repository on Quay.io
2. Click **Settings**
3. Change **Repository Visibility** to **Public**
4. Click **Save**
## Updating docker-compose.yml for Quay.io
Users can pull from Quay.io by updating their `docker-compose.yml`:
```yaml
services:
sgo:
image: quay.io/yourusername/sgo:latest
# rest of configuration...
```
Or pull specific version:
```yaml
services:
sgo:
image: quay.io/yourusername/sgo:v1.0.0
# rest of configuration...
```
## Troubleshooting
### Authentication Failed
```bash
# 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
```bash
# Check Dockerfile syntax
docker build --no-cache -t test .
# View build logs
docker build -t test . 2>&1 | tee build.log
```
### Image Too Large
```bash
# 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`:
```bash
#!/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:
```bash
chmod +x scripts/build-and-push.sh
```
Run it:
```bash
./scripts/build-and-push.sh
```