Step 2 of the build order. The admin mints an invite link, the recipient registers with it, and from then on has a session. - The invite is spent in the same transaction that creates the account, so a failed signup leaves the code usable - Sessions are idle timeouts, 24h or 30 days with remember me, read from a cookie or a bearer header, extended at most once a minute - Ban is a reversible toggle that drops the member's live sessions - No password minimum; login is rate limited instead, 10 failures per email in 15 minutes, cleared by a correct password - Invite codes render as links carrying ?code=, which the register form prefills; PUBLIC_URL makes them pasteable from the loopback admin panel Tests cover invite spending, the idle timeout, ban, and the rate limiter.
40 lines
1.3 KiB
YAML
40 lines
1.3 KiB
YAML
services:
|
|
postgres:
|
|
image: postgres:18-alpine
|
|
environment:
|
|
POSTGRES_USER: levyraati
|
|
POSTGRES_PASSWORD: ${POSTGRES_PASSWORD:?set POSTGRES_PASSWORD in .env}
|
|
POSTGRES_DB: levyraati
|
|
volumes:
|
|
# Postgres 18 keeps its data in /var/lib/postgresql/<version>/docker, so the mount is the
|
|
# parent directory, not the old /var/lib/postgresql/data.
|
|
- ./pgdata:/var/lib/postgresql
|
|
healthcheck:
|
|
test: ["CMD-SHELL", "pg_isready -U levyraati"]
|
|
interval: 5s
|
|
timeout: 3s
|
|
retries: 10
|
|
restart: unless-stopped
|
|
|
|
app:
|
|
build: .
|
|
environment:
|
|
DATABASE_URL: postgres://levyraati:${POSTGRES_PASSWORD}@postgres:5432/levyraati
|
|
ADMIN_USER: ${ADMIN_USER:-admin}
|
|
ADMIN_PASSWORD: ${ADMIN_PASSWORD:?set ADMIN_PASSWORD in .env}
|
|
ADDR: ":8080"
|
|
# Inside the container the admin listener must bind the container's own interface; it is not
|
|
# published below, so it stays unreachable from outside without a tunnel or the proxy.
|
|
ADMIN_ADDR: ":8081"
|
|
SECURE_COOKIES: ${SECURE_COOKIES:-true}
|
|
PUBLIC_URL: ${PUBLIC_URL:-}
|
|
volumes:
|
|
- ./storage:/storage
|
|
ports:
|
|
- "8080:8080"
|
|
- "8081:8081"
|
|
depends_on:
|
|
postgres:
|
|
condition: service_healthy
|
|
restart: unless-stopped
|