释放小七猫的分享欲

Linux 系统的 NAS 之路——systemd 基础及非容器应用的部署

tags: NAS, Linux
@ 17/07/2026

Linux 系统的 NAS 之路—— systemd 基础及非容器应用的部署

使用容器部署应用固然方便,但还是存在不少缺点的:

  1. 占用空间较大,由于每个镜像都额外带了很多依赖,会导致镜像比程序本身大很多。再加上容器镜像“层”的概念,不及时清理冗余镜像的话,时间长了硬盘空间直接爆炸。
  2. 网络性能问题,尽管 host 网络可以与主机共享网络协议栈,但容器中也许会存在不少的冗余服务(例如有的容器默认 Nginx 会占用 80 端口),这些服务会让主机网络很难管理。而桥接网络的话,会有一些性能损失。

因此对于某些轻量化,易部署的应用,我更推荐用 systemd 进行处理。

系统级 systemd

系统级 systemd 服务默认以 root 用户运行,但可以在配置文件中指定用户。

有些发行版 systemd 配置文件在 /etc/systemd/system/

sukipai@DESKTOP-F3AQEDF:/etc/systemd$ tree -L2
.
├── network
├── system
│   ├── basic.target.wants
....
│   ├── sysinit.target.wants
│   ├── systemd-homed.service.wants
│   ├── systemd-journald.service.wants
│   └── timers.target.wants
└── user
    ├── basic.target.wants
    ├── dbus.service -> /usr/lib/systemd/user/dbus-broker.service
    ├── sockets.target.wants
    └── timers.target.wants

但 Fedora 系统的配置在 /usr/lib/systemd/system,.service 文件就是一个服务文件。

如果你的服务程序需要以 root 身份运行,就把 service 文件放在这里。

[Unit]
Description=My Simple Service
After=network.target

[Service]
ExecStart=/usr/bin/python3 /path/to/your/script.py
Restart=always
User=root

[Install]
WantedBy=multi-user.target

服务文件的三个区块

服务配置其实就三个区块。理解了它们,systemd 就学会了七成:

  • [Unit] — 描述与依赖。After=network.target 表示网络就绪后再启动此服务
  • [Service] — 核心配置。ExecStart 指定运行命令,Restart 定义重启策略,User 指定运行用户
  • [Install] — enable 时挂载到哪个启动级别。WantedBy=multi-user.target 表示进入多用户模式时自动启动

关键字段 Type=

[Service] 里有一个容易被忽略但很重要的字段——Type,它告诉 systemd 如何判断服务是否启动成功。选错了可能导致 systemd 误判,不断重启服务:

  • simple(默认)— 程序在前台直接运行,systemd 看到进程启动就认为成功
  • forking — 传统守护进程会 fork 到后台、父进程退出,
  • oneshot — 执行一次就结束,适合一次性脚本任务
  • notify — 程序通过 sd_notify() 主动通知 systemd 自己已就绪

后面的 mihomo 示例用的就是 Type=simple,这也是最推荐的方式——保持程序在前台即可。

用户级 systemd

不推荐把所有的服务都放在系统级目录里面,许多应用普通用户也可以启动,放在系统级目录下面反而会降低安全性。

用户级 systemd 配置目录:~/.config/system/user

服务配置:

[Unit]
Description=My Simple Service
After=network.target

[Service]
ExecStart=/usr/bin/python3 /path/to/your/script.py
Restart=always

[Install]
WantedBy=defualt.target

这项服务会以当前用户启动,即便服务被黑,攻击者能获取到的文件权限是有限的,被限定在当前用户范围内。

使用用户级 systemd 的时候不要加 sudo

重载配置文件:

systemctl --user daemon-reload

启动/停止服务:

systemctl --user start/stop SERVICE

自启动服务:

systemctl --user enable SERVICE

相比系统级 systemd,主要使用方式区别在于不加 sudo 和添加–user 参数。

查看服务日志(journalctl)

服务跑起来后第一件事就是看它正不正常。systemctl status 可以快速了解概况:

systemctl --user status mihomo

输出中重点关注两行:

  • Loaded: loaded — 配置文件已被加载
  • Active: active (running) — 正在运行;如果显示 failed 则启动失败

更详细的排查要靠日志。systemd 的日志统一由 journalctl 管理,用它替代直接读文本日志文件:

# 查看某个服务的全部日志
journalctl --user -u mihomo.service

# 实时跟踪日志(类似 tail -f)
journalctl --user -u mihomo.service -f

# 只看最近 20 条
journalctl --user -u mihomo.service -n 20

系统级服务去掉 --user 即可,不加 sudo 只能看到当前用户的日志。

mihomo 部署示例

mihomo 是一款分流软件,支持多种代理协议和规则分流。

安装 mihomo

从 MetaCubeX/mihomo 下载对应架构的二进制文件。

将这个文件放在用户目录下,比如 ~/applications/mihomo/mihomo

添加你的配置文件到 ~/applications/mihomo/mihomo/config.yaml,然后测试运行:

cd ~/applications/mihomo/
./mihomo -d .

确认无误后 Ctrl+C 停止,接下来用 systemd 管理。

用户级 systemd 服务

如果以普通用户运行,使用用户级 systemd,在 ~/.config/systemd/user/ 下创建 mihomo.service:

[Unit]
Description=mihomo proxy service
After=network.target

[Service]
Type=simple
ExecStart=%h/applications/mihomo/mihomo -d %h/applications/mihomo/
Restart=on-failure
RestartSec=5s

[Install]
WantedBy=default.target

%h 会自动展开为当前用户的家目录,这样配置文件路径就不需要硬编码用户名。

然后进行启动与验证:

systemctl --user daemon-reload
systemctl --user enable --now mihomo
systemctl --user status mihomo