systemd Service 设置工作目录:WorkingDirectory 与 ExecStart 相对路径

systemd service 文件通过 WorkingDirectory 指令设置进程启动后的工作目录,等同于 cd 后再执行命令。

基本配置

[Unit]
Description=My App Service

[Service]
Type=simple
User=www-data
WorkingDirectory=/opt/myapp
ExecStart=/usr/bin/python3 main.py
Restart=always
RestartSec=5

[Install]
WantedBy=multi-user.target

设置 WorkingDirectory=/opt/myapp 后:

  • ExecStart 中的相对路径基于 /opt/myapp
  • 程序内 os.getcwd()(Python)或 process.cwd()(Node.js)返回 /opt/myapp
  • 读写相对路径的文件(如 config.jsonlogs/)都指向该目录

修改配置后重新加载

sudo systemctl daemon-reload
sudo systemctl restart myapp.service

# 查看服务状态
systemctl status myapp.service

每次修改 .service 文件都需要 daemon-reload,否则 systemd 不会读取新配置。

常见问题

User 与目录权限

如果指定了 User=www-data,该用户必须对 WorkingDirectory 有读取权限(通常还需要写权限):

sudo chown www-data:www-data /opt/myapp
sudo chmod 750 /opt/myapp

带有空格的路径

WorkingDirectory=/opt/my app/   # 错误,空格无需引号但会导致解析问题
WorkingDirectory="/opt/my app"  # 正确,用引号包裹

ExecStart 中用绝对路径

ExecStart 建议始终用绝对路径,避免 $PATH 不同导致找不到命令:

ExecStart=/usr/bin/node /opt/myapp/server.js
# 不要写:ExecStart=node server.js

查看服务文件位置

# 列出所有用户服务文件
ls /etc/systemd/system/

# 查看某个服务的完整配置(包括覆盖)
systemctl cat myapp.service

服务文件通常放在 /etc/systemd/system/ 下,命名为 <name>.service