用 systemd 托管一个自写服务 · 修改记录
这是 linux/systemd-service.md 的每次改动内容,按时间从新到旧。其他文章一起提交的部分不会出现在这里。
#1
2026-10-18
+83
−0
docs: 新增 23 篇网络/ Linux / Windows / 服务器文章
be5956e
new file mode 100644
@@ -0,0 +1,83 @@
+---
+tags: [systemd, 服务, Linux]
+order: 30
+---
+
+# 用 systemd 托管一个自写服务
+
+## 场景
+
+脚本或程序要开机自启、挂了自动拉起、日志能查。别再写 `nohup &` 了。
+
+## 前置条件
+
+- 程序有确定的启动命令和运行目录
+- 用独立用户跑,不要用 root
+- 知道它会写哪些目录
+
+## 配置
+
+```bash
+# 建用户
+useradd -r -s /usr/sbin/nologin appuser
+
+# 单元文件
+cat >/etc/systemd/system/myapp.service <<'EOF'
+[Unit]
+Description=My App
+After=network-online.target
+Wants=network-online.target
+
+[Service]
+Type=simple
+User=appuser
+Group=appuser
+WorkingDirectory=/opt/myapp
+Environment="TZ=Asia/Shanghai"
+EnvironmentFile=-/opt/myapp/.env
+ExecStart=/opt/myapp/venv/bin/python /opt/myapp/main.py
+Restart=always
+RestartSec=3
+LimitNOFILE=65535
+StandardOutput=journal
+StandardError=journal
+
+[Install]
+WantedBy=multi-user.target
+EOF
+
+systemctl daemon-reload
+systemctl enable --now myapp
+```
+
+## 验证
+
+```bash
+systemctl status myapp
+journalctl -u myapp -n 100 --no-pager
+journalctl -u myapp -f
+systemctl restart myapp
+```
+
+杀进程测试自动拉起:
+
+```bash
+pkill -f main.py && sleep 4 && systemctl is-active myapp
+```
+
+## 回滚
+
+```bash
+systemctl disable --now myapp
+rm /etc/systemd/system/myapp.service
+systemctl daemon-reload
+```
+
+## 坑
+
+- **改了 unit 文件必须 `daemon-reload`**,否则 `start` 还是旧配置。
+- `Type=forking` 要配 PIDFile,配错会一直 `activating`。
+- `EnvironmentFile` 里的值不要加引号外层再加引号,会原样传进去。
+- 程序自己要写日志文件时,注意目录属主是 `appuser`。
+- `Restart=always` 遇到配置错误会无限重启,看 `journalctl` 里的报错再修。
+- 不要用 `systemctl edit` 之后忘记 `daemon-reload`,这个坑踩过不止一次。