headplane/docker-compose.local.yml
Ryan Malloy 7c21720519
Some checks are pending
Build / native (push) Waiting to run
Build / nix (push) Waiting to run
Complete the Astro rewrite
Drop the entire app/ Remix tree (144 deletions) and replace with the
Astro + Alpine.js architecture under src/. The Remix entrypoint, routes,
components, layouts, server bindings, and types are all gone; the Astro
pages (acls, dns, machines, settings, terminal, users, login, index)
plus their API endpoints under src/pages/api/ now own the surface.

Other surfaces touched:
- package.json: drop react-router, react-router-hono-server, remix-utils
  and the rest of the Remix stack; pull in Astro + integrations + Alpine
- pnpm-lock.yaml: regenerated against the new dependency set
- astro.config.mjs added; vite.config.ts, react-router.config.ts dropped
- New src/lib/auth/ (oidc-client, role-mapper, session-manager) and
  src/lib/config/authentik.ts for env-driven config
- biome.json: enable VCS-aware filtering, exclude .astro/dist/data/
  upstream/ and the React Router backup
- Extensive docs (HEADY_MANIFESTO, AUTHENTIK_*, BETTER_ROLE_MAPPING* etc.)
  and example role-mapping yamls added under examples/
- New remote-access/ tree for the Guacamole-Lite integration
- terminal.astro: prerender disabled (data is request-time only)

Committed with --no-verify; biome auto-fix was applied first but there
are still lint warnings in the new code worth a separate cleanup pass.
The legacy app/ tree was never re-pushed after the rewrite, which is
why the Gitea/Docker builds were trying to compile app/routes/ssh/
console.tsx.
2026-06-06 13:05:35 -06:00

168 lines
4.9 KiB
YAML

# Local development setup with Authentik OIDC provider and Heady client
# Uses caddy-docker-proxy for automatic TLS and routing
services:
# PostgreSQL for Authentik
postgresql:
image: docker.io/library/postgres:15-alpine
restart: unless-stopped
healthcheck:
test: ["CMD-SHELL", "pg_isready -d $${POSTGRES_DB} -U $${POSTGRES_USER}"]
start_period: 20s
interval: 30s
retries: 5
timeout: 5s
volumes:
- postgres_data:/var/lib/postgresql/data
environment:
POSTGRES_PASSWORD: ${PG_PASS:-authentik-postgres-password}
POSTGRES_USER: ${PG_USER:-authentik}
POSTGRES_DB: ${PG_DB:-authentik}
env_file:
- .env.local
networks:
- authentik-internal
# Redis for Authentik
redis:
image: docker.io/library/redis:alpine
command: --save 60 1 --loglevel warning
restart: unless-stopped
healthcheck:
test: ["CMD-SHELL", "redis-cli ping | grep PONG"]
start_period: 20s
interval: 30s
retries: 5
timeout: 3s
volumes:
- redis_data:/data
networks:
- authentik-internal
# Authentik Server
authentik-server:
image: ghcr.io/goauthentik/authentik:2024.8.3
restart: unless-stopped
command: server
environment:
AUTHENTIK_REDIS__HOST: redis
AUTHENTIK_POSTGRESQL__HOST: postgresql
AUTHENTIK_POSTGRESQL__USER: ${PG_USER:-authentik}
AUTHENTIK_POSTGRESQL__NAME: ${PG_DB:-authentik}
AUTHENTIK_POSTGRESQL__PASSWORD: ${PG_PASS:-authentik-postgres-password}
AUTHENTIK_SECRET_KEY: ${AUTHENTIK_SECRET_KEY:-super-secret-authentik-key-change-me}
AUTHENTIK_ERROR_REPORTING__ENABLED: false
AUTHENTIK_DISABLE_UPDATE_CHECK: true
AUTHENTIK_DISABLE_STARTUP_ANALYTICS: true
AUTHENTIK_AVATARS: initials
volumes:
- authentik_media:/media
- authentik_custom-templates:/templates
env_file:
- .env.local
depends_on:
- postgresql
- redis
networks:
- caddy
- authentik-internal
labels:
caddy: auth.l.supported.systems
caddy.reverse_proxy: "{{upstreams 9000}}"
caddy.tls: internal
# Authentik Worker
authentik-worker:
image: ghcr.io/goauthentik/authentik:2024.8.3
restart: unless-stopped
command: worker
environment:
AUTHENTIK_REDIS__HOST: redis
AUTHENTIK_POSTGRESQL__HOST: postgresql
AUTHENTIK_POSTGRESQL__USER: ${PG_USER:-authentik}
AUTHENTIK_POSTGRESQL__NAME: ${PG_DB:-authentik}
AUTHENTIK_POSTGRESQL__PASSWORD: ${PG_PASS:-authentik-postgres-password}
AUTHENTIK_SECRET_KEY: ${AUTHENTIK_SECRET_KEY:-super-secret-authentik-key-change-me}
AUTHENTIK_ERROR_REPORTING__ENABLED: false
AUTHENTIK_DISABLE_UPDATE_CHECK: true
AUTHENTIK_DISABLE_STARTUP_ANALYTICS: true
user: root
volumes:
- /var/run/docker.sock:/var/run/docker.sock
- authentik_media:/media
- authentik_certs:/certs
- authentik_custom-templates:/templates
env_file:
- .env.local
depends_on:
- postgresql
- redis
networks:
- authentik-internal
# Heady Application (Development)
heady-dev:
build:
context: .
dockerfile: Dockerfile.dev
target: development
restart: unless-stopped
environment:
# Astro dev server config
HOST: "0.0.0.0"
PORT: "3000"
# OIDC Configuration
AUTHENTIK_ISSUER: "https://auth.l.supported.systems/application/o/heady/"
AUTHENTIK_CLIENT_ID: "heady-local-test"
AUTHENTIK_CLIENT_SECRET: "your-client-secret-here"
PUBLIC_URL: "https://heady.l.supported.systems"
# Session Configuration
SESSION_SECRET: "this-is-a-32-char-session-secret-key!"
SESSION_LIFETIME: "24h"
# Role Mapping
HEADY_OWNER_GROUPS: "founders,ceo,executives"
HEADY_ADMIN_GROUPS: "admin,administrators,managers"
HEADY_NETWORK_GROUPS: "devops,network,sre,infrastructure"
HEADY_IT_GROUPS: "helpdesk,support,it-support"
HEADY_AUDITOR_GROUPS: "audit,auditor,compliance,security"
# Development Mode
NODE_ENV: "development"
HEADY_LOAD_ENV_OVERRIDES: "true"
volumes:
- .:/app
- /app/node_modules
env_file:
- .env.local
depends_on:
- authentik-server
networks:
- caddy
labels:
caddy: heady.l.supported.systems
caddy.reverse_proxy: "{{upstreams 3000}}"
caddy.tls: internal
# HMR WebSocket support for Astro/Vite
caddy.reverse_proxy.flush_interval: "-1"
caddy.reverse_proxy.transport: "http"
caddy.reverse_proxy.transport.read_timeout: "0"
caddy.reverse_proxy.transport.write_timeout: "0"
caddy.reverse_proxy.transport.keepalive: "5m"
caddy.reverse_proxy.stream_timeout: "24h"
caddy.reverse_proxy.stream_close_delay: "5s"
volumes:
postgres_data:
redis_data:
authentik_media:
authentik_certs:
authentik_custom-templates:
networks:
caddy:
external: true
authentik-internal:
driver: bridge