init
This commit is contained in:
@@ -0,0 +1,58 @@
|
||||
# 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.
|
||||
@@ -0,0 +1,7 @@
|
||||
# Include this inside the existing Apache virtual host.
|
||||
# Do not add a public Listen for Node. TLS stays on Apache.
|
||||
# Requires: a2enmod proxy proxy_http
|
||||
|
||||
ProxyPreserveHost On
|
||||
ProxyPass / http://127.0.0.1:3000/
|
||||
ProxyPassReverse / http://127.0.0.1:3000/
|
||||
@@ -0,0 +1,19 @@
|
||||
[Unit]
|
||||
Description=100kmph front desk
|
||||
After=network.target mariadb.service
|
||||
|
||||
[Service]
|
||||
Type=simple
|
||||
User=hundredkmph
|
||||
Group=hundredkmph
|
||||
WorkingDirectory=/opt/hundredkmph/web
|
||||
Environment=NODE_ENV=production
|
||||
Environment=HOSTNAME=127.0.0.1
|
||||
Environment=PORT=3000
|
||||
EnvironmentFile=/etc/hundredkmph/web.env
|
||||
ExecStart=/usr/bin/node /opt/hundredkmph/web/server.js
|
||||
Restart=on-failure
|
||||
NoNewPrivileges=true
|
||||
|
||||
[Install]
|
||||
WantedBy=multi-user.target
|
||||
@@ -0,0 +1,16 @@
|
||||
-- Run as an admin, before the app starts.
|
||||
-- Do not create a remote root, and do not grant this user '@'%'.
|
||||
-- The app user cannot DELETE and cannot apply DDL.
|
||||
-- Soft-delete is an UPDATE of deleted_at.
|
||||
-- Replace the password, then: chmod 600 this file if you fill in a real password.
|
||||
|
||||
CREATE DATABASE IF NOT EXISTS hundredkmph CHARACTER SET utf8mb4 COLLATE utf8mb4_unicode_ci;
|
||||
|
||||
CREATE USER IF NOT EXISTS 'hundredkmph'@'localhost' IDENTIFIED BY 'replace-with-a-long-random-password';
|
||||
|
||||
GRANT SELECT, INSERT, UPDATE ON hundredkmph.* TO 'hundredkmph'@'localhost';
|
||||
|
||||
FLUSH PRIVILEGES;
|
||||
|
||||
-- Then apply the migration as an admin (the app user cannot):
|
||||
-- mariadb hundredkmph < /opt/hundredkmph/src/web/db/001_init.sql
|
||||
Reference in New Issue
Block a user