freezmo/deploy/freezmo.service
Martin Dvorak 4c2834edac Run Freezmo as a systemd user service
After a reboot the app was simply gone because it only ever ran as a
foreground `npm start`. deploy/freezmo.service runs the production build
under systemd (user), restarts on crash and starts at boot:

- ExecStart runs next start directly (no npm wrapper), 0.0.0.0:3207.
- AssertPathExists=.next/BUILD_ID refuses to start without a build.
- After/Wants network-online, and After=ollama.service for local mode.
- README: install steps, useful commands, and the stop-build-start
  sequence for manual rebuilds (build and running server share .next/).

Installed and verified locally: enabled in default.target.wants with
linger already on, active after a stop/start cycle, 200 on
127.0.0.1:3207 and the LAN IP, and it self-heals after a kill -9.
2026-10-08 12:58:04 +00:00

33 lines
1.2 KiB
Desktop File

[Unit]
# Freezmo — self-hosted notes-to-study-feed app.
# Install (per user, no root needed):
# mkdir -p ~/.config/systemd/user
# cp deploy/freezmo.service ~/.config/systemd/user/
# systemctl --user daemon-reload
# systemctl --user enable --now freezmo.service
# loginctl enable-linger "$USER" # start at boot without logging in
# Logs: journalctl --user -u freezmo -f
Description=Freezmo (self-hosted study app)
Documentation=file://%h/freezmo/README.md
After=network-online.target
Wants=network-online.target
# In OLLAMA_AUTH=local mode the daemon should be up first (no-op otherwise).
After=ollama.service
[Service]
Type=simple
WorkingDirectory=%h/freezmo
Environment=NODE_ENV=production
Environment=NEXT_TELEMETRY_DISABLED=1
Environment=PATH=/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin
# Refuse to start without a production build — clearer than next crashing in a
# restart loop. Run `npm run build` in %h/freezmo first.
AssertPathExists=%h/freezmo/.next/BUILD_ID
# Next.js loads .env.local (OLLAMA_*) from the working directory itself.
ExecStart=/bin/node %h/freezmo/node_modules/next/dist/bin/next start -H 0.0.0.0 -p 3207
Restart=always
RestartSec=3
TimeoutStartSec=0
[Install]
WantedBy=default.target