sotashimozono_obsidian-remo.../docs/en/server/systemd.md
Souta 545bbe0862 fix(docs): correct reuse-existing-daemon claim across 5 docs + 3 troubleshooting nits
Pass-3 review caught a sustained fabrication: I'd been claiming
"the plugin always kills + redeploys the daemon on every connect,
the 'reuse existing daemon' profile flag is on the roadmap" across
5 docs. Reality (verified against plugin/src/transport/DaemonProbe.ts:49
and plugin/src/ConnectionManager.ts:87): tryReuseExistingDaemon already
runs unconditionally before deploy. It probes socket + token + handshake;
on success the deploy is skipped entirely. The "roadmap flag" framing
was pure invention — the feature ships today.

Fixes (all narrative-level, no behavior change):
- en/server/auto-deploy.md: rewrote "What happens, in order" to lead
  with the reuse probe as step 2 (the real first action after path
  resolution); removed the "planned Reuse existing daemon" claim from
  "What if I don't want auto-deploy" — answer is "you already don't,
  the reuse path runs by default".
- en/server/systemd.md: replaced the "warm spare only" caveat with
  the accurate story (systemd-managed daemon gets reused via the probe).
- en/cookbook/systemd-managed-daemon.md: rewrote the trade-off note +
  the "Connect once" paragraph. The recipe now leads with the right
  expectation (reuse skips the upload) instead of an apologetic
  "accept the redeploy".
- en/faq.md: same correction in the "does the plugin re-deploy every
  connect" answer.
- en/server/raspberry-pi.md: corrected the throwaway "kills + restarts
  on every connect" line at the bottom.

Other pass-3 findings:
- en/api/authentication.md: server.info capabilities array used the
  "fs.read*"/"fs.write*" glob notation, which the daemon never emits.
  Replaced with the actual sorted 22-entry array (matches examples.md).
- en/operations/troubleshooting.md: removed "coalesced too aggressively"
  diagnosis (no server-side coalescing exists, per proto/README.md).
  Updated plugin log path from "<plugin>/logs/*.jsonl" to actual
  console.log location. Updated "Settings → About" (no such section)
  to the real version-display location.
2026-05-10 15:47:27 +09:00

2.8 KiB

title tags
systemd unit
server
deploy
systemd

systemd unit

Run the daemon as a long-lived service so it survives plugin reconnects, OS reboots, and lets you pre-deploy across many hosts.

Why bother

Auto-deploy works fine for most setups. systemd is worth it when:

  • You run the same vault from many clients (other devices, mobile relay) and want the daemon up 24/7.
  • You want central logging via journalctl rather than file-based logs.
  • You manage many hosts with config management (Ansible, NixOS) and prefer declarative service definitions.
  • You want resource limits enforced (MemoryMax, CPUQuota).

Install

# 1. Drop the binary somewhere persistent
sudo install -m 0755 -o YOUR_USER -g YOUR_USER \
  obsidian-remote-server-linux-amd64 \
  /usr/local/bin/obsidian-remote-server

# 2. Verify it's the binary you expect (see Cosign verify)
cosign verify-blob \
  --bundle obsidian-remote-server-linux-amd64.bundle \
  --certificate-identity-regexp 'https://github.com/sotashimozono/obsidian-remote-ssh/.github/workflows/release.yml@.*' \
  --certificate-oidc-issuer https://token.actions.githubusercontent.com \
  /usr/local/bin/obsidian-remote-server

Unit file

~/.config/systemd/user/obsidian-remote-server.service:

[Unit]
Description=obsidian-remote-ssh daemon
After=network.target

[Service]
Type=simple
ExecStart=/usr/local/bin/obsidian-remote-server \
  --vault-root=%h/notes \
  --socket=%h/.obsidian-remote/server.sock \
  --token-file=%h/.obsidian-remote/token \
  --verbose
Restart=on-failure
RestartSec=2s
MemoryMax=512M
CPUQuota=50%

[Install]
WantedBy=default.target

Replace %h/notes with your vault path.

Enable

mkdir -p ~/.obsidian-remote && chmod 700 ~/.obsidian-remote
systemctl --user daemon-reload
systemctl --user enable --now obsidian-remote-server
systemctl --user status obsidian-remote-server

To survive logout (no console session):

sudo loginctl enable-linger $USER

Plugin profile setup

In the plugin profile, set:

Field Value
Daemon socket path .obsidian-remote/server.sock (home-relative)
Daemon token path .obsidian-remote/token (home-relative)

The remote daemon binary path is currently fixed at ~/.obsidian-remote/server in the plugin (no UI override yet). The plugin's reuse-existing-daemon probe (see en/server/auto-deploy#what-happens-in-order) will attach to your systemd-managed daemon when it's healthy and skip the binary upload entirely. The deploy fallback only kicks in if the socket / token / handshake fails — typically when your binary version doesn't match the one the current plugin bundle expects.

Logs

journalctl --user -u obsidian-remote-server -f

Replaces ~/.obsidian-remote/server.log for the systemd-managed instance.

Next: en/server/raspberry-pi.