# Local development compose — builds the Directus image from this repo's source # tree and runs it alongside a TimescaleDB container. # # Use this file to verify Dockerfile changes, db-init migrations, and snapshot # apply behaviour locally before pushing. For day-to-day admin UI work you can # run `docker compose -f compose.dev.yaml up --build` and hit localhost:8055. # # For STAGE and PRODUCTION deployment, use the multi-service compose in the # sibling `deploy/` repo (https://git.dev.microservices.al/trm/deploy), which # references this service by its registry image tag instead of building locally. # # Usage: # docker compose -f compose.dev.yaml up --build # docker compose -f compose.dev.yaml down # preserves volumes # docker compose -f compose.dev.yaml down -v # wipes volumes (clean slate) # # See also: pnpm dev | pnpm dev:down | pnpm dev:reset name: directus-dev services: # --------------------------------------------------------------------------- # db — PostgreSQL 16 + TimescaleDB + PostGIS (via timescaledb-ha) # # The "-all" suffix variant bundles all extensions (TimescaleDB, PostGIS, # postgis_raster, etc.). Note: the binaries are present in the image, but # extensions still need `CREATE EXTENSION` on each database that uses them # — that's what db-init/*.sql does (Phase 1 task 1.3 + Phase 2). # # Pin a specific TS+PG version (not :pg16-latest, which doesn't exist on # Docker Hub). Bump the pin explicitly when upgrading. # # PGDATA: this image initialises Postgres at /home/postgres/pgdata/data, # not the upstream-standard /var/lib/postgresql/data and not /pgdata. # The volume mount must match exactly or initdb fails with permission errors. # --------------------------------------------------------------------------- db: image: timescale/timescaledb-ha:pg16.6-ts2.17.2-all environment: POSTGRES_USER: ${DB_USER:-directus} POSTGRES_PASSWORD: ${DB_PASSWORD:-directus} POSTGRES_DB: ${DB_DATABASE:-directus} PGDATA: /home/postgres/pgdata/data volumes: - directus-pg-data:/home/postgres/pgdata/data expose: - '5432' restart: unless-stopped healthcheck: # pg_isready reads PGUSER / PGDATABASE from env; compose sets those from # the environment block above, so no hard-coding is needed here. test: ['CMD-SHELL', 'pg_isready -U $$POSTGRES_USER -d $$POSTGRES_DB'] interval: 10s timeout: 5s start_period: 30s retries: 5 # --------------------------------------------------------------------------- # directus — built from local Dockerfile # # All env vars are read from .env (copy .env.example → .env to get started). # The service waits for db to pass its healthcheck before starting. # --------------------------------------------------------------------------- directus: build: context: . dockerfile: Dockerfile depends_on: db: condition: service_healthy ports: - '8055:8055' environment: # Database connection DB_CLIENT: ${DB_CLIENT:-pg} DB_HOST: db DB_PORT: ${DB_PORT:-5432} DB_DATABASE: ${DB_DATABASE:-directus} DB_USER: ${DB_USER:-directus} DB_PASSWORD: ${DB_PASSWORD:-directus} # Instance security — REQUIRED; set non-placeholder values in .env KEY: ${KEY} SECRET: ${SECRET} # Admin bootstrap — only applied on first init when the users table is empty ADMIN_EMAIL: ${ADMIN_EMAIL} ADMIN_PASSWORD: ${ADMIN_PASSWORD} # Public URL used in emails and OAuth redirects PUBLIC_URL: ${PUBLIC_URL:-http://localhost:8055} # Logging LOG_LEVEL: ${LOG_LEVEL:-info} LOG_STYLE: ${LOG_STYLE:-pretty} # Optional: cache, CORS, WebSockets (inherit from .env if set) CACHE_ENABLED: ${CACHE_ENABLED:-false} CORS_ENABLED: ${CORS_ENABLED:-false} CORS_ORIGIN: ${CORS_ORIGIN:-false} WEBSOCKETS_ENABLED: ${WEBSOCKETS_ENABLED:-true} volumes: # Persist Directus file uploads across container restarts. # No uploads use-case in Phase 1, but the volume is cheap to declare now. - directus-uploads:/directus/uploads restart: unless-stopped healthcheck: test: ['CMD-SHELL', 'wget -qO- http://localhost:8055/server/health || exit 1'] interval: 30s timeout: 10s start_period: 60s retries: 3 volumes: # Named volume so `down` preserves data and `down -v` wipes it. directus-pg-data: directus-uploads: