# 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 triggers Komodo webhooks for any stack whose folder changed in the push. --- ## 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 webhook URLs retrieved from Komodo UI (see [Step 4](#step-4--add-required-secrets-in-gitea)) --- ## Step 1 — Retrieve a Runner Registration Token 1. In Gitea, go to **Repository** → `nathan/homelab` → **Settings** → **Actions** → **Runners** 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: ```bash mkdir -p /opt/gitea-runner ``` Create `/opt/gitea-runner/compose.yaml`: ```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`: ```env GITEA_RUNNER_REGISTRATION_TOKEN= ``` > **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 ```bash cd /opt/gitea-runner docker compose up -d ``` Watch the startup logs to confirm registration: ```bash 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 **Repository** → **Settings** → **Actions** → **Runners** - `heimdall-runner` should show **Online** --- ## Step 4 — Add Required Secrets in Gitea The auto-deploy workflow does not use a shared secret (Komodo webhook URLs are self-authenticating). No repository secrets are required for the workflow itself. If you later need to store additional credentials (e.g., a Komodo API key for a future workflow), add them at: > **Repository** → **Settings** → **Secrets and Variables** → **Actions** → **New secret** --- ## Step 5 — Fill In Webhook URLs Open `.gitea/workflows/auto-deploy.yml` in the repo and replace each `TODO` value in `WEBHOOK_MAP` with the actual URL from Komodo: 1. Log into Komodo UI (`https://komodo.castaldifamily.com`) 2. Navigate to **Stacks** → select the stack 3. Open the **Webhooks** tab 4. Copy the full webhook URL (token is embedded in the path) 5. Paste it as the map value for that stack name Commit the updated workflow file to `main` (or merge a PR that includes it). > **Never paste webhook URLs into public forks or issue comments.** They are > equivalent to credentials. --- ## Step 6 — 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 **Repository** → **Actions** — 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 webhooks === → sonarr ... HTTP 200 OK All webhooks 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 404` on webhook POST | URL in `WEBHOOK_MAP` is wrong; re-copy from Komodo UI | | `HTTP 401` / `403` on webhook POST | URL token is stale; regenerate webhook in Komodo UI | | Job shows `HEAD~1` diff error | Ensure `fetch-depth: 2` is set in the checkout step | | Stack not in `WEBHOOK_MAP` | Logged as a warning in job output; add the stack name to the map | --- ## Rollback To stop the runner without removing its registration: ```bash cd /opt/gitea-runner && docker compose stop runner ``` To fully deregister and remove: ```bash cd /opt/gitea-runner && docker compose down -v ``` Then delete the runner from **Gitea → Repository → Settings → Actions → Runners**.