Files
2026-09-28 23:15:47 +05:30

59 lines
2.1 KiB
Markdown

# Deploy 100kmph web on Debian 12
Apache and MariaDB are already on the box. Add Node.js 20 LTS. The Next process listens on `127.0.0.1:3000` only. Apache is the public front. Do not open port 3000.
## MariaDB
1. Edit the password in [mariadb-grants.sql](mariadb-grants.sql).
2. Apply it as an admin: `mariadb < mariadb-grants.sql`
3. Apply [../db/001_init.sql](../db/001_init.sql) as an admin, not as `hundredkmph`.
4. Do not enable remote root.
The app user gets `SELECT`, `INSERT`, and `UPDATE` on `hundredkmph` from `localhost` only.
## App process
Build on the server (or copy a build from a machine with the same Node major version):
```sh
cd /opt/hundredkmph/src/web
npm ci
npm run build
mkdir -p /opt/hundredkmph/web
rm -rf /opt/hundredkmph/web/*
cp -a .next/standalone/. /opt/hundredkmph/web/
mkdir -p /opt/hundredkmph/web/.next
cp -a .next/static /opt/hundredkmph/web/.next/static
```
Create a system user and a root-only env file:
```sh
useradd --system --home /opt/hundredkmph/web --shell /usr/sbin/nologin hundredkmph
install -d -m 0750 -o root -g root /etc/hundredkmph
install -m 0600 -o root -g root /dev/null /etc/hundredkmph/web.env
```
`/etc/hundredkmph/web.env` contains only:
```
DATABASE_URL=mysql://hundredkmph:THE_PASSWORD@127.0.0.1:3306/hundredkmph
SYNC_TOKEN=a-long-random-secret
```
systemd reads that file as root before dropping to `hundredkmph`. `HOSTNAME=127.0.0.1` and `PORT=3000` are set in [hundredkmph-web.service](hundredkmph-web.service), so the process does not listen on a public interface.
```sh
cp hundredkmph-web.service /etc/systemd/system/hundredkmph-web.service
systemctl daemon-reload
systemctl enable --now hundredkmph-web
```
`npm start` is the non-standalone equivalent: `next start -H 127.0.0.1 -p 3000`.
## Apache
Leave the existing TLS virtual host in place. Enable `proxy` and `proxy_http`, then include [apache-hundredkmph.conf](apache-hundredkmph.conf) inside that virtual host. WebSocket upgrade is not required.
`mod_proxy` appends the client address to `X-Forwarded-For`. The status lookup uses the last address in that header.