picpeak/ml has an empty Hub overview and picpeak/aio has none at all,
while backend and frontend carry hand-written ones — so the two newest
images are the two with nothing on their registry page.
Adds .github/dockerhub/{aio,ml}.md as the source of those pages and a
dockerhub-descriptions job that pushes them on every main merge, so the
page cannot drift from the release it describes. backend/frontend stay
hand-maintained for now: capturing their current Hub text into files is
a prerequisite, not a side effect of this change.
README gains a registry table for all four images (both registries share
digests and tags), the org-move callout lists the full set, and the
feature list finally mentions People in this gallery, which shipped in
#1074 without a README line.
7.0 KiB
Docker Build and Push Workflow
This GitHub Actions workflow automatically builds and pushes Docker images for the backend, the frontend, the all-in-one image and the optional ML sidecar to GitHub Container Registry (ghcr.io). On the canonical org repo every one of them is mirrored to Docker Hub as docker.io/picpeak/{backend,frontend,aio,ml}; forks build the same images GHCR-only.
The all-in-one image (<repo>/aio, built from Dockerfile.aio at the repo root, #1042) bundles the backend and the built frontend into a single container with SQLite as the default engine — one docker run, no compose. It follows the same per-arch build → digest-merge → per-version tag scheme as the other two images, is mirrored to Docker Hub (docker.io/picpeak/aio) alongside GHCR on the canonical org repo, and every PR additionally runs a smoke-aio job that boots the image and asserts the SPA shell, brand-title rendering, immutable asset caching, and the SQLite engine resolution.
Features
- 🔧 Automatic builds on push to main/develop branches, PRs, and releases
- 🏗️ Multi-architecture support (linux/amd64 and linux/arm64)
- 🏷️ Smart tagging based on branches, versions, and commits
- 🔒 Security scanning with Trivy vulnerability scanner
- 💾 Build caching for faster subsequent builds
- 📊 Build summaries in GitHub Actions UI
- 📝 Docker Hub pages for
aioandmlsynced from.github/dockerhub/*.mdon everymainmerge (dockerhub-descriptionsjob).backendandfrontendpages are still hand-maintained in the Hub UI — add.github/dockerhub/{backend,frontend}.mdwith their current text before putting them under the same job.
Authentication
The workflow uses the built-in GITHUB_TOKEN for authentication with GitHub Container Registry. No additional setup or personal access tokens are required.
Required Permissions
The workflow automatically sets the necessary permissions:
contents: read- To checkout the repositorypackages: write- To push images to ghcr.iosecurity-events: write- To upload security scan results
Image Tags
Images are automatically tagged based on the trigger event:
| Event | Tags Generated |
|---|---|
| Push to main | latest, main, main-<short-sha> |
| Push to develop | develop, develop-<short-sha> |
| Pull Request | pr-<number> |
| Release (v1.2.3) | 1.2.3, 1.2, 1, latest |
| Manual trigger | Based on branch + optional push |
Usage
Pull Images
Once published, images can be pulled using:
# Pull backend image
docker pull ghcr.io/picpeak/picpeak/backend:latest
# Pull frontend image
docker pull ghcr.io/picpeak/picpeak/frontend:latest
# Pull specific version
docker pull ghcr.io/picpeak/picpeak/backend:v1.0.0
# Pull for specific architecture
docker pull --platform linux/arm64 ghcr.io/picpeak/picpeak/backend:latest
# The same images on Docker Hub (identical tags, identical digests)
docker pull picpeak/backend:latest
docker pull picpeak/aio:stable
docker pull picpeak/ml:stable
Using in Docker Compose
version: '3.8'
services:
backend:
image: ghcr.io/picpeak/picpeak/backend:latest
environment:
- NODE_ENV=production
ports:
- "3001:3000"
frontend:
image: ghcr.io/picpeak/picpeak/frontend:latest
ports:
- "80:80"
Using in Kubernetes
apiVersion: apps/v1
kind: Deployment
metadata:
name: picpeak-backend
spec:
replicas: 3
template:
spec:
containers:
- name: backend
image: ghcr.io/picpeak/picpeak/backend:latest
imagePullPolicy: Always
Manual Workflow Trigger
You can manually trigger the workflow from the Actions tab:
- Go to Actions → "Build and Push Docker Images"
- Click "Run workflow"
- Select branch and whether to push images
- Click "Run workflow"
Security Scanning
The workflow includes Trivy vulnerability scanning that:
- Scans for CRITICAL and HIGH severity vulnerabilities
- Uploads results to GitHub Security tab
- Available under Security → Code scanning alerts
Build Optimization
The workflow uses several optimization techniques:
- GitHub Actions Cache: Speeds up builds by caching layers
- Multi-stage builds: Reduces final image size
- Parallel builds: Backend and frontend build simultaneously
- Smart rebuilds: Only rebuilds changed components
Troubleshooting
Permission Denied Errors
If you encounter permission errors when pushing images:
-
First-time setup: The first push creates a private package. You may need to:
- Go to your package settings at
https://github.com/users/YOUR_USERNAME/packages - Link the package to your repository
- Set package visibility (public/private)
- Go to your package settings at
-
Organization repositories: Ensure the organization allows GitHub Actions to create packages
Build Failures
Check the workflow logs in the Actions tab for detailed error messages. Common issues:
- Missing dependencies in package.json
- Dockerfile syntax errors
- Network issues during package installation
Image Not Found
If images aren't visible after successful push:
- Check package visibility settings
- Ensure you're authenticated to pull private images:
echo $GITHUB_TOKEN | docker login ghcr.io -u YOUR_USERNAME --password-stdin
Package Management
View Packages
Your Docker images are available at:
- Backend:
https://github.com/orgs/PicPeak/packages/container/package/picpeak%2Fbackend - Frontend:
https://github.com/orgs/PicPeak/packages/container/package/picpeak%2Ffrontend
Delete Old Versions
To save storage, you can delete old versions:
- Go to package settings
- Click on "Manage versions"
- Select versions to delete
- Click "Delete selected versions"
Set Retention Policy
Configure automatic cleanup in package settings:
- Go to package settings
- Click on "Manage Actions access"
- Set retention days for untagged versions
Best Practices
- Use semantic versioning for releases (e.g., v1.2.3)
- Test images locally before pushing to production
- Monitor security alerts from Trivy scans
- Clean up old images regularly to save storage
- Use specific tags in production (avoid
latest)
Advanced Configuration
Custom Registry
To use a different registry, update the workflow:
env:
REGISTRY: docker.io # or your custom registry
BACKEND_IMAGE_NAME: yourusername/picpeak-backend
Additional Platforms
To build for more platforms:
platforms: linux/amd64,linux/arm64,linux/arm/v7
Custom Build Arguments
Add build arguments in the workflow:
build-args: |
NODE_VERSION=20
API_URL=${{ secrets.API_URL }}