2026-09-27 15:58:44 +02:00
|
|
|
# Configuration for the production instance learn.halkyon.eu.
|
|
|
|
|
# Caddy terminates TLS on 443 and forwards to the API server on 8080; only the API
|
|
|
|
|
# server runs in production.
|
2026-09-16 19:24:59 +02:00
|
|
|
|
|
|
|
|
# Configuration for the main API server.
|
|
|
|
|
apiServer:
|
|
|
|
|
port: 8080
|
2026-09-27 15:58:44 +02:00
|
|
|
publicHost: learn.halkyon.eu
|
2026-09-16 19:24:59 +02:00
|
|
|
publicPort: 443
|
|
|
|
|
publicScheme: https
|
|
|
|
|
|
2026-09-27 15:58:44 +02:00
|
|
|
# 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.
|
|
|
|
|
#
|
|
|
|
|
# No webServer: there is no web app.
|
2026-09-16 19:24:59 +02:00
|
|
|
|
feat(deploy): Docker Compose stack for the instance
Caddy, the Serverpod server and PostgreSQL 16 in deploy/. Only Caddy publishes ports; the server and Postgres are reachable only inside the Compose network (Docker bypasses ufw, and the server listens on every interface). Secrets come from deploy/.env as environment variables; there is no production passwords.yaml, and .dockerignore keeps local secrets out of the build context.
The server image builds on Serverpod's template with an Ubuntu 24.04 runtime: complete glibc incl. libgcc_s for the SQLite libraries Serverpod 4 bundles, CA certificates, a non-root user, and exec so SIGTERM reaches the server. The scaffold's dev-only docker-compose.yaml is removed.
Verified locally: image builds, all native libraries resolve, no passwords.yaml in the image, migrations apply at start, Caddy serves 200, port 8080 unreachable from the host, Postgres in UTC.
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Signed-off-by: Tizian 「ティツィアーン」 <raisondetredev@pm.me>
2026-09-27 17:18:31 +02:00
|
|
|
# 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.
|
2026-09-16 19:24:59 +02:00
|
|
|
database:
|
feat(deploy): Docker Compose stack for the instance
Caddy, the Serverpod server and PostgreSQL 16 in deploy/. Only Caddy publishes ports; the server and Postgres are reachable only inside the Compose network (Docker bypasses ufw, and the server listens on every interface). Secrets come from deploy/.env as environment variables; there is no production passwords.yaml, and .dockerignore keeps local secrets out of the build context.
The server image builds on Serverpod's template with an Ubuntu 24.04 runtime: complete glibc incl. libgcc_s for the SQLite libraries Serverpod 4 bundles, CA certificates, a non-root user, and exec so SIGTERM reaches the server. The scaffold's dev-only docker-compose.yaml is removed.
Verified locally: image builds, all native libraries resolve, no passwords.yaml in the image, migrations apply at start, Caddy serves 200, port 8080 unreachable from the host, Postgres in UTC.
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Signed-off-by: Tizian 「ティツィアーン」 <raisondetredev@pm.me>
2026-09-27 17:18:31 +02:00
|
|
|
host: postgres
|
2026-09-16 19:24:59 +02:00
|
|
|
port: 5432
|
feat(deploy): Docker Compose stack for the instance
Caddy, the Serverpod server and PostgreSQL 16 in deploy/. Only Caddy publishes ports; the server and Postgres are reachable only inside the Compose network (Docker bypasses ufw, and the server listens on every interface). Secrets come from deploy/.env as environment variables; there is no production passwords.yaml, and .dockerignore keeps local secrets out of the build context.
The server image builds on Serverpod's template with an Ubuntu 24.04 runtime: complete glibc incl. libgcc_s for the SQLite libraries Serverpod 4 bundles, CA certificates, a non-root user, and exec so SIGTERM reaches the server. The scaffold's dev-only docker-compose.yaml is removed.
Verified locally: image builds, all native libraries resolve, no passwords.yaml in the image, migrations apply at start, Caddy serves 200, port 8080 unreachable from the host, Postgres in UTC.
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Signed-off-by: Tizian 「ティツィアーン」 <raisondetredev@pm.me>
2026-09-27 17:18:31 +02:00
|
|
|
name: halkyon_learn
|
|
|
|
|
user: halkyon_learn
|
|
|
|
|
requireSsl: false
|
2026-09-16 19:24:59 +02:00
|
|
|
#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:
|
2026-09-24 15:02:52 +02:00
|
|
|
consoleEnabled: true
|
|
|
|
|
persistentEnabled: false
|
2026-09-16 19:24:59 +02:00
|
|
|
# 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
|