# syntax=docker/dockerfile:1.7 # # TRM directus service image. # # Single-stage build for Phase 1. A multi-stage build (with a Node builder for # extensions) lands in Phase 5 when TypeScript extensions are introduced. # # Artifacts baked into the image at build time: # /directus/snapshots/ — schema.yaml (generated; empty placeholder in Phase 1) # /directus/db-init/ — numbered SQL migration files (Phase 1 task 1.3 fills these) # /directus/scripts/ — shell helpers (Phase 1 tasks 1.2, 1.6 fill these) # /directus/extensions/ — TypeScript extensions (Phase 5) # /directus/entrypoint.sh — boot wrapper (real flow lands in Phase 1 task 1.7) # # No bind mounts of these directories in compose.dev.yaml — the image is the # source of truth. Reproducible across local, CI, and production environments. FROM directus/directus:11.17.4 # Switch to root only for the setup steps; Directus's upstream image already # drops to a non-root user — we preserve that for runtime. USER root # Install bash + postgresql-client. # bash: scripts/apply-db-init.sh (task 1.2) uses bash-specific # features (associative arrays, [[ ]], mapfile, # BASH_REMATCH). Alpine ships ash via BusyBox, not bash — # without this the script fails at line 1 (shebang) or # line 69 (array declaration) depending on how it's run. # postgresql16-client: provides psql + pg_isready, required by the db-init # runner. RUN apk add --no-cache bash postgresql16-client # ---- Copy baked-in artifacts ---- # Each COPY is conditional on the directory existing at build time. # .gitkeep files ensure the directories always exist so COPY never fails. COPY snapshots/ /directus/snapshots/ COPY db-init/ /directus/db-init/ COPY scripts/ /directus/scripts/ COPY extensions/ /directus/extensions/ COPY entrypoint.sh /directus/entrypoint.sh # Ensure the entrypoint is executable inside the image regardless of the host # filesystem's permission bits. RUN chmod +x /directus/entrypoint.sh # Drop back to the non-root user the upstream image uses. USER node ENTRYPOINT ["/directus/entrypoint.sh"]