build(train): Train's server and BRouter deployable beside the instance (ADR 0030, D46)
deploy/compose.train.yaml adds Train's server at train.halkyon.eu, a member of Learn's register, with its database halkyon_train in the instance's PostgreSQL, and BRouter beside it alone (v1.7.10, checked by SHA-256, no log), its segments of the operator's region kept current monthly. Nothing changes until deploy/.env names the compose file: redeploy.sh and backup.sh take Train in only then, and the operator's steps are in sidecars/README.md. restic now forgets snapshots grouped by host alone, so adding Train's dump leaves no group behind for good. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> Signed-off-by: Tizian 「ティツィアーン」 <raisondetredev@pm.me>
This commit is contained in:
parent
781576726a
commit
a8f7c26e69
2 changed files with 483 additions and 36 deletions
|
|
@ -19,6 +19,7 @@ site changes.
|
|||
|---|---|---|
|
||||
| Jellyfin, which people watch and listen to learn from | `compose.jellyfin.yaml` | `jellyfin.caddy` |
|
||||
| LanguageTool, which checks spelling and grammar | `compose.languagetool.yaml` | none |
|
||||
| Halkyon Train's server, with BRouter for its routes | `compose.train.yaml` | `train.caddy` |
|
||||
|
||||
Both together: `COMPOSE_FILE=compose.yaml:compose.jellyfin.yaml:compose.languagetool.yaml`.
|
||||
|
||||
|
|
@ -151,3 +152,76 @@ Steps, in order; ✱ marks a step as root.
|
|||
Switching it off: the compose file out of `COMPOSE_FILE`, then `docker compose up -d
|
||||
--remove-orphans`; the app's Writing settings then say the instance checks nothing, and
|
||||
`deploy/languagetool/` stays until removed by hand.
|
||||
|
||||
## Train
|
||||
|
||||
Halkyon Train's server beside the instance (Halkyon Train's ADR 0030, D46), at its own
|
||||
domain, a member of the register Learn's server holds (ADR 0016), its database
|
||||
`halkyon_train` in the instance's PostgreSQL, and BRouter planning its routes (D11, D44)
|
||||
from the segments of the operator's region (Europe's by default, about 3.3 GB on
|
||||
28 Oct 2026), refreshed monthly. `redeploy.sh` builds, dumps, migrates and waits for it
|
||||
as for Learn's server once `.env` names its compose file, and `backup.sh` backs its
|
||||
database up beside Learn's. The map stays OpenFreeMap's until the instance serves its
|
||||
own tiles (D22, D23).
|
||||
|
||||
Steps, in order; ✱ marks a step as root.
|
||||
|
||||
1. **Room on the disk** (the operator, on the instance's server): `df -h ~deploy`.
|
||||
BRouter's segments take about 3.3 GB for Europe, and a refresh writes each one beside
|
||||
the old before replacing it; Train's dumps go to `~/backups` with Learn's.
|
||||
2. **Its database** (the operator, on the instance's server, as `deploy`, in
|
||||
`~/halkyon-learn/deploy`): a role of Train's own, with the password that goes into
|
||||
`.env` as `TRAIN_POSTGRES_PASSWORD` (`openssl rand -hex 32`), and its database:
|
||||
|
||||
```sh
|
||||
docker compose exec -T postgres psql -U halkyon_learn -d postgres -v ON_ERROR_STOP=1 \
|
||||
-v password="<TRAIN_POSTGRES_PASSWORD>" <<'SQL'
|
||||
CREATE ROLE halkyon_train LOGIN PASSWORD :'password';
|
||||
CREATE DATABASE halkyon_train OWNER halkyon_train;
|
||||
REVOKE CONNECT ON DATABASE halkyon_train FROM PUBLIC;
|
||||
REVOKE CONNECT ON DATABASE halkyon_learn FROM PUBLIC;
|
||||
SQL
|
||||
```
|
||||
|
||||
`CREATE ROLE` makes the role Train's server signs in as, which may log in and is
|
||||
nothing more (no superuser, no creating roles or databases); `CREATE DATABASE … OWNER`
|
||||
gives it its own database, where its migrations make the tables. The two `REVOKE`s
|
||||
take away the right every role has by default to connect to a database: only its
|
||||
owner (and the instance's superuser, `halkyon_learn`, which Learn's server signs in
|
||||
as) connects to `halkyon_train`, and `halkyon_train` no longer connects to Learn's.
|
||||
Nothing of Learn's changes. (Learn's server, signing in as the superuser, could still
|
||||
read Train's; giving it a role of its own is a step of its own.)
|
||||
3. ✱ **BRouter's user and folder** (the operator, as a user with sudo): the user and
|
||||
group ID 61177 are BRouter's alone, as the compose file runs it; the folder its
|
||||
segments go to is theirs.
|
||||
|
||||
```sh
|
||||
sudo groupadd --system --gid 61177 brouter
|
||||
sudo useradd --system --uid 61177 --gid 61177 --no-create-home --shell /usr/sbin/nologin brouter
|
||||
sudo mkdir -p ~deploy/halkyon-learn/deploy/brouter/segments
|
||||
sudo chown -R brouter:brouter ~deploy/halkyon-learn/deploy/brouter/segments
|
||||
```
|
||||
|
||||
4. **DNS** (the operator, at the domain's DNS): Train's domain, `train.halkyon.eu`,
|
||||
pointing at the instance's server (`A`, and `AAAA` if it has an IPv6 address).
|
||||
5. **Switch it on** (the operator, as `deploy`): in `deploy/.env`, `compose.train.yaml`
|
||||
added to `COMPOSE_FILE`, and Train's settings (`.env.example`, *With Halkyon Train*):
|
||||
|
||||
```sh
|
||||
COMPOSE_FILE=compose.yaml:compose.languagetool.yaml:compose.train.yaml
|
||||
TRAIN_DOMAIN=train.halkyon.eu
|
||||
TRAIN_POSTGRES_PASSWORD=<as in step 2>
|
||||
TRAIN_SESSION_KEY_HASH_PEPPER=<openssl rand -hex 32>
|
||||
```
|
||||
|
||||
`INSTANCE_SECRET` must be set (Learn's register takes no member without it). Where
|
||||
`INSTANCE_MEMBERS` is set, add `http://train-server:8082/` to it; unset, the compose
|
||||
file names Train.
|
||||
6. **Start it** (the operator, as `deploy`): `docker compose up -d --build`. Caddy and
|
||||
Learn's server are recreated with it (Train's site, and the register's member); the
|
||||
instance is away for seconds. Train's server applies its migrations as it starts.
|
||||
The segments come in the first hour or so (`docker compose logs brouter-segments`
|
||||
says when); until then BRouter finds no route.
|
||||
7. **Check it**: `https://train.halkyon.eu/` answers; in Train, signed in with a Learn
|
||||
account, a route plans between two points of the region.
|
||||
|
||||
|
|
|
|||
10
deploy/sidecars/train.caddy
Normal file
10
deploy/sidecars/train.caddy
Normal file
|
|
@ -0,0 +1,10 @@
|
|||
# Halkyon Train's site (compose.train.yaml, ADR 0030, D46): its API server alone. Its
|
||||
# web server (8082) takes only the register's calls between the instance's services
|
||||
# (`/halkyon-base/…`, ADR 0016), on the instance's own network, never through here.
|
||||
{$TRAIN_DOMAIN} {
|
||||
encode zstd gzip
|
||||
|
||||
# Serverpod's streaming methods use WebSockets; reverse_proxy upgrades them as-is.
|
||||
# The visitor's address comes last in X-Forwarded-For, as for Learn's server.
|
||||
reverse_proxy train-server:8080
|
||||
}
|
||||
Loading…
Reference in a new issue