towerops/.forgejo
Graham McIntire 31cbd18128 ci: cache slow runtime apt deps in a prebuilt base image
Splits the runtime apt installs (gdal-bin, snmp, libsnmp40, locales,
BEAM runtime libs) into k8s/Dockerfile.base, hosted at
codeberg.org/gmcintire/towerops-base:latest. The app Dockerfile now
does FROM that base instead of re-installing gdal (~500 MB) on every
push.

The new build-base workflow rebuilds the base image only when
k8s/Dockerfile.base or the workflow itself changes, weekly via cron
(Sundays 06:00 UTC, with CACHE_BUST=<ISO week> to force apt-get update
on a week boundary), or via workflow_dispatch.

Production workflow now uses buildx + does docker login before the
build so it can pull the private base image.
2026-05-05 11:19:49 -05:00
..
workflows ci: cache slow runtime apt deps in a prebuilt base image 2026-05-05 11:19:49 -05:00
README.md change runner for forgejo 2026-02-03 14:06:24 -06:00

Forgejo Actions Configuration

This directory contains Forgejo Actions workflows (GitHub Actions-compatible) for CI/CD.

Migration from GitLab CI

The .forgejo/workflows/build-deploy.yml file replaces .gitlab-ci.yml with equivalent functionality:

Key Differences

GitLab CI Forgejo Actions
stages: jobs: (jobs run in dependency order)
tags: [home] runs-on: ubuntu-latest
rules: on: (trigger conditions)
$CI_COMMIT_SHA ${{ github.sha }}
$CI_REGISTRY_IMAGE ${{ secrets.REGISTRY_URL }}/${{ github.repository }}
workflow.auto_cancel concurrency.cancel-in-progress
Docker-in-Docker service docker/build-push-action@v5

Required Secrets

Configure these in your Forgejo repository settings (Settings → Secrets):

  1. REGISTRY_URL - Container registry URL (e.g., registry.gitlab.com)
  2. REGISTRY_USER - Container registry username
  3. REGISTRY_PASSWORD - Container registry password/token

Required Runner Setup

The workflow uses ubuntu-latest as the target label, which should match most Linux-based runners.

To check your runner's labels:

  1. Go to your Forgejo repository → Settings → Actions → Runners
  2. Look for the "Labels" column for your registered runner
  3. If you see ubuntu-latest or ubuntu-22.04, the workflow should work

To register a runner with specific labels:

# Register with custom labels
./act_runner register --labels ubuntu-latest,custom-label

# Or edit the runner config after registration
# Edit .runner file or config.yaml and add labels

The runner must have:

  1. Docker - For building images
  2. kubectl - Pre-configured with cluster access
    • Context: towerops/towerops:home-cluster-agent must exist
    • Namespace: towerops with deployment named towerops

Workflow Stages

1. Build

  • Triggers on push to main branch
  • Checks out code
  • Logs into container registry
  • Builds Docker image using k8s/Dockerfile
  • Uses layer caching from :latest tag for faster builds
  • Pushes two tags:
    • <registry>/<repo>:<commit-sha> - Specific version
    • <registry>/<repo>:latest - Latest build

2. Deploy

  • Depends on successful build
  • Uses kubectl to update Kubernetes deployment
  • Sets image to the newly built commit SHA
  • Adds DEPLOY_TIMESTAMP environment variable
  • Lets Kubernetes handle rollout asynchronously

Testing the Workflow

To test without deploying:

# Validate workflow syntax
act --list -W .forgejo/workflows/build-deploy.yml

# Run build job locally (if act is installed)
act push -W .forgejo/workflows/build-deploy.yml -j build

Comparison to GitLab CI

Advantages:

  • Uses official Docker actions (more reliable layer caching)
  • Better concurrency control (auto-cancels old runs)
  • Clearer job dependencies with needs:

Equivalent Features:

  • Same Docker build process with BUILDKIT and caching
  • Same kubectl deployment commands
  • Same environment protection (production)
  • Same branch filtering (main only)

Troubleshooting

Build fails with registry authentication:

  • Verify REGISTRY_USER and REGISTRY_PASSWORD secrets are set
  • Check runner has network access to registry

Deploy fails with kubectl errors:

  • Verify runner has kubectl installed: kubectl version --client
  • Check kubeconfig context exists: kubectl config get-contexts
  • Verify cluster access: kubectl get deployments -n towerops

Runner not picking up jobs:

  • Check runner labels: Repository → Settings → Actions → Runners
  • Verify runner has ubuntu-latest label (or update workflow to match your runner's labels)
  • Check runner logs: journalctl -u act_runner -f or check runner process output
  • Ensure runner is online and connected (green status in UI)
  • If runner has different labels, update runs-on: in workflow to match