# syntax=docker/dockerfile:1 # Build stage: compile Sass and assemble the allowlisted dist/ folder. # config.php never enters the image (.dockerignore), and build-dist.js # doesn't copy it anyway. FROM node:24-alpine AS build WORKDIR /src COPY package.json package-lock.json ./ RUN npm ci COPY . . RUN npm run dist # Runtime stage. Production php.ini and expose_php = Off are baked in here, # replacing the startup `command:` in docker-compose.yaml. Files are owned # by root with 644/755 (normalized by build-dist.js), so www-data can read # the site but not modify it; data/ and config/ arrive as mounts. FROM php:8.5-apache RUN cp "$PHP_INI_DIR/php.ini-production" "$PHP_INI_DIR/php.ini" \ && printf 'expose_php = Off\n' > "$PHP_INI_DIR/conf.d/zz-hardening.ini" COPY --from=build /src/dist/ /var/www/html/