Files
MajorWiki/05-troubleshooting/gitea-runner-boot-race-network-target.md
MajorLinux 6592eb4fea wiki: audit fixes — broken links, wikilinks, frontmatter, stale content (66 files)
- Fixed 4 broken markdown links (bad relative paths in See Also sections)
- Corrected n8n port binding to 127.0.0.1:5678 (matches actual deployment)
- Updated SnapRAID article with actual majorhome paths (/majorRAID, disk1-3)
- Converted 67 Obsidian wikilinks to relative markdown links or plain text
- Added YAML frontmatter to 35 articles missing it entirely
- Completed frontmatter on 8 articles with missing fields

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-04-02 11:16:29 -04:00

94 lines
3.6 KiB
Markdown

---
title: "Gitea Actions Runner: Boot Race Condition Fix"
domain: troubleshooting
category: general
tags: [gitea, systemd, boot, dns, ci-cd]
status: published
created: 2026-04-02
updated: 2026-04-02
---
# Gitea Actions Runner: Boot Race Condition Fix
If your `gitea-runner` (act_runner) service fails to start on boot — crash-looping and eventually hitting systemd's restart rate limit — the service is likely starting before DNS is available.
## Symptoms
- `gitea-runner.service` enters a crash loop on boot
- `journalctl -u gitea-runner` shows connection/DNS errors on startup:
```
dial tcp: lookup git.example.com: no such host
```
or similar resolution failures
- Service eventually stops retrying (systemd restart rate limit reached)
- `systemctl status gitea-runner` shows `(Result: start-limit-hit)` after reboot
- Service works fine if started manually after boot completes
## Why It Happens
`After=network.target` only guarantees that the network **interfaces are configured** — not that DNS resolution is functional. systemd-resolved (or your local resolver) starts slightly later. `act_runner` tries to connect to the Gitea instance by hostname on startup, the DNS lookup fails, and the process exits.
With the default `Restart=always` and no `RestartSec`, systemd restarts the service immediately. After 5 rapid failures within the default burst window (10 attempts in 2 minutes), systemd hits the rate limit and stops restarting.
## Fix
### 1. Update the Service File
Edit `/etc/systemd/system/gitea-runner.service`:
```ini
[Unit]
Description=Gitea Actions Runner
After=network-online.target
Wants=network-online.target
[Service]
User=deploy
WorkingDirectory=/opt/gitea-runner
ExecStart=/opt/gitea-runner/act_runner daemon
Restart=always
RestartSec=10
[Install]
WantedBy=multi-user.target
```
Key changes:
- `After=network-online.target` + `Wants=network-online.target` — waits for full network stack including DNS
- `RestartSec=10` — adds a 10-second delay between restart attempts, preventing rapid failure bursts from hitting the rate limit
### 2. Add a Local /etc/hosts Entry (Optional but Recommended)
If your Gitea instance is on the same local network or reachable via Tailscale, add an entry to `/etc/hosts` so act_runner can resolve it without depending on external DNS:
```
127.0.0.1 git.example.com
```
Replace `git.example.com` with your Gitea hostname and the IP with the correct local address. This makes resolution instantaneous and eliminates the DNS dependency entirely for startup.
### 3. Reload and Restart
```bash
sudo systemctl daemon-reload
sudo systemctl restart gitea-runner
sudo systemctl status gitea-runner
```
Verify it shows `active (running)` and stays that way. Then reboot and confirm it comes up automatically.
## Why `network-online.target` and Not `network.target`
| Target | What it guarantees |
|---|---|
| `network.target` | Network interfaces are configured (IP assigned) |
| `network-online.target` | Network is fully operational (DNS resolvers reachable) |
Services that need to make outbound network connections (especially DNS lookups) on startup should always use `network-online.target`. This includes: mail servers, monitoring agents, CI runners, anything that connects to an external host by name.
> [!note] `network-online.target` can add a few seconds to boot time since systemd waits for the network stack to fully initialize. For server contexts this is always the right tradeoff.
## Related
- [Managing Linux Services with systemd](../01-linux/process-management/managing-linux-services-systemd-ansible.md)
- [MajorWiki Setup & Publishing Pipeline](majwiki-setup-and-pipeline.md)