# Gitea Actions Runner Setup — HOALedgerIQ Production Server This guide walks through setting up a self-hosted Gitea Actions runner on the production server so the deployment workflow (`.gitea/workflows/deploy.yml`) can execute automatically. The runner uses **host execution mode** — jobs run directly on the server (not inside Docker containers) so the deploy script has access to Docker, the git repo, and the local filesystem. --- ## Prerequisites - Ubuntu Linux production server - Gitea instance (e.g., `https://git.sensetostyle.com`) - Docker and Docker Compose installed on the server - The HOALedgerIQ repo cloned at `/opt/hoa-ledgeriq` --- ## Step 1: Enable Actions in Gitea Ensure Actions are enabled in your Gitea configuration (`/etc/gitea/app.ini`): ```ini [actions] ENABLED = true ``` Restart Gitea after making changes: ```bash sudo systemctl restart gitea ``` --- ## Step 2: Get a Registration Token 1. Log into your Gitea instance 2. Navigate to **Site Administration** → **Actions** → **Runners** 3. Copy the **Registration Token** > **Tip:** For tighter security, you can get a repo-scoped token instead: > Repo → **Settings** → **Actions** → **Runners** → copy the token shown there. > This limits the runner to only execute workflows from that specific repository. --- ## Step 3: Install the Act Runner Binary ```bash # Download the latest act_runner for x86_64 Linux wget https://dl.gitea.com/act_runner/latest/act_runner-linux-amd64 # Make executable and install to system path chmod +x act_runner-linux-amd64 sudo mv act_runner-linux-amd64 /usr/local/bin/act_runner # Verify installation act_runner --version ``` > For ARM64 servers, use `act_runner-linux-arm64` instead. --- ## Step 4: Generate and Edit the Configuration ```bash sudo mkdir -p /etc/act_runner act_runner generate-config > /tmp/config.yaml ``` Edit `/tmp/config.yaml` and set the **labels to use host execution mode**: ```yaml runner: labels: - "ubuntu-latest:host" - "ubuntu-22.04:host" ``` The `:host` suffix tells the runner to execute jobs directly on the server rather than spinning up Docker containers. This is required because the deploy script needs access to: - The Docker socket (to run `docker compose`) - The git repository at `/opt/hoa-ledgeriq` - The backup scripts and database Move the config into place and lock down permissions: ```bash sudo mv /tmp/config.yaml /etc/act_runner/config.yaml sudo chmod 600 /etc/act_runner/config.yaml ``` --- ## Step 5: Register the Runner ```bash act_runner register \ --no-interactive \ --instance "https://git.sensetostyle.com" \ --token "YOUR_REGISTRATION_TOKEN_HERE" \ --name "hoaledgeriq-prod" \ --labels "ubuntu-latest:host,ubuntu-22.04:host" \ --config /etc/act_runner/config.yaml ``` This creates a `.runner` file in the current directory containing the registration state. > **Interactive alternative:** Run `act_runner register --config /etc/act_runner/config.yaml` and follow the prompts. --- ## Step 6: Set Up as a Systemd Service Create the service file at `/etc/systemd/system/act_runner.service`: ```ini [Unit] Description=Gitea Actions Runner (HOALedgerIQ Prod) Documentation=https://docs.gitea.com/usage/actions/act-runner After=docker.service network-online.target [Service] Type=simple User=root WorkingDirectory=/opt/hoa-ledgeriq ExecStart=/usr/local/bin/act_runner daemon --config /etc/act_runner/config.yaml Restart=always RestartSec=10 StandardOutput=journal StandardError=journal [Install] WantedBy=multi-user.target ``` > **Security note on `User=root`:** The deploy script needs to run `docker compose`, `git reset --hard`, etc. If you have a dedicated deploy user in the `docker` group with write access to `/opt/hoa-ledgeriq`, use that instead. Running as root is the simplest option but grants maximum privileges. Enable and start the service: ```bash sudo systemctl daemon-reload sudo systemctl enable act_runner sudo systemctl start act_runner ``` --- ## Step 7: Verify the Runner Is Online Check the service is running: ```bash sudo systemctl status act_runner ``` View logs: ```bash sudo journalctl -u act_runner -f ``` Then confirm in Gitea: 1. Go to **Site Administration** → **Actions** → **Runners** 2. You should see **"hoaledgeriq-prod"** listed with status **Online** --- ## Step 8: Test the Workflow 1. Go to your repo on Gitea → **Actions** tab 2. Select the **"Deploy to Production"** workflow 3. Click **Run Workflow** 4. If this is the first deployment against an existing database, check the **"Mark existing migrations as applied"** box 5. Monitor the run in the Actions tab --- ## Troubleshooting ### Runner shows as Offline ```bash # Check service status and logs sudo systemctl status act_runner sudo journalctl -u act_runner -n 50 # Verify the instance URL is reachable from the server wget -qO- https://git.sensetostyle.com/api/v1/version ``` ### Workflow stuck on "Waiting for runner" - Verify the runner labels match what the workflow expects. The workflow uses `runs-on: ubuntu-latest` which must match the `ubuntu-latest:host` label. - Check the runner is registered at the correct scope (instance-wide, org-level, or repo-level). ### Permission denied errors during deploy - Ensure the systemd service `User` has Docker access (`usermod -aG docker `) - Ensure the user has write access to `/opt/hoa-ledgeriq` ### Re-registering after token expiry ```bash sudo systemctl stop act_runner # Get a new token from Gitea admin panel, then: act_runner register \ --no-interactive \ --instance "https://git.sensetostyle.com" \ --token "NEW_TOKEN_HERE" \ --name "hoaledgeriq-prod" \ --labels "ubuntu-latest:host,ubuntu-22.04:host" \ --config /etc/act_runner/config.yaml sudo systemctl start act_runner ``` --- ## Security Best Practices | Concern | Recommendation | |---------|----------------| | Runner user | Use a dedicated user with `docker` group access rather than `root` when possible | | Registration token | Rotate periodically in the Gitea admin panel | | Config file | Keep `/etc/act_runner/config.yaml` at mode `600` (owner-read only) | | Runner scope | Register at the **repo level** instead of instance-wide so only this repo can trigger deployments | | Workflow triggers | The deploy workflow uses `workflow_dispatch` (manual only) — no automatic triggers on push | | Network | Ensure Gitea is accessed over HTTPS with valid SSL certificates |