feat: F5.6b server F as an image: the editor from F itself, one stack per environment
F hands out the editor's page and bundle (editor/ beside main.mjs, or FILIUS_EDITOR_DIR): GET and HEAD only, one wall against leaving the folder, F's own routes first, assets/ cached a year, the rest asked for again; the build lays .br and .gz beside the files and F sends the better one the browser takes (bundle 695 KB to 212 KB). deploy/Dockerfile: two stages, Node 24, no node_modules, not root. deploy/docker-compose.yml with an env file per environment: the file sets the stack's name, volume, image tag and port (test 8081, production 8080). Measured with both stacks side by side behind nginx and Chromium. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
This commit is contained in:
@@ -0,0 +1,73 @@
|
||||
# Server F: one stack per environment, both on the same machine.
|
||||
#
|
||||
# docker compose -f deploy/docker-compose.yml --env-file deploy/test.env up -d --build
|
||||
# docker compose -f deploy/docker-compose.yml --env-file deploy/production.env up -d --build
|
||||
#
|
||||
# The environment file decides everything that tells the two apart, and it
|
||||
# does so through **names**, not through the place the command runs in:
|
||||
#
|
||||
# * `name:` is the stack's name (`filius-test`, `filius-production`). Docker
|
||||
# prefixes containers, network and volume with it, so the two stacks share
|
||||
# nothing — above all not the database. Without it, compose would take the
|
||||
# folder's name, and both stacks started from this folder would be **one**
|
||||
# stack: the second `up` would replace the first. That is also why no
|
||||
# `-p` is needed (and why forgetting one does no harm, unlike on server S).
|
||||
# * `image:` carries the stack's name as its tag. A shared tag would let a
|
||||
# build for the test environment change what production runs at its next
|
||||
# restart.
|
||||
# * The port: test 8081, production 8080, as `deploy/proxy.conf` expects.
|
||||
#
|
||||
# Needs Docker Compose v2 (`docker compose`; the old `docker-compose` 1.x
|
||||
# does not know `name:`).
|
||||
#
|
||||
# The data lies in the volume `<name>_db` (documents, sessions, blobs). It is
|
||||
# the one thing of a stack that has to be backed up:
|
||||
#
|
||||
# docker compose -f deploy/docker-compose.yml --env-file deploy/production.env \
|
||||
# exec -T db pg_dump -U filius filius > filius-production.sql
|
||||
|
||||
name: "${FILIUS_STACK:?FILIUS_STACK missing, start with --env-file deploy/<environment>.env}"
|
||||
|
||||
services:
|
||||
db:
|
||||
image: postgres:16-alpine
|
||||
restart: unless-stopped
|
||||
environment:
|
||||
POSTGRES_DB: filius
|
||||
POSTGRES_USER: filius
|
||||
POSTGRES_PASSWORD: ${FILIUS_DB_PASSWORD:?FILIUS_DB_PASSWORD missing}
|
||||
volumes:
|
||||
- db:/var/lib/postgresql/data
|
||||
healthcheck:
|
||||
test: ["CMD-SHELL", "pg_isready -U filius -d filius"]
|
||||
interval: 5s
|
||||
timeout: 5s
|
||||
retries: 12
|
||||
# No `ports:`: only F talks to its database, over the stack's network.
|
||||
|
||||
filius:
|
||||
image: mdg-filius:${FILIUS_STACK}
|
||||
build:
|
||||
context: ..
|
||||
dockerfile: deploy/Dockerfile
|
||||
restart: unless-stopped
|
||||
depends_on:
|
||||
db:
|
||||
condition: service_healthy
|
||||
environment:
|
||||
# The password goes into a URL: hex only (`openssl rand -hex 32`), a
|
||||
# `@`, `/` or `:` in it would break the URL.
|
||||
DATABASE_URL: postgres://filius:${FILIUS_DB_PASSWORD}@db:5432/filius
|
||||
FILIUS_TICKET_SECRET: ${FILIUS_TICKET_SECRET:?FILIUS_TICKET_SECRET missing}
|
||||
FILIUS_SERVICE_KEY: ${FILIUS_SERVICE_KEY:?FILIUS_SERVICE_KEY missing}
|
||||
FILIUS_ORIGINS: ${FILIUS_ORIGINS:?FILIUS_ORIGINS missing}
|
||||
ports:
|
||||
# The address the openresty reaches F on, and the stack's port.
|
||||
- "${FILIUS_BIND:?FILIUS_BIND missing}:${FILIUS_PUBLIC_PORT:?FILIUS_PUBLIC_PORT missing}:8080"
|
||||
# F stops its rooms and stores every open document before it ends
|
||||
# (main.ts, SIGTERM); Docker's 10 s are enough today, 30 s leave room
|
||||
# for a large school day.
|
||||
stop_grace_period: 30s
|
||||
|
||||
volumes:
|
||||
db:
|
||||
Reference in New Issue
Block a user