An anonymous person may keep 100 MB of images and sounds, an identified one 500 MB, and one person more by a file_allowance row the operator adds; all of them together 15 GB, since every file is in the database and in each dump the server keeps (decided 2026-10-02). Each comes from the environment (FILE_LIMIT_*_MB), with these defaults, documented in deploy/.env.example. The server checks when an upload starts, counting unfinished uploads so they can't fill the disk unnoticed, and again when it finishes, counting what is kept, so uploads started side by side can't overshoot; a refusal is a FileLimitExceededException, and an upload refused as it finishes is deleted. deletePerson deletes the allowance with the person. Migration: the new table file_allowance, only added. The app keeps a refused file waiting on the device and stops that round of uploads; the Anki import warns when a deck's files may not fit in the room left (asset.usage()). Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> Signed-off-by: Tizian 「ティツィアーン」 <raisondetredev@pm.me>
87 lines
3.3 KiB
YAML
87 lines
3.3 KiB
YAML
# The Halkyon Learn instance: Caddy in front, the Serverpod server, PostgreSQL.
|
|
#
|
|
# cd deploy
|
|
# cp .env.example .env && chmod 600 .env # then fill in the secrets
|
|
# docker compose up -d --build
|
|
#
|
|
# Only Caddy publishes ports. Docker opens published ports directly in the kernel's
|
|
# packet filter, past ufw, and the Serverpod server listens on every interface, so the
|
|
# server and Postgres publish nothing: they're reachable only inside this project's
|
|
# network, where Caddy finds the server by its service name.
|
|
|
|
name: halkyon-learn
|
|
|
|
# Logs go to the host's journal, whose size and age limits apply (journald.conf).
|
|
x-logging: &logging
|
|
driver: journald
|
|
|
|
services:
|
|
caddy:
|
|
image: caddy:2
|
|
restart: unless-stopped
|
|
ports:
|
|
- "80:80"
|
|
- "443:443"
|
|
- "443:443/udp" # HTTP/3
|
|
environment:
|
|
# `learn.halkyon.eu` on sahaquiel (automatic Let's Encrypt certificate);
|
|
# `http://localhost` for the local rehearsal (plain HTTP, no certificate).
|
|
DOMAIN: ${DOMAIN:?set DOMAIN in deploy/.env}
|
|
volumes:
|
|
- ./Caddyfile:/etc/caddy/Caddyfile:ro
|
|
- caddy_data:/data # certificates: must survive restarts (rate limits)
|
|
- caddy_config:/config
|
|
depends_on:
|
|
- server
|
|
logging: *logging
|
|
|
|
server:
|
|
build:
|
|
context: ..
|
|
dockerfile: halkyon_learn_server/Dockerfile
|
|
image: halkyon-learn-server
|
|
restart: unless-stopped
|
|
# Applies pending migrations at every start, then serves. One instance only, so
|
|
# no two servers ever migrate at once. (On learn.halkyon.eu, deploy/redeploy.sh has
|
|
# applied them in a run of their own before, so nothing is left to do here.)
|
|
command: ["--apply-migrations"]
|
|
environment:
|
|
SERVERPOD_DATABASE_PASSWORD: ${POSTGRES_PASSWORD:?set POSTGRES_PASSWORD in deploy/.env}
|
|
SERVERPOD_PASSWORD_serverSideSessionKeyHashPepper: ${SESSION_KEY_HASH_PEPPER:?set SESSION_KEY_HASH_PEPPER in deploy/.env}
|
|
# GitHub sign-in, only with this instance's GitHub OAuth app; empty: off.
|
|
SERVERPOD_PASSWORD_githubClientId: ${GITHUB_CLIENT_ID:-}
|
|
SERVERPOD_PASSWORD_githubClientSecret: ${GITHUB_CLIENT_SECRET:-}
|
|
# Where the source of what this instance runs is; empty: the project's.
|
|
SOURCE_URL: ${SOURCE_URL:-}
|
|
# How much room people's files may take, in MiB; empty: the defaults.
|
|
FILE_LIMIT_ANONYMOUS_MB: ${FILE_LIMIT_ANONYMOUS_MB:-}
|
|
FILE_LIMIT_IDENTIFIED_MB: ${FILE_LIMIT_IDENTIFIED_MB:-}
|
|
FILE_LIMIT_INSTANCE_MB: ${FILE_LIMIT_INSTANCE_MB:-}
|
|
depends_on:
|
|
postgres:
|
|
condition: service_healthy
|
|
logging: *logging
|
|
|
|
postgres:
|
|
image: postgres:16
|
|
restart: unless-stopped
|
|
# The server's session is UTC anyway (the driver sets it); this makes the
|
|
# database's own default UTC too, for psql, COPY loads and future sidecars.
|
|
command: ["postgres", "-c", "timezone=UTC", "-c", "log_timezone=UTC"]
|
|
environment:
|
|
POSTGRES_USER: halkyon_learn
|
|
POSTGRES_DB: halkyon_learn
|
|
POSTGRES_PASSWORD: ${POSTGRES_PASSWORD:?set POSTGRES_PASSWORD in deploy/.env}
|
|
volumes:
|
|
- postgres_data:/var/lib/postgresql/data
|
|
healthcheck:
|
|
test: ["CMD-SHELL", "pg_isready -U halkyon_learn -d halkyon_learn"]
|
|
interval: 5s
|
|
timeout: 5s
|
|
retries: 12
|
|
logging: *logging
|
|
|
|
volumes:
|
|
caddy_data:
|
|
caddy_config:
|
|
postgres_data:
|