跳过正文

通过systemd将Python程序部署为稳定运行的服务

·288 字·2 分钟·
凌风
作者
凌风
凌风迥秀,响振虚谷
目录

在服务器上运行 Python 脚本时,一个常见但脆弱的方法是使用 python3 my_app.py &。这种方式虽然能让程序在后台运行,但它存在致命的缺点:一旦程序因错误崩溃,或者服务器重启,进程就会永久终止,需要手动重新启动。这对于需要 7x24 小时运行的服务是不可接受的。

为了解决这个问题,我们可以使用 systemd——现代 Linux 发行版(如 Ubuntu 16.04+、CentOS 7+)内置的系统和服务管理器。systemd 可以像守护神一样守护你的程序,实现自动启动、失败重启、日志管理等关键功能,是专业部署的黄金标准。

本文将手把手教你如何为你的 Python 程序创建一个 systemd 服务。

第一步:准备你的 Python 程序
#

在开始之前,请确保:

  1. 你的 Python 程序(例如 my_app.py)可以在服务器上无误地运行。
  2. 记下你的 Python 解释器和脚本的绝对路径
    • 查找 Python 解释器的绝对路径:which python3 (可能会返回 /usr/bin/python3/usr/local/bin/python3 等)
    • 查找脚本所在的目录路径。

第二步:创建 systemd 服务文件 (.service)
#

systemd 通过后缀为 .service 的配置文件来管理服务。这些文件通常存放在 /etc/systemd/system/ 目录下。

  1. 创建服务文件。我们将为服务取一个有意义的名字,例如 my-python-app.service。使用你喜欢的文本编辑器(如 nanovim)创建它:

    sudo nano /etc/systemd/system/my-python-app.service
    
  2. 编写配置内容。将以下模板内容复制到文件中,然后我们会逐一解释每个指令的含义。

    [Unit]
    Description=A description for your Python application
    After=network.target
    
    [Service]
    User=your_username
    Group=your_groupname
    WorkingDirectory=/path/to/your/project
    ExecStart=/path/to/your/python3 /path/to/your/project/my_app.py
    Restart=on-failure
    RestartSec=5s
    
    [Install]
    WantedBy=multi-user.target
    

第三步:理解配置文件的每一部分
#

让我们来详细解析这个配置文件的每个部分和指令:

  • [Unit] 部分: 定义了服务的基本信息和依赖关系。

    • Description: 服务的简短描述,会在你查看服务状态时显示。
    • After=network.target: 指定此服务应该在网络服务准备好之后再启动。对于需要网络连接的程序(如 Web 服务、API),这是一个必须的设置。
  • [Service] 部分: 定义了服务的核心行为。

    • User: **(重要)**指定运行此服务的用户。为了安全,强烈建议使用一个非 root 的普通用户。如果你的程序不需要特殊权限,不要使用 root
    • Group: 指定运行此服务的用户组(可选,但推荐)。
    • WorkingDirectory: 指定脚本的工作目录。这非常重要,因为你的 Python 代码中任何相对路径的文件读写(如打开配置文件、写入日志)都将以此目录为基准。
    • ExecStart: (核心)定义启动服务的完整命令。这里必须使用绝对路径指定 Python 解释器和你的脚本。
    • Restart=on-failure: 这是实现稳定性的关键!它告诉 systemd,如果进程非正常退出(即返回非 0 的退出码,通常意味着发生错误),就自动重启它。你也可以设置为 always,这样即使用户手动停止,它也会被重启。
    • RestartSec=5s: 在尝试重启前等待 5 秒。这可以防止因程序快速连续崩溃而耗尽系统资源。
  • [Install] 部分: 定义了服务的安装信息。

    • WantedBy=multi-user.target: 这意味着当你执行 systemctl enable my-python-app.service 时,服务会被设置为在系统进入多用户模式(即正常开机后)时自动启动。

第四步:实战案例 - 部署 Gemini UI 应用
#

现在,让我们应用这些知识,看看你提供的 gemini.service 配置。假设我们将服务文件命名为 gemini-ui.service

配置文件 (/etc/systemd/system/gemini-ui.service):

[Unit]
Description=My Python Application
# 确保在网络服务启动后再启动你的应用
After=network.target

[Service]
# 运行此服务的用户
User=root
# 你的Python项目所在的目录
WorkingDirectory=/root/codes/gemini-2.0-flash-exp-ui
# 启动命令,请使用绝对路径!
# 可以用 which python3 命令找到python3的绝对路径
ExecStart=/usr/local/bin/python3 gemini_image_ui_base64.py 
# 在失败时自动重启
Restart=on-failure 
# 重启间隔
RestartSec=5s 

[Install]
WantedBy=multi-user.target

配置分析:

  • 这个配置非常标准且实用。它正确地设置了工作目录和启动命令。
  • WorkingDirectory 设置为 /root/codes/gemini-2.0-flash-exp-ui,这意味着 gemini_image_ui_base64.py 中所有相对路径的操作都会在这个目录下进行。
  • ExecStart 使用了绝对路径 /usr/local/bin/python3,这是一个好习惯。
  • 安全提示: User=root 意味着程序拥有服务器的最高权限。如果此程序存在任何安全漏洞,可能会对整个系统造成风险。如果程序不需要 root 权限(例如,它不监听 1024 以下的端口),建议创建一个专用用户来运行它,以提高安全性。

第五步:管理你的服务
#

在你创建并保存了 .service 文件后,就可以使用 systemctl 命令来管理你的服务了。

  1. 重载 systemd 配置: 每次创建或修改 .service 文件后,你都必须运行此命令来让 systemd 重新加载配置。

    sudo systemctl daemon-reload
    
  2. 启动服务

    sudo systemctl start gemini-ui.service
    
  3. 查看服务状态(最常用的命令): 这是排查问题的首要工具!它会显示服务是否正在运行、进程ID (PID) 以及最新的几行日志输出。

    sudo systemctl status gemini-ui.service
    
    • 如果看到 Active: active (running),恭喜你,服务运行正常!
    • 如果看到 Active: failed,说明启动失败,你需要查看下方的日志来找出原因。
  4. 设置开机自启动: 要让服务在服务器重启后自动运行,你需要“启用”它。

    sudo systemctl enable gemini-ui.service
    

    (对应的,禁用开机自启是 sudo systemctl disable gemini-ui.service)

  5. 停止服务

    sudo systemctl stop gemini-ui.service
    
  6. 重启服务: 当你修改了 Python 代码并想让它生效时,使用此命令。

    sudo systemctl restart gemini-ui.service
    

第六步:查看日志
#

systemd 有自己强大的日志系统 journald。你可以用 journalctl 命令方便地查看你的程序的所有输出(包括 print 语句和错误信息)。

  • 查看服务的全部日志

    sudo journalctl -u gemini-ui.service
    
  • 实时查看日志(类似 tail -f: 这个命令在调试时非常有用,可以实时看到程序的输出。

    sudo journalctl -u gemini-ui.service -f
    
  • 查看最新的100行日志

    sudo journalctl -u gemini-ui.service -n 100
    

总结
#

通过以上步骤,你已经成功地将一个简单的 Python 脚本转变成了一个健壮、可靠、可管理的系统服务。从此以后,你再也无需担心程序崩溃或服务器重启导致的服务中断。这是从“能用”到“可靠”的关键一步。