用 systemd 把 Python 脚本变成开机自启的可靠服务

举报
yd_284037603 发表于 2026/11/02 20:20:16 2026/11/02
【摘要】 用 systemd 托管 Python 脚本的完整改造:unit 文件怎么写、daemon-reload 为什么必须、EnvironmentFile 权限怎么收、Restart 策略怎么选、日志怎么看。附一份可以直接改的配置和一套排错顺序。

背景

把一个 Python 脚本丢到服务器上跑,最常见的做法是 nohup python main.py &。当时能跑,但过两天就会发现:机器重启后进程没了、日志散在 nohup.out 里翻不到、脚本半夜挂了没人知道。用 systemd 托管,改造成本其实只有十几行配置。

第一步:写一个 unit 文件

在 /etc/systemd/system/ 下新建 myjob.service:

[Unit]
Description=My Python Job
After=network-online.target
Wants=network-online.target

[Service]
Type=simple
User=appuser
WorkingDirectory=/opt/myjob
EnvironmentFile=/opt/myjob/.env
ExecStart=/opt/myjob/.venv/bin/python /opt/myjob/main.py
Restart=always
RestartSec=5

[Install]
WantedBy=multi-user.target

第二步:加载并启动

两条命令,一条让它被 systemd 认识,一条让它开机自启并立刻跑起来:

systemctl daemon-reload
systemctl enable --now myjob

改完 unit 文件之后一定要重新 daemon-reload,否则 systemd 用的还是内存里的旧配置——这是最容易踩的坑,改了半天发现没生效。

几个关键细节

1. 别用 root 跑。User=appuser 加上最小权限,比出事之后再补救便宜得多。注意 WorkingDirectory 要设成脚本真正的工作目录,否则代码里所有相对路径都会失效。

2. EnvironmentFile 的权限要收紧。把环境变量(数据库密码、API Key)放进 .env,用 EnvironmentFile 引用,然后 chmod 600 并 chown 给运行用户。不要直接把密码写在 unit 文件里,那个文件默认全局可读。

3. Restart 用 always 还是 on-failure。常驻服务用 always,进程不管因为什么退出都会被拉起来;一次性任务用 on-failure,正常退出就结束。RestartSec=5 别省,否则进程因配置错误秒退时会疯狂重启,把 CPU 和日志都打满。

4. 日志交给 journald。不要自己往文件里写,直接打到标准输出,然后 journalctl -u myjob -f 看实时日志,journalctl -u myjob --since "10 min ago" 查历史。想限制体积,在 /etc/systemd/journald.conf 里设 SystemMaxUse=500M。

出问题先看这两个地方

systemctl status myjob 看状态和最近几行输出;journalctl -u myjob -n 50 --no-pager 看完整报错。如果状态是 activating (auto-restart),基本就是脚本启动后立刻退出了,先手动执行一遍 ExecStart 那条命令,报错会直接打在终端上。

小结

systemd 不是什么高级玩意,它只是把「怎么跑、挂了怎么办、日志去哪、重启后还在不在」这四个问题一次性回答完。十几行配置换掉 nohup 和一地鸡毛,这笔账怎么算都划算。

【声明】本内容来自华为云开发者社区博主,不代表华为云及华为云开发者社区的观点和立场。转载时必须标注文章的来源(华为云社区)、文章链接、文章作者等基本信息,否则作者和本社区有权追究责任。如果您发现本社区中有涉嫌抄袭的内容,欢迎发送邮件进行举报,并提供相关证据,一经查实,本社区将立刻删除涉嫌侵权内容,举报邮箱: cloudbbs@huaweicloud.com
  • 点赞
  • 收藏
  • 关注作者

评论(0)

0/1000
抱歉,系统识别当前为高风险访问,暂不支持该操作

全部回复

上滑加载中

设置昵称

在此一键设置昵称,即可参与社区互动!

*长度不超过10个汉字或20个英文字符,设置后3个月内不可修改。

*长度不超过10个汉字或20个英文字符,设置后3个月内不可修改。