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
- Edit the password in mariadb-grants.sql.
- Apply it as an admin:
mariadb < mariadb-grants.sql - Apply ../db/001_init.sql as an admin, not as
hundredkmph. - 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):
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:
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, so the process does not listen on a public interface.
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 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.