halkyon/apps/learn/halkyon_learn_server/config/production.yaml
Tizian 「ティツィアーン」 8d6785f5c6
feat(base): SimpleLogin's forwarding page and Learn's App Links statement (ADR 0020, step 1)
SimpleLogin takes only https redirect addresses, each registered exactly,
so the instance's SimpleLogin app registers one page on the register's
web server, /simplelogin-callback, which sends the browser on to the app
that began the sign-in: a 303 to the desktop's loopback (127.0.0.1, a port
per app) or the phone's scheme, chosen by the marker the state begins with
(`<app>-<platform>.<rest>`, the rest 1 to 512 characters of base64url),
from a fixed table, so it sends nobody anywhere else. It forwards the code
or SimpleLogin's error (`deny`) with the state and nothing else, refuses
anything malformed, repeated or not a GET with a page that repeats nothing
it was given, and keeps and logs nothing (no-store, no referrer). It is
built ahead of the sign-in itself so development can sign in through
learn.halkyon.eu's page, which the development app registers too.

Android's assetlinks.json for Halkyon Learn signed with the release key
is answered by the Caddyfile on learn.halkyon.eu alone: the one domain the
project's builds name, and the server knows no app's key. A root test
holds its fingerprint to tool/release/android-certificate.sha256. The
app's intent filter comes with the sign-in; iOS's association waits for
an Apple team ID.

The profile page's language choice and look move to common/web_page.dart,
shared by both pages.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Signed-off-by: Tizian 「ティツィアーン」 <raisondetredev@pm.me>
2026-10-23 17:48:31 +02:00

79 lines
3.2 KiB
YAML

# Configuration for the production instance learn.halkyon.eu.
# Caddy terminates TLS on 443 and forwards to the API server on 8080, and the
# web server's paths to it on 8082; Insights doesn't run.
# Configuration for the main API server.
apiServer:
port: 8080
publicHost: learn.halkyon.eu
publicPort: 443
publicScheme: https
# No insightsServer: without this block Serverpod doesn't start Insights at all (it
# would otherwise listen on every interface). To use Insights later, add the block
# back (port 8081), set `serviceSecret` in the production passwords, and reach the
# port through an SSH tunnel, never through Caddy.
# The web server serves profile pages (ADR 0011), the dictionaries devices
# download (ADR 0012), SimpleLogin's forwarding page (ADR 0020) and the calls
# between the instance's services (ADR 0016). Caddy forwards the paths of the
# first three alone to it (deploy/Caddyfile), never the last; everything else
# stays on the API server.
webServer:
port: 8082
publicHost: learn.halkyon.eu
publicPort: 443
publicScheme: https
# The database: the `postgres` service of deploy/compose.yaml, reachable only inside
# the Compose network (it publishes no port), so no TLS between server and database.
# The password comes from the environment (SERVERPOD_DATABASE_PASSWORD, set in
# deploy/.env); there is no production passwords.yaml.
database:
host: postgres
port: 5432
name: halkyon_learn
user: halkyon_learn
requireSsl: false
#isUnixSocket: true # defaults to false
#maxConnectionCount: 10 # Defaults to 10, a negative or null value removes the limit
# This is the setup for Redis. The default for the Google Cloud Engine Terraform
# configuration is to connect on a private IP address.
# If you are connecting on a public IP (e.g. on AWS or Google Cloud Run), you
# connect on the public IP of the database e.g. redis.examplepod.com.
redis:
enabled: false
host: redis.private-production.examplepod.com
port: 6379
#user: # defaults to empty
#requireSsl: true # defaults to false
maxRequestSize: 524288 # The maximum size of requests allowed in bytes
sessionLogs:
consoleEnabled: true
persistentEnabled: false
# consoleLogFormat: json # Defaults to "json", options are "text" or "json"
# futureCallExecutionEnabled: true # Defaults to true
#futureCall:
# concurrencyLimit: 1 # Defaults to 1, a negative or null value removes the limit
# scanInterval: 5000 # Unit in milliseconds, defaults to 5000
# Recommended when serving web clients: keeps auth tokens in httpOnly
# cookies. Without this, web tokens live in JavaScript-readable storage,
# where any XSS can steal them. Web clients opt in with
# `client.cookieAuth = true`. Requires `allowedOrigins`; browsers from
# origins not in the list lose cross-origin access, including to public
# endpoints.
#authCookie:
# sameSite: lax # Defaults to "lax", options are "strict" or "none"
# #name: serverpod_auth # Defaults to "serverpod_auth"
# #refreshName: serverpod_auth_refresh # Defaults to "<name>_refresh"
# #domain: examplepod.com # Defaults to host-only; set to share across subdomains
# #path: / # Defaults to "/"
# #secure: true # Defaults to true; the cookie is only sent over https
#allowedOrigins:
# - https://app.examplepod.com # The origin serving your Flutter web app