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.
This commit is contained in:
Martin Dvořák 2026-10-08 12:58:04 +00:00
commit 4c2834edac
2 changed files with 67 additions and 0 deletions

View file

@ -24,6 +24,7 @@ no database, no data leaving your machine except the requests you send to Ollama
- [Changing models](#changing-models)
- [Checking the connection](#checking-the-connection)
- [Running on your network / from your phone](#running-on-your-network--from-your-phone)
- [Keep it running as a service](#keep-it-running-as-a-service-systemd-user-service)
- [Folders](#folders)
- [Install as an app (PWA)](#install-as-an-app-pwa)
- [Security notes](#security-notes)
@ -378,6 +379,37 @@ Notes for phones:
- Clipboard paste works best on desktop; on mobile use the camera or photo picker.
- Add the page to your home screen for a full-screen, app-like experience.
### Keep it running as a service (systemd user service)
`deploy/freezmo.service` runs the production build under **systemd (user)**, so Freezmo comes back by
itself after a reboot and restarts if it ever crashes:
```bash
npm run build # the service serves the built app
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
```
| Command | What it does |
| --- | --- |
| `systemctl --user status freezmo` | is it up? |
| `journalctl --user -u freezmo -f` | live logs |
| `systemctl --user restart freezmo` | after a rebuild |
| `systemctl --user stop freezmo` | stop it |
It binds `0.0.0.0:3207` exactly like `npm start` and reads `.env.local` from the project directory.
The unit refuses to start without `.next/BUILD_ID`, so run `npm run build` before enabling it — and
again after pulling changes.
Because the build and the running server share `.next/`, stop the service before a manual rebuild:
```bash
systemctl --user stop freezmo && npm run build && systemctl --user start freezmo
```
---
## Folders
@ -580,6 +612,8 @@ public/
icons/ PWA + iOS icons and splash screens
assets/
app-icon-source.jpeg master artwork the icons are rendered from
deploy/
freezmo.service systemd user unit (auto-start at boot)
scripts/
copy-pdf-worker.mjs copies the pdf.js worker to /public (runs on predev/prebuild)
make-icons.mjs regenerates the PWA/iOS icons from the master (one-off tool)