Files
Hermes-Skills/devops/clash-docker-workflow/references/systemd-setup.md
T
Hermes Skills Manager 6770bc9b9d Initial commit: Hermes Agent skills collection
- Trading skills (OKX, dividend, lottery, quantitative)
- Creative skills (ASCII art, diagrams, video)
- Development skills (GitHub, debugging, TDD)
- Research skills (arXiv, blog monitoring)
- Productivity skills (email, documents, notes)
- MCP integration skills
- Custom user skills
2026-07-05 02:31:15 -04:00

154 lines
4.3 KiB
Markdown

# 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
```