diff --git a/Dockerfile b/Dockerfile index a286923..97fccca 100644 --- a/Dockerfile +++ b/Dockerfile @@ -8,7 +8,67 @@ FROM dunglas/frankenphp:1.11-php8.5 AS frankenphp_upstream # https://docs.docker.com/compose/compose-file/#target -# Base FrankenPHP image +# --------------------------------------------------------------- +# Builder: install prod vendor, dump autoload, warm Symfony cache +# --------------------------------------------------------------- +FROM frankenphp_upstream AS php_builder + +WORKDIR /app + +ENV COMPOSER_ALLOW_SUPERUSER=1 \ + APP_ENV=prod + +# hadolint ignore=DL3008 +RUN apt-get update && apt-get install -y --no-install-recommends \ + git \ + && apt-get clean \ + && rm -rf /var/lib/apt/lists/* + +RUN install-php-extensions \ + @composer \ + intl \ + pdo_mysql \ + zip \ + ; + +# Install dependencies first so the layer is cached when only sources change +COPY --link composer.* symfony.* ./ +RUN --mount=type=cache,target=/tmp/composer-cache \ + COMPOSER_CACHE_DIR=/tmp/composer-cache \ + composer install --prefer-dist --no-dev --no-autoloader --no-scripts --no-progress + +COPY --link --exclude=frankenphp/ . ./ + +RUN set -eux; \ + mkdir -p var/cache var/log var/share; \ + composer dump-autoload --classmap-authoritative --no-dev; \ + composer dump-env prod; \ + chmod +x bin/console; \ + sync + + +# --------------------------------------------------------------- +# Builder: compile frontend assets via webpack-encore +# --------------------------------------------------------------- +FROM node:24-alpine AS node_builder + +WORKDIR /app + +# package.json references "file:vendor/symfony/ux-react/assets" +COPY --from=php_builder /app/vendor ./vendor + +COPY --link package.json package-lock.json webpack.config.js tsconfig.json ./ +COPY --link assets ./assets + +RUN --mount=type=cache,target=/root/.npm \ + npm ci --no-audit --no-fund + +RUN npm run build + + +# --------------------------------------------------------------- +# Base FrankenPHP image — minimal, shared by dev and prod +# --------------------------------------------------------------- FROM frankenphp_upstream AS frankenphp_base WORKDIR /app @@ -18,33 +78,27 @@ VOLUME /app/var/ # persistent / runtime deps # hadolint ignore=DL3008 RUN apt-get update && apt-get install -y --no-install-recommends \ - file \ - cron \ - supervisor \ - procps \ - git \ + cron \ + file \ + procps \ + supervisor \ + && apt-get clean \ && rm -rf /var/lib/apt/lists/* RUN set -eux; \ install-php-extensions \ - @composer \ apcu \ intl \ - pdo_mysql \ opcache \ + pdo_mysql \ zip \ ; -# https://getcomposer.org/doc/03-cli.md#composer-allow-superuser -ENV COMPOSER_ALLOW_SUPERUSER=1 - ENV PHP_INI_SCAN_DIR=":$PHP_INI_DIR/app.conf.d" ###> recipes ### ###< recipes ### -RUN curl -fsSL https://deb.nodesource.com/setup_24.x | bash - && apt-get install -y nodejs - COPY --link frankenphp/conf.d/10-app.ini $PHP_INI_DIR/app.conf.d/ COPY --link --chmod=755 frankenphp/docker-entrypoint.sh /usr/local/bin/docker-entrypoint COPY --link frankenphp/Caddyfile /etc/frankenphp/Caddyfile @@ -57,26 +111,38 @@ ENTRYPOINT ["docker-entrypoint"] HEALTHCHECK --start-period=60s CMD curl -f http://localhost:2019/metrics || exit 1 CMD [ "frankenphp", "run", "--config", "/etc/frankenphp/Caddyfile" ] -# Dev FrankenPHP image + +# --------------------------------------------------------------- +# Dev image — composer + node + git + xdebug for live development +# --------------------------------------------------------------- FROM frankenphp_base AS frankenphp_dev -ENV APP_ENV=dev -ENV XDEBUG_MODE=off -ENV FRANKENPHP_WORKER_CONFIG=watch +ENV APP_ENV=dev \ + XDEBUG_MODE=off \ + FRANKENPHP_WORKER_CONFIG=watch \ + COMPOSER_ALLOW_SUPERUSER=1 -RUN mv "$PHP_INI_DIR/php.ini-development" "$PHP_INI_DIR/php.ini" +# hadolint ignore=DL3008 +RUN apt-get update \ + && apt-get install -y --no-install-recommends git \ + && curl -fsSL https://deb.nodesource.com/setup_24.x | bash - \ + && apt-get install -y --no-install-recommends nodejs \ + && apt-get clean \ + && rm -rf /var/lib/apt/lists/* -RUN set -eux; \ - install-php-extensions \ - xdebug \ - ; +RUN install-php-extensions @composer xdebug + +RUN mv "$PHP_INI_DIR/php.ini-development" "$PHP_INI_DIR/php.ini" COPY --link frankenphp/conf.d/20-app.dev.ini $PHP_INI_DIR/app.conf.d/ COPY --link frankenphp/supervisord_dev.conf /etc/supervisor/conf.d/supervisord.conf CMD ["/usr/bin/supervisord"] -# Prod FrankenPHP image + +# --------------------------------------------------------------- +# Prod image — minimal runtime, pre-built vendor + assets +# --------------------------------------------------------------- FROM frankenphp_base AS frankenphp_prod ENV APP_ENV=prod @@ -85,21 +151,11 @@ RUN mv "$PHP_INI_DIR/php.ini-production" "$PHP_INI_DIR/php.ini" COPY --link frankenphp/conf.d/20-app.prod.ini $PHP_INI_DIR/app.conf.d/ -# prevent the reinstallation of vendors at every changes in the source code -COPY --link composer.* symfony.* ./ -RUN set -eux; \ - composer install --no-cache --prefer-dist --no-dev --no-autoloader --no-scripts --no-progress +# Pre-built application: vendor, sources, warmed cache, bundle assets +COPY --from=php_builder --link /app /app +# Pre-built webpack assets +COPY --from=node_builder --link /app/public/build /app/public/build -# copy sources -COPY --link --exclude=frankenphp/ . ./ COPY --link frankenphp/supervisord_prod.conf /etc/supervisor/conf.d/supervisord.conf -RUN set -eux -RUN mkdir -p var/cache var/log var/share -RUN composer dump-autoload --classmap-authoritative --no-dev -RUN composer dump-env prod -#RUN composer run-script --no-dev post-install-cmd -RUN chmod +x bin/console -RUN sync - CMD ["/usr/bin/supervisord"] diff --git a/frankenphp/docker-entrypoint.sh b/frankenphp/docker-entrypoint.sh index 02e4430..164ee6f 100755 --- a/frankenphp/docker-entrypoint.sh +++ b/frankenphp/docker-entrypoint.sh @@ -1,12 +1,14 @@ #!/bin/sh set -e -if [ -z "$(ls -A 'vendor/' 2>/dev/null)" ]; then +if command -v composer >/dev/null 2>&1 && [ -z "$(ls -A 'vendor/' 2>/dev/null)" ]; then composer install --prefer-dist --no-progress --no-interaction fi -npm install -npm run build +if command -v npm >/dev/null 2>&1; then + npm install + npm run build +fi # Display information about the current project # Or about an error in project initialization @@ -38,7 +40,8 @@ if grep -q ^DATABASE_URL= .env; then fi fi -composer run-script --no-dev post-install-cmd +php bin/console cache:clear --no-debug +php bin/console assets:install public --no-debug echo 'PHP app ready!'