build: M1 Dockerized development stack with PHP skeleton, config/logging, Tailwind assets, and wrappers

Implements MeshVault M1 (issues #6–11):

- Four-service Docker Compose stack (nginx, PHP-FPM 8.3, PostgreSQL 17, Node assets)
- Slim 4 + PHP-DI routing with escaped PHP views and production/dev error handling
- Immutable validated AppConfig with redacted diagnostics
- JSON stdout Monolog logging with job-scoped context
- Tailwind CSS v4 deterministic locked builds with template scanning
- POSIX and PowerShell dev wrappers (up/down/test/lint/assets/watch)
- Startup config validation fails before FPM serves as unprivileged www-data
- migrate/seed explicitly unavailable until M2 (#12); #10 remains open

Verified via clean-start acceptance on remote host (keith@192.168.2.23).
This commit is contained in:
Keith Solomon committed 2026-10-11 16:45:45 -05:00
1 parent c2747a5762
commit d3e8cf8fae
39 files changed
+5291 -38

No files matched your search

+20
View File
@@ -0,0 +1,20 @@
FROM php:8.3-fpm-bookworm
RUN apt-get update && apt-get install -y --no-install-recommends libonig-dev libxml2-dev unzip \
&& docker-php-ext-install mbstring dom \
&& rm -rf /var/lib/apt/lists/*
COPY --from=composer:2 /usr/bin/composer /usr/local/bin/composer
WORKDIR /var/www/html
# Dependencies are Linux-native and rebuilt from the lock, never host-mounted.
COPY composer.json composer.lock ./
RUN composer install --no-interaction --prefer-dist --no-progress
COPY bin ./bin
COPY docker/php/entrypoint.sh /usr/local/bin/meshvault-entrypoint
COPY docker/php/zz-meshvault.conf /usr/local/etc/php-fpm.d/zz-meshvault.conf
RUN chmod 755 /usr/local/bin/meshvault-entrypoint
RUN mkdir -p /var/www/html/.phpunit.cache && chown www-data:www-data /var/www/html/.phpunit.cache
# The entire FPM process runs as the same identity used for library checks.
USER www-data
ENTRYPOINT ["meshvault-entrypoint"]
CMD ["php-fpm"]
+11
View File
@@ -0,0 +1,11 @@
#!/bin/sh
set -eu
# Image and Compose both select www-data; validation and FPM inherit this identity.
if [ "$1" = "php-fpm" ]; then
if [ "$(id -u)" = 0 ]; then
echo 'Refusing to validate or serve FPM as root; use www-data.' >&2
exit 1
fi
php /var/www/html/bin/check-config.php
fi
exec docker-php-entrypoint "$@"
+7
View File
@@ -0,0 +1,7 @@
[www]
; Preserve explicit Compose settings and forward Monolog JSON without prefixes.
clear_env = no
catch_workers_output = yes
decorate_workers_output = no
php_admin_flag[log_errors] = on
php_admin_flag[display_errors] = off