如何配置Systemd实现Rclone→Mergerfs→Docker的启动依赖顺序?
问题描述
我的最终目标是让Docker在mergerfs挂载完成后再启动,同时让mergerfs在3个rclone挂载(tv、movies、music)完成后再启动自身。我尝试过使用requires参数、ExecPreStart阶段的bash脚本,以及requiresmountsfor、wants=、after=参数,还有这些选项的组合;甚至尝试过通过/etc/fstab挂载mergerfs,但均无效。Systemd服务仅会因依赖问题“失败”,且不会重试,没有服务会等待或持续尝试。请问正确的配置方式是什么?
当前配置文件
docker.service.d/override.conf
[Unit] After=merge.service
{tv,movies,music}.service(以tv为例)
[Unit] Description=tv Wants=network-online.target After=network-online.target [Service] Type=notify Environment=RCLONE_CONFIG=/data/rclone/config/rclone.conf RestartSec=5 ExecStart=/usr/bin/rclone mount tv: /mnt/media/tv \ --<options> ExecStop=/bin/fusermount -uz /mnt/media/tv ExecStartPost=/usr/bin/rclone rc vfs/refresh recursive=true --rc-addr 127.0.0.1:5572 _async=true Restart=on-failure User=user Group=user [Install] WantedBy=multi-user.target
merge.service
[Unit] Description=merge After=tv.service movies.service music.service [Service] Type=forking ExecStart=/usr/bin/mergerfs /mnt/local:/mnt/media=NC /mnt/merge -o rw,use_ino,allow_other,func.getattr=newest,category.action=all,category.create=ff,cache.files=auto-full,nonempty KillMode=process Restart=on-failure [Install] WantedBy=multi-user.target
正确配置方案
要实现服务间的依赖等待和自动重试,需调整Systemd服务的依赖规则与服务类型,确保每个服务仅在前置依赖完全就绪后启动,且依赖失败时能自动重试等待。
1. 修改rclone挂载服务(tv/movies/music.service)
确保rclone挂载服务能正确通知Systemd挂载完成,让merge.service可明确依赖其就绪状态:
[Unit] Description=tv Wants=network-online.target After=network-online.target RequiresMountsFor=/mnt/media/tv Before=merge.service [Service] Type=notify Environment=RCLONE_CONFIG=/data/rclone/config/rclone.conf RestartSec=5 ExecStart=/usr/bin/rclone mount tv: /mnt/media/tv \ --<options> \ --daemon \ --rc-disable ExecStop=/bin/fusermount -uz /mnt/media/tv ExecStartPost=/bin/sleep 2 ExecStartPost=/bin/systemd-notify --ready Restart=always User=user Group=user RestartForceExitStatus=SIGINT SIGTERM [Install] WantedBy=multi-user.target WantedBy=merge.service
2. 修改merge.service
让mergerfs服务明确依赖三个rclone服务的就绪状态,自身启动后通知Systemd,并配置重试逻辑:
[Unit] Description=merge Requires=tv.service movies.service music.service After=tv.service movies.service music.service RequiresMountsFor=/mnt/local /mnt/media /mnt/merge Before=docker.service [Service] Type=simple ExecStart=/usr/bin/mergerfs /mnt/local:/mnt/media=NC /mnt/merge -o rw,use_ino,allow_other,func.getattr=newest,category.action=all,category.create=ff,cache.files=auto-full,nonempty ExecStop=/bin/fusermount -uz /mnt/merge ExecStartPost=/bin/systemd-notify --ready Restart=always RestartSec=3 KillMode=process RestartForceExitStatus=1 [Install] WantedBy=multi-user.target WantedBy=docker.service
3. 修改docker.service.d/override.conf
确保Docker在merge服务完全就绪后启动:
[Unit] Requires=merge.service After=merge.service
4. 关键配置说明
RequiresvsWants:Requires为强制依赖,若依赖服务启动失败,当前服务也会终止;Wants是弱依赖,不影响当前服务启动。此处用Requires确保依赖服务必须就绪。Type=notify:服务启动完成后必须通过systemd-notify --ready通知Systemd,依赖它的服务才会等待其真正就绪。Restart=always:确保服务失败或退出时自动重启,解决之前不重试的问题。RequiresMountsFor:检查挂载点目录是否存在,避免因目录缺失导致挂载失败。Before/After:明确服务启动顺序,确保前置服务完全启动后再启动后续服务。
内容的提问来源于stack exchange,提问作者Danny Michel
相关产品推荐
相关产品推荐

