add systemd user unit so the dev server starts at boot
This commit is contained in:
parent
bc738541cf
commit
174212750b
3 changed files with 78 additions and 3 deletions
20
README.md
20
README.md
|
|
@ -112,6 +112,24 @@ those endpoints and `*.map` for any request that isn't a direct localhost connec
|
|||
Localhost keeps the full dev experience; the LAN and tunnel get a plain, live-reloading
|
||||
site. To force the raw server instead, use `npm run dev:next` (don't point a tunnel at it).
|
||||
|
||||
### Running it as a service (survives reboot)
|
||||
|
||||
On this host the dev server runs as a **user** systemd unit, so it comes back after a
|
||||
reboot without a login (linger is enabled). The unit lives in the repo at
|
||||
[`deploy/dvorakmortonxd-dev.service`](./deploy/dvorakmortonxd-dev.service):
|
||||
|
||||
```bash
|
||||
mkdir -p ~/.config/systemd/user
|
||||
cp deploy/dvorakmortonxd-dev.service ~/.config/systemd/user/
|
||||
systemctl --user daemon-reload
|
||||
systemctl --user enable --now dvorakmortonxd-dev.service
|
||||
loginctl enable-linger "$USER" # once, so it starts at boot
|
||||
```
|
||||
|
||||
Manage it with `systemctl --user status|restart|stop dvorakmortonxd-dev` and follow logs with
|
||||
`journalctl --user -u dvorakmortonxd-dev -f`. It shares `.next/dev/lock` with a manual
|
||||
`npm run dev`, so stop the service before starting one by hand.
|
||||
|
||||
## 📡 API Routes
|
||||
|
||||
| Route | Method | What it does |
|
||||
|
|
@ -153,6 +171,8 @@ src/app/
|
|||
SlBackground.tsx → animated ASCII train background
|
||||
scripts/
|
||||
dev-server.mjs → custom dev server: live updates without the dev-only debug surface
|
||||
deploy/
|
||||
dvorakmortonxd-dev.service → systemd user unit so the dev server starts at boot
|
||||
public/ → fonts, wallpapers, icons, friend pages, /revival-inc game, llms.txt, robots.txt, sitemap.xml
|
||||
```
|
||||
|
||||
|
|
|
|||
17
agents.md
17
agents.md
|
|
@ -249,6 +249,15 @@ list reordering, not free placement. Don't confuse the two.
|
|||
`localhost:3000` keeps the full dev experience; the LAN/tunnel get a plain,
|
||||
live-reloading site. Use `npm run dev:next` only if you explicitly want the
|
||||
raw, unprotected server (never point the tunnel at it).
|
||||
- The dev server normally runs on this host as a **user** systemd unit
|
||||
(`~/.config/systemd/user/dvorakmortonxd-dev.service`, kept in-repo at
|
||||
`deploy/dvorakmortonxd-dev.service`). `Linger=yes` for uid 1000 means it starts
|
||||
at boot without a login. `systemctl --user restart dvorakmortonxd-dev` reloads
|
||||
it; logs with `journalctl --user -u dvorakmortonxd-dev -f`. From a bare shell
|
||||
with no session bus, prefix those with
|
||||
`XDG_RUNTIME_DIR=/run/user/1000 DBUS_SESSION_BUS_ADDRESS=unix:path=/run/user/1000/bus`.
|
||||
The unit pins `HOSTNAME=0.0.0.0` (the script reads that env var) so the tunnel
|
||||
can reach :3000, and clears a stale `.next/dev/lock` on start.
|
||||
- `allowedDevOrigins` (`next.config.ts`) still matters: the tunnel host and any
|
||||
LAN origin must be listed or Next rejects the HMR WebSocket with a 403 (the
|
||||
client then never hydrates — SSR only, icons stacked at `(0,0)`, dead
|
||||
|
|
@ -299,9 +308,11 @@ list reordering, not free placement. Don't confuse the two.
|
|||
## Testing notes
|
||||
- There is **no test suite**. Verification is `tsc --noEmit`, `eslint`, and
|
||||
`next build`.
|
||||
- A dev server may already be running on port 3000; check before starting one.
|
||||
Two dev servers on this repo collide on `.next/dev/lock`, so stop the old one
|
||||
(and delete the stale lock) before starting the custom one.
|
||||
- A dev server may already be running on port 3000 — on this host it is normally
|
||||
the `dvorakmortonxd-dev` user systemd service, so check
|
||||
`systemctl --user status dvorakmortonxd-dev` first. Two dev servers on this
|
||||
repo collide on `.next/dev/lock`; stop the service (or the old process)
|
||||
before starting the custom server by hand.
|
||||
- Dev-server guard check: `curl -s -o /dev/null -w '%{http_code}' \
|
||||
http://localhost:3000/__nextjs_server_status` must be `200` (localhost keeps
|
||||
debug), while the same path through the LAN IP or `beta.dvorakmortonxd.dev`
|
||||
|
|
|
|||
44
deploy/dvorakmortonxd-dev.service
Normal file
44
deploy/dvorakmortonxd-dev.service
Normal file
|
|
@ -0,0 +1,44 @@
|
|||
# User systemd service for the dvorakmortonxd.dev dev server.
|
||||
#
|
||||
# Install (no root needed, runs as the current user):
|
||||
#
|
||||
# mkdir -p ~/.config/systemd/user
|
||||
# cp deploy/dvorakmortonxd-dev.service ~/.config/systemd/user/
|
||||
# systemctl --user daemon-reload
|
||||
# systemctl --user enable --now dvorakmortonxd-dev.service
|
||||
# loginctl enable-linger "$USER" # once: start at boot without logging in
|
||||
#
|
||||
# Manage:
|
||||
# systemctl --user status dvorakmortonxd-dev
|
||||
# systemctl --user restart dvorakmortonxd-dev
|
||||
# systemctl --user stop dvorakmortonxd-dev
|
||||
# journalctl --user -u dvorakmortonxd-dev -f
|
||||
#
|
||||
# It shares .next/dev/lock with a manual `npm run dev`, so stop the service
|
||||
# before starting one by hand.
|
||||
|
||||
[Unit]
|
||||
Description=dvorakmortonxd.dev dev server (custom Next.js dev wrapper)
|
||||
Documentation=file:///home/martin/dvorakmortonxd.dev/README.md
|
||||
After=network.target
|
||||
|
||||
[Service]
|
||||
Type=simple
|
||||
WorkingDirectory=/home/martin/dvorakmortonxd.dev
|
||||
# Bind all interfaces so the Cloudflare tunnel host can reach :3000. Pin
|
||||
# HOSTNAME explicitly: the dev server reads process.env.HOSTNAME and would
|
||||
# otherwise try to bind to whatever systemd/the shell exported.
|
||||
Environment=HOSTNAME=0.0.0.0
|
||||
Environment=PORT=3000
|
||||
# A reboot can leave a stale dev lock behind; clear it before starting.
|
||||
ExecStartPre=/bin/rm -f /home/martin/dvorakmortonxd.dev/.next/dev/lock
|
||||
ExecStart=/bin/node /home/martin/dvorakmortonxd.dev/scripts/dev-server.mjs
|
||||
Restart=always
|
||||
RestartSec=3
|
||||
# Give Next.js a moment to shut down cleanly.
|
||||
TimeoutStopSec=15
|
||||
StandardOutput=journal
|
||||
StandardError=journal
|
||||
|
||||
[Install]
|
||||
WantedBy=default.target
|
||||
Loading…
Add table
Add a link
Reference in a new issue