mirror of
https://github.com/nestriness/nestri.git
synced 2026-09-19 09:15:19 +03:00
Moving the issuer's state into Postgres removed the last thing that tied either app to one hosting provider. What was left was a deployment tool describing resources that no longer existed — so this replaces it with `wrangler`, which is what actually deploys a Worker, and adds a second way to run each app that involves no provider at all. Each app now has a `wrangler.jsonc` with an environment per stage, and a `Dockerfile` beside it. The handler is the same one in both cases; what differs is only where its settings come from. Two of them gained a second spelling so that nothing has to branch on the runtime: Postgres arrives as a pooled binding or as `DATABASE_URL`, and the route to the issuer is a service binding or `AUTH_INTERNAL_URL`. That last one is new, and it is a split the binding was already making without saying so. `AUTH_ISSUER_URL` has to be the issuer's public name, because it is compared literally against every token's `iss` claim — but the public name is often not routable from inside a deployment. So the name and the route are two settings now rather than one that cannot be both. DNS moves out of code and into `docs/dns.md`, which lists every hostname and what it is for. Six records that change roughly never did not need a tool, and the table outlives whatever is answering the names — which is the point, since some of them will stop being Workers. The sandbox hostnames are hyphenated rather than nested for the same reason: a certificate covering `*.nestri.io` covers one label and not two, so `api-sandbox.nestri.io` can become an ordinary origin later without a certificate having to be ordered for it first. Also drops `EMAIL_DEV_LOG` from committed configuration into `.dev.vars`, which `wrangler deploy` cannot upload. Printing a live sign-in code to a log should not be one forgotten override away from production.
77 lines
2.6 KiB
YAML
77 lines
2.6 KiB
YAML
# The whole control plane on one machine.
|
|
#
|
|
# Two uses, deliberately the same file. It is what a self-hoster runs, and it
|
|
# is the shape this deployment takes when it stops being a set of Workers: two
|
|
# stateless processes and a database, with a reverse proxy in front of them
|
|
# terminating TLS. Nothing here knows about a hosting provider.
|
|
#
|
|
# docker compose up --build everything, built from source
|
|
# docker compose up postgres just the database, for `bun dev`
|
|
#
|
|
# Migrations are not run for you — `bun run db:migrate` against DATABASE_URL,
|
|
# because a container that migrates on boot races with the second copy of
|
|
# itself and there is eventually a second copy.
|
|
|
|
services:
|
|
postgres:
|
|
image: docker.io/postgres:18-alpine
|
|
container_name: nestri_postgres
|
|
environment:
|
|
POSTGRES_USER: postgres
|
|
POSTGRES_PASSWORD: postgres
|
|
POSTGRES_DB: nestri
|
|
ports:
|
|
- '5432:5432'
|
|
volumes:
|
|
- nestri_data:/var/lib/postgresql
|
|
healthcheck:
|
|
test: ['CMD-SHELL', 'pg_isready -U postgres -d nestri']
|
|
interval: 5s
|
|
timeout: 5s
|
|
retries: 10
|
|
|
|
auth:
|
|
build:
|
|
# The repository root, because the lockfile and the shared packages are
|
|
# there. Same reason for both images below.
|
|
context: .
|
|
dockerfile: apps/auth/Dockerfile
|
|
container_name: nestri_auth
|
|
depends_on:
|
|
postgres:
|
|
condition: service_healthy
|
|
environment:
|
|
DATABASE_URL: postgres://postgres:postgres@postgres:5432/nestri
|
|
# Printing a live sign-in code to the log is a thing you ask for by name,
|
|
# and this file is the local machine. Set the three EMAIL_* settings
|
|
# instead and codes are delivered rather than printed.
|
|
EMAIL_DEV_LOG: 'true'
|
|
ports:
|
|
- '1337:1337'
|
|
|
|
api:
|
|
build:
|
|
context: .
|
|
dockerfile: apps/api/Dockerfile
|
|
container_name: nestri_api
|
|
depends_on:
|
|
postgres:
|
|
condition: service_healthy
|
|
auth:
|
|
condition: service_started
|
|
environment:
|
|
DATABASE_URL: postgres://postgres:postgres@postgres:5432/nestri
|
|
# The issuer's public URL, and not `http://auth:1337`. A token carries
|
|
# the address it was minted through, and verification compares the two
|
|
# literally — so the name a browser used is the only one that can appear
|
|
# here. `AUTH_INTERNAL_URL` is how this container actually gets there.
|
|
AUTH_ISSUER_URL: http://localhost:1337
|
|
AUTH_INTERNAL_URL: http://auth:1337
|
|
STEAM_API_KEY: ${STEAM_API_KEY:-}
|
|
ADMIN_SHARED_SECRET: ${ADMIN_SHARED_SECRET:-dev-admin-shared-secret-change-in-prod}
|
|
ports:
|
|
- '3000:3000'
|
|
|
|
volumes:
|
|
nestri_data:
|