用 systemd 托管 Python 脚本:让后台服务真正稳住的 6 个配置
很多人在服务器上跑爬虫、定时任务或者小型接口时,开局基本都是 python app.py & 一把梭。问题是进程崩了没人管,机器重启后服务也没了,日志还散在各个角落。其实 Linux 自带的 systemd 几行配置就能解决这些麻烦,不必额外引入 Supervisor 或 PM2。下面这 6 个配置项,是我长期用下来觉得最关键的。
1. Restart:决定它能不能自己爬起来
[Service]
Restart=on-failure
RestartSec=5
StartLimitIntervalSec=300
StartLimitBurst=5
Restart=on-failure 表示只有非 0 退出码才重启,比 always 更合理:代码本身有 bug 导致秒退时,配合 StartLimitBurst 限制启动次数,避免把机器打满。手动正常停掉服务时也不会被强行拉起来。
2. 用 -u 关掉缓冲,日志才跟得上
ExecStart=/usr/bin/python3 -u /opt/app/main.py
Python 输出重定向到管道时默认是块缓冲的,不加 -u,你在 journal 里看到的日志可能是几分钟前的一批。
3. WorkingDirectory 与 EnvironmentFile
脚本里凡是用了相对路径(读配置、写缓存),一旦放到 systemd 里就全部失效——systemd 的默认工作目录不是你的项目目录。显式声明:
[Service]
WorkingDirectory=/opt/app
EnvironmentFile=/etc/myapp/env
环境变量、密钥统一放到 EnvironmentFile,权限设成 600,既方便改又因为不进 git 而不泄露。写进 unit 文件里是最糟的做法。
4. 日志交给 journald,别自己重定向
默认 stdout/stderr 就进 journald,直接:
journalctl -u myapp -f
journalctl -u myapp --since "10 min ago" -o cat
想控制占用,在 /etc/systemd/journald.conf 里设 SystemMaxUse=500M,别让日志把磁盘撑爆。
5. 给它一个资源上限
[Service]
MemoryMax=512M
CPUQuota=50%
脚本存在内存泄漏是常态,不加限制最后往往是整个机器 OOM,连 SSH 都登不上。加完之后最坏情况只是这一个服务被杀掉。
6. 最小权限:顺手加固
[Service]
User=appuser
NoNewPrivileges=true
PrivateTmp=true
ProtectSystem=strict
ReadWritePaths=/var/lib/myapp
以普通用户运行、拿不到新权限、独立的 /tmp、系统目录只读只放行需要写入的路径。这几行几乎零成本,却能把绝大多数意外写操作挡在外面。
收尾:改完别忘 reload
sudo systemctl daemon-reload
sudo systemctl enable --now myapp
systemctl status myapp
enable --now 等价于开机自启 + 立即启动。最后用 status 看一眼 Active: 行有没有落成 active (running),绿字不等于真的活着,最好再确认一次进程确实在跑。
把这 6 项配齐,一个 Python 脚本才算真正“服务化”:能自愈、看得见日志、有资源上限、出问题时不会连累整台机器。
- 点赞
- 收藏
- 关注作者
评论(0)