homelab/documentation/SOPs/SOP-003-Gitea-Actions-Runner-Setup.md
Nathan 92b7ffce74
Some checks failed
Auto-Deploy Changed Stacks / deploy (push) Failing after 4s
feat: update auto-deploy workflow to use Komodo API and remove webhook dependency
2026-06-02 12:23:21 -04:00

5.7 KiB

SOP-003: Gitea Actions Runner Setup (Heimdall)

Status: Active
Created: June 2, 2026
Last Updated: June 2, 2026
Owner: Nathan Castaldi
Applies To: Gitea Actions auto-deploy workflow


Purpose

Install and register a Gitea Actions runner on Heimdall so that the .gitea/workflows/auto-deploy.yml workflow can execute when PRs are merged to main. The runner calls the Komodo REST API to redeploy any stack whose folder changed in the push — no per-stack webhook URLs required.


Prerequisites

  • SSH access to Heimdall (10.0.0.151)
  • Docker and Docker Compose running on Heimdall
  • Gitea instance accessible at https://git.castaldifamily.com
  • Admin or repo-owner access to the nathan/homelab Gitea repository
  • Komodo service user created with Stack → Execute permissions (see Step 4)
  • API key + secret copied and ready to add as Gitea secrets

Step 1 — Retrieve a Runner Registration Token

  1. In Gitea, go to Repositorynathan/homelabSettingsActionsRunners
  2. Click Create new Runner
  3. Copy the registration token — you will need it in Step 3

Note: Tokens are single-use. If you lose it, generate a new one.


Step 2 — Create the Runner Compose File on Heimdall

SSH into Heimdall and create the runner stack directory:

mkdir -p /opt/gitea-runner

Create /opt/gitea-runner/compose.yaml:

name: gitea-runner

services:
  runner:
    image: gitea/act_runner:latest
    container_name: gitea-runner
    restart: unless-stopped
    environment:
      GITEA_INSTANCE_URL: "https://git.castaldifamily.com"
      GITEA_RUNNER_REGISTRATION_TOKEN: "${GITEA_RUNNER_REGISTRATION_TOKEN}"
      GITEA_RUNNER_NAME: "heimdall-runner"
      GITEA_RUNNER_LABELS: "ubuntu-latest:docker://node:20-bullseye-slim"
    volumes:
      - /var/run/docker.sock:/var/run/docker.sock
      - runner-data:/data

volumes:
  runner-data:

Create /opt/gitea-runner/.env:

GITEA_RUNNER_REGISTRATION_TOKEN=<paste token from Step 1>

Security: The .env file contains a credential. Do not commit it to Git. The token is consumed on first registration; after that the runner stores its own credentials in the runner-data volume.


Step 3 — Start the Runner

cd /opt/gitea-runner
docker compose up -d

Watch the startup logs to confirm registration:

docker compose logs -f runner

Expected output (within ~10 seconds):

INFO Registering runner ... runner=heimdall-runner
INFO Runner registered successfully.
INFO Starting runner ... name=heimdall-runner

Verify the runner appears in Gitea:

  • Go to RepositorySettingsActionsRunners
  • heimdall-runner should show Online

Step 4 — Create Komodo Service User and API Key

The workflow authenticates to Komodo using a dedicated service user with minimal permissions. Do not use your personal admin account.

4a — Create the service user

  1. Log into Komodo UI (https://komodo.castaldifamily.com)
  2. Go to SettingsUsersNew User
  3. Set type to Service
  4. Name it something like gitea-ci
  5. Grant Execute permission on Stacks only — no write or delete access
  6. Save the user

4b — Generate an API key

  1. Open the gitea-ci user → Api KeysNew Api Key
  2. Copy both the key and the secret immediately — the secret is not shown again

4c — Add secrets to Gitea

In Gitea: RepositorySettingsSecrets and VariablesActionsNew secret

Add all three:

Secret name Value
KOMODO_URL https://komodo.castaldifamily.com
KOMODO_API_KEY API key from step 4b
KOMODO_API_SECRET API secret from step 4b

Security: Never commit these values to the repo. The workflow reads them from Gitea secrets at runtime.


Step 5 — Verify End-to-End

  1. Make a trivial change to any stack folder (e.g., add a blank line to nodes/heimdall/sonarr/compose.yaml)

  2. Commit and push directly to main (or merge a PR)

  3. In Gitea, go to RepositoryActions — the Auto-Deploy Changed Stacks run should appear

  4. Click the run → expand the Detect changed stacks and trigger Komodo webhooks step

  5. Confirm output resembles:

    === Changed files ===
    nodes/heimdall/sonarr/compose.yaml
    
      Queued for deploy: sonarr  (node: heimdall)
    
    === Triggering Komodo deployments ===
      → sonarr ... HTTP 200 OK
    
    All deployments triggered successfully.
    
  6. In Komodo UI, verify the sonarr stack shows a recent deployment event


Troubleshooting

Symptom Check
Runner shows Offline in Gitea docker compose logs runner on Heimdall; check GITEA_INSTANCE_URL reachability
Job never picks up Runner label must match runs-on in the workflow (ubuntu-latest)
HTTP 401 / 403 on DeployStack call Check KOMODO_API_KEY / KOMODO_API_SECRET secrets are set correctly in Gitea
HTTP 404 on DeployStack call Stack name in repo folder does not match the name registered in Komodo UI
HTTP 404 logged as WARNING, not failure Expected — stack exists in repo but isn't registered in Komodo yet
Job shows HEAD~1 diff error Ensure fetch-depth: 2 is set in the checkout step

Rollback

To stop the runner without removing its registration:

cd /opt/gitea-runner && docker compose stop runner

To fully deregister and remove:

cd /opt/gitea-runner && docker compose down -v

Then delete the runner from Gitea → Repository → Settings → Actions → Runners.