# Systemd Service for Mihomo + YACD

Two approaches: **system-level** (recommended for always-on servers) and **user-level**.

---

## Option A: System-Level Services (recommended for servers)

System-level services run as root, survive logout without extra config, and start early in boot.

### Create service files

**Pitfall**: The Hermes security scanner blocks `sudo tee /etc/systemd/system/` and `sudo cp` into system paths. Workaround: write to `/tmp` first using `write_file`, then ask the user to manually run `sudo cp` + `sudo systemctl`.

```bash
# Step 1: Agent writes to /tmp (allowed by write_file tool)
# /tmp/mihomo.service:
[Unit]
Description=Mihomo (Clash Meta) Proxy
After=network-online.target
Wants=network-online.target

[Service]
Type=simple
WorkingDirectory=/home/openclaw/clash
ExecStart=/home/openclaw/clash/mihomo -d /home/openclaw/clash/config
Restart=on-failure
RestartSec=5
LimitNOFILE=65535
StandardOutput=append:/tmp/mihomo.log
StandardError=append:/tmp/mihomo.log

[Install]
WantedBy=multi-user.target

# /tmp/yacd.service:
[Unit]
Description=YACD - Clash Dashboard
After=network-online.target mihomo.service
Wants=network-online.target
Requires=mihomo.service

[Service]
Type=simple
WorkingDirectory=/home/openclaw/clash/yacd
ExecStart=/usr/bin/python3 -m http.server 9091 --bind 0.0.0.0
Restart=on-failure
RestartSec=3
StandardOutput=append:/tmp/yacd.log
StandardError=append:/tmp/yacd.log

[Install]
WantedBy=multi-user.target
```

### Step 2: User manually runs
```bash
sudo cp /tmp/mihomo.service /etc/systemd/system/
sudo cp /tmp/yacd.service /etc/systemd/system/
sudo systemctl daemon-reload
sudo systemctl enable mihomo yacd
sudo systemctl start mihomo yacd
sudo systemctl status mihomo yacd
```

### Key design choices
- `Requires=mihomo.service` on yacd: yacd won't start if mihomo fails
- `After=network-online.target`: wait for network before starting
- `Restart=on-failure`: auto-restart on crash
- `LimitNOFILE=65535`: mihomo handles many connections
- Logs to `/tmp/` via `append:` (matches startup.sh convention)

### Migration from startup.sh
Once systemd manages the services, **disable** the startup.sh service definitions to prevent conflicts:
```bash
# Disable (don't delete — keep as backup)
mv ~/startup/services/mihomo.sh ~/startup/services/mihomo.sh.disabled
mv ~/startup/services/yacd.sh ~/startup/services/yacd.sh.disabled  # if applicable

# Verify startup.sh no longer manages these
bash ~/startup/startup.sh status  # should not show mihomo/yacd

# Use systemd exclusively
systemctl --user start|stop|restart|status mihomo  # user-level
# or: sudo systemctl start|stop|restart|status mihomo  # system-level
```

**Why disable instead of delete**: If systemd service has issues, you can quickly re-enable by renaming back. Also keeps the service definition as documentation.

**Pitfall**: If you forget to disable startup.sh definitions AND the watchdog still calls `startup.sh restart`, the two managers fight over PIDs. Always migrate atomically: create systemd service → enable → disable startup.sh definition → update watchdog.

---

## Option B: User-Level Services (for non-root setups)

User services run as the logged-in user, no root needed for service files.

```bash
mkdir -p ~/.config/systemd/user
cat > ~/.config/systemd/user/mihomo.service << 'EOF'
[Unit]
Description=Mihomo (Clash Meta) Proxy
After=network.target

[Service]
Type=simple
WorkingDirectory=%h/clash
ExecStart=%h/clash/mihomo -d %h/clash/config
Restart=on-failure
RestartSec=5

[Install]
WantedBy=default.target
EOF

cat > ~/.config/systemd/user/yacd-dashboard.service << 'EOF'
[Unit]
Description=YACD Dashboard (static HTTP)
After=network.target mihomo.service

[Service]
Type=simple
WorkingDirectory=%h/clash/yacd
ExecStart=/usr/bin/python3 -m http.server 9091 --bind 0.0.0.0 --directory %h/clash/yacd
Restart=on-failure
RestartSec=5

[Install]
WantedBy=default.target
EOF

systemctl --user daemon-reload
systemctl --user enable mihomo yacd-dashboard
systemctl --user start mihomo yacd-dashboard
```

**Critical**: Without linger, user services die on logout:
```bash
sudo loginctl enable-linger $USER
```

---

## Verify (both options)
```bash
# System-level
sudo systemctl status mihomo yacd
# User-level
systemctl --user status mihomo yacd-dashboard

curl -s http://127.0.0.1:9090/version
curl -s http://127.0.0.1:9091/ | head -3
```
