release gate / check (push) Failing after 6m43s
High severity: - wire TRUSTED_PROXY through Compose/deploy/docs and warn at web startup - bucket public rate limits on effective client IP, add per-bookmark budget, and forward the signed browser identity from the share page - disable first-run bootstrap in server deployments and document seeding - serialize last-admin demotion in one advisory-locked transaction Medium/low: - cap and batch share recipient inserts - add a shared outbound budget for preview/CardDAV/IMAP/signal work - pin CardDAV dials to 443 and bound IMAP logout - fix rightward kanban column drags and normalize cards on column delete - classify backend outages in auth guards, add request timeouts and an error boundary, remove the dead login route, surface throttling - enforce pinned/unpinned page reorder grouping server-side - avoid preview work for stale bookmark versions; drop duplicate dialog fetch - sequence-guard collection/tag/calendar/quick-find loads - validate property config and fix MULTI_SELECT/DATE filter inputs - document index maintenance; apply same-origin check to sign-out - trim signup names, unique shared dates and kanban keys (migration 010), reset reference cache on identity changes, hide OIDC issuer, return 413 for oversized direct bodies, escape Markdown link destinations - remove dead template files and duplicate test helper Verified with go build/vet, full PostgreSQL race suite, db convergence, tsc, both ESLint configs and a Next production build.
149 lines
4.9 KiB
YAML
149 lines
4.9 KiB
YAML
name: computer
|
|
services:
|
|
db:
|
|
image: postgres:16.15-alpine
|
|
restart: unless-stopped
|
|
environment:
|
|
POSTGRES_DB: computer
|
|
POSTGRES_USER: computer
|
|
POSTGRES_PASSWORD: ${POSTGRES_PASSWORD:?Set POSTGRES_PASSWORD in .env}
|
|
volumes:
|
|
- pgdata:/var/lib/postgresql/data
|
|
- ./db/schema.sql:/docker-entrypoint-initdb.d/01-schema.sql:ro
|
|
healthcheck:
|
|
test: [CMD-SHELL, pg_isready -h 127.0.0.1 -U computer -d computer]
|
|
interval: 3s
|
|
timeout: 3s
|
|
retries: 20
|
|
networks: [backend]
|
|
|
|
migrate:
|
|
image: postgres:16.15-alpine
|
|
restart: "no"
|
|
depends_on:
|
|
db: {condition: service_healthy}
|
|
environment:
|
|
PGPASSWORD: ${POSTGRES_PASSWORD:?Set POSTGRES_PASSWORD in .env}
|
|
DB_HOST: db
|
|
DB_USER: computer
|
|
DB_NAME: computer
|
|
volumes:
|
|
- ./db:/db:ro
|
|
command: [sh, /db/migrate.sh]
|
|
networks: [backend]
|
|
|
|
app:
|
|
build: .
|
|
restart: unless-stopped
|
|
depends_on:
|
|
migrate: {condition: service_completed_successfully}
|
|
environment:
|
|
DATABASE_URL: postgres://computer:${POSTGRES_PASSWORD:?Set POSTGRES_PASSWORD in .env}@db:5432/computer?sslmode=disable
|
|
AUTH_SECRET: ${AUTH_SECRET:?Set AUTH_SECRET in .env}
|
|
NEXTAUTH_SECRET: ${AUTH_SECRET}
|
|
# Optional dedicated key for stored integration credentials (review
|
|
# OPS-01): rotating AUTH_SECRET no longer invalidates IMAP passwords
|
|
# when ENCRYPTION_KEY is set. Back it up with the database.
|
|
ENCRYPTION_KEY: ${ENCRYPTION_KEY:-}
|
|
NEXTAUTH_URL: ${NEXTAUTH_URL:-http://localhost:3000}
|
|
ADMIN_EMAILS: ${ADMIN_EMAILS:-}
|
|
# Review H-3: these must reach the Go container, not just .env. An empty
|
|
# value keeps local defaults (bootstrap enabled, signup open).
|
|
ALLOW_BOOTSTRAP_SIGNUP: ${ALLOW_BOOTSTRAP_SIGNUP:-}
|
|
SIGNUP_ENABLED: ${SIGNUP_ENABLED:-}
|
|
COOKIE_SECURE: ${COOKIE_SECURE:-}
|
|
OIDC_ISSUER: ${OIDC_ISSUER:-}
|
|
OIDC_CLIENT_ID: ${OIDC_CLIENT_ID:-}
|
|
OIDC_CLIENT_SECRET: ${OIDC_CLIENT_SECRET:-}
|
|
ports: ["127.0.0.1:${APP_HOST_PORT:-8080}:8080"]
|
|
healthcheck:
|
|
test: [CMD, /computer, --healthcheck]
|
|
interval: 3s
|
|
timeout: 4s
|
|
retries: 20
|
|
read_only: true
|
|
cap_drop: [ALL]
|
|
security_opt: [no-new-privileges:true]
|
|
networks: [backend]
|
|
|
|
web:
|
|
build: ./web
|
|
restart: unless-stopped
|
|
depends_on:
|
|
app: {condition: service_healthy}
|
|
environment:
|
|
API_BASE_URL: http://app:8080
|
|
AUTH_SECRET: ${AUTH_SECRET}
|
|
NEXTAUTH_SECRET: ${AUTH_SECRET}
|
|
NEXTAUTH_URL: ${NEXTAUTH_URL:-http://localhost:3000}
|
|
AUTH_TRUST_HOST: "true"
|
|
# Review H-1: opt in only when a proxy in front of web pins X-Real-IP
|
|
# (the shipped nginx template does; scripts/server-deploy.sh sets it).
|
|
# Leave unset when port 3000 is browser-reachable directly, otherwise
|
|
# clients can spoof their rate-limit identity.
|
|
TRUSTED_PROXY: ${TRUSTED_PROXY:-}
|
|
OIDC_ISSUER: ${OIDC_ISSUER:-}
|
|
OIDC_CLIENT_ID: ${OIDC_CLIENT_ID:-}
|
|
OIDC_CLIENT_SECRET: ${OIDC_CLIENT_SECRET:-}
|
|
ports: ["127.0.0.1:${WEB_HOST_PORT:-3000}:3000"]
|
|
read_only: true
|
|
tmpfs: [/tmp]
|
|
cap_drop: [ALL]
|
|
security_opt: [no-new-privileges:true]
|
|
healthcheck:
|
|
# busybox wget from the alpine base; /login renders without a session.
|
|
test: ["CMD", "wget", "-q", "-O", "/dev/null", "http://127.0.0.1:3000/login"]
|
|
interval: 10s
|
|
timeout: 4s
|
|
retries: 3
|
|
start_period: 20s
|
|
networks: [backend]
|
|
|
|
tests:
|
|
profiles: [test]
|
|
# Debian-based (not alpine): -race requires cgo, which needs gcc.
|
|
# Keep the Go version in lockstep with the app Dockerfile.
|
|
image: golang:1.26.1
|
|
depends_on:
|
|
db: {condition: service_healthy}
|
|
working_dir: /src
|
|
# Mount only what `go test ./internal/...` needs — notably NOT the repo
|
|
# root, so the real .env (AUTH_SECRET, POSTGRES_PASSWORD) never reaches
|
|
# the test process; tests set their own secrets via t.Setenv.
|
|
volumes:
|
|
- ./go.mod:/src/go.mod:ro
|
|
- ./go.sum:/src/go.sum:ro
|
|
- ./internal:/src/internal:ro
|
|
- ./db:/src/db:ro
|
|
tmpfs: ["/tmp:exec"]
|
|
environment:
|
|
TEST_DATABASE_URL: postgres://computer:${POSTGRES_PASSWORD:?Set POSTGRES_PASSWORD in .env}@db:5432/computer?sslmode=disable
|
|
GOCACHE: /tmp/go-cache
|
|
GOMODCACHE: /tmp/go-mod
|
|
command: [go, test, -race, -count=1, -v, ./internal/...]
|
|
networks: [backend]
|
|
|
|
# Fails when db/schema.sql drifts from the migration chain (review MIG-03).
|
|
converge:
|
|
profiles: [test]
|
|
image: postgres:16.15-alpine
|
|
restart: "no"
|
|
depends_on:
|
|
db: {condition: service_healthy}
|
|
environment:
|
|
PGPASSWORD: ${POSTGRES_PASSWORD:?Set POSTGRES_PASSWORD in .env}
|
|
DB_HOST: db
|
|
DB_USER: computer
|
|
volumes:
|
|
- ./db:/db:ro
|
|
command: [sh, /db/check-convergence.sh]
|
|
networks: [backend]
|
|
|
|
volumes:
|
|
pgdata:
|
|
name: ${POSTGRES_VOLUME:-computer_pgdata}
|
|
external: ${POSTGRES_VOLUME_EXTERNAL:-false}
|
|
networks:
|
|
backend:
|
|
driver: bridge
|