Task 1.1 — Project scaffold
Phase 1 task 1.1 lands. Directus 11.17.4 boots locally end-to-end against a TimescaleDB+PostGIS container; admin UI serves at :8055, admin bootstrap from env vars works, named volumes preserve data across down/up cycles. Scaffold: - Dockerfile — FROM directus/directus:11.17.4. Pre-installs postgresql16-client (ahead of task 1.2's db-init runner needing psql). Bakes in /directus/snapshots, /directus/db-init, /directus/scripts, /directus/extensions, /directus/entrypoint.sh. - compose.dev.yaml — db (timescale/timescaledb-ha:pg16.6-ts2.17.2-all) + directus (local build), healthchecks, named volumes directus-pg-data + directus-uploads. - entrypoint.sh — placeholder using upstream's actual flow (node cli.js bootstrap && pm2-runtime start ecosystem.config.cjs); the real db-init -> schema apply -> start wrapper lands in task 1.7. - package.json — scripts-only (dev, dev:down, dev:reset, schema:snapshot, schema:apply, db:init), no runtime deps. - .env.example — sectioned, fully documented, KEY/SECRET marked required with generation hints. - .gitignore, .dockerignore — match the processor service conventions. - snapshots/, db-init/, scripts/, extensions/ — empty with .gitkeep, filled by later Phase 1 tasks (1.3, 1.6) and Phase 5. Lessons locked in (against the empirical pnpm dev boot): - timescale/timescaledb-ha:pg16-latest does NOT exist on Docker Hub. Pin a concrete version (we used pg16.6-ts2.17.2-all). - This image's data directory is /home/postgres/pgdata/data, not /pgdata or /var/lib/postgresql/data. PGDATA env var and the volume mount must both target it. - The -all variant bundles PostGIS binaries but the extension is not auto-created on the directus database; CREATE EXTENSION lands in Phase 2 alongside the geofences/SLZs/waypoints collections. - The upstream image's CMD is bootstrap + pm2-runtime, not a simple cli.js start. Bypassing pm2 would lose crash recovery. These corrections folded into 01-project-scaffold.md (deliverable line + Done section), 08-gitea-ci-dryrun.md (CI service tag), and the inline comments in compose.dev.yaml so future implementers don't re-discover them. Status: ROADMAP marks 1.1 done, Phase 1 in progress, 1.2 next.
This commit is contained in:
@@ -0,0 +1,120 @@
|
||||
# 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:
|
||||
Reference in New Issue
Block a user