ARG NODE_VERSION=22 # Node.js build stage for building frontend assets # Use native platform for build stage as it's platform-independent FROM --platform=$BUILDPLATFORM node:${NODE_VERSION}-bookworm-slim AS node-builder ARG TARGETARCH WORKDIR /app # Install composer and minimal PHP for running Symfony commands COPY --from=composer:latest /usr/bin/composer /usr/bin/composer # Use BuildKit cache mounts for apt in builder stage RUN --mount=type=cache,id=apt-cache-node-$TARGETARCH,target=/var/cache/apt \ --mount=type=cache,id=apt-lists-node-$TARGETARCH,target=/var/lib/apt/lists \ apt-get update && apt-get install -y --no-install-recommends \ php-cli \ php-xml \ php-mbstring \ unzip \ git \ && apt-get clean && rm -rf /var/lib/apt/lists/* # Copy composer files and install dependencies (needed for Symfony UX assets) COPY composer.json composer.lock symfony.lock ./ # Use BuildKit cache for Composer downloads RUN --mount=type=cache,id=composer-cache,target=/root/.cache/composer \ composer install --no-scripts --no-autoloader --no-dev --prefer-dist --ignore-platform-reqs # Copy all application files needed for cache warmup and webpack build COPY .env* ./ COPY bin ./bin COPY config ./config COPY src ./src COPY translations ./translations COPY public ./public COPY assets ./assets COPY webpack.config.js ./ # Generate autoloader RUN composer dump-autoload # Create required directories for cache warmup RUN mkdir -p var/cache var/log uploads public/media # Dump translations, which we need for cache warmup RUN php bin/console cache:warmup -n --env=prod 2>&1 # Copy package files and install node dependencies COPY package.json yarn.lock ./ # Use BuildKit cache for yarn/npm RUN --mount=type=cache,id=yarn-cache,target=/root/.cache/yarn \ --mount=type=cache,id=npm-cache,target=/root/.npm \ yarn install --network-timeout 600000 # Build the assets RUN yarn build # Clean up RUN yarn cache clean && rm -rf node_modules/ # FrankenPHP base stage FROM dunglas/frankenphp:1-php8.4 AS frankenphp_upstream ARG TARGETARCH RUN --mount=type=cache,id=apt-cache-$TARGETARCH,target=/var/cache/apt \ --mount=type=cache,id=apt-lists-$TARGETARCH,target=/var/lib/apt/lists \ apt-get update && apt-get -y install \ curl \ ca-certificates \ mariadb-client \ postgresql-client \ file \ acl \ git \ gettext \ gnupg \ zip \ && apt-get -y autoremove && apt-get clean autoclean && rm -rf /var/lib/apt/lists/*; # Install PHP RUN set -eux; \ install-php-extensions \ @composer \ apcu \ intl \ opcache \ zip \ pdo_mysql \ pdo_sqlite \ pdo_pgsql \ gd \ bcmath \ xsl \ ; # Copy config files for php and caddy COPY --link .docker/frankenphp/conf.d/app.ini $PHP_INI_DIR/conf.d/ COPY --chmod=755 .docker/frankenphp/docker-entrypoint.sh /usr/local/bin/docker-entrypoint COPY --link .docker/frankenphp/Caddyfile /etc/caddy/Caddyfile COPY --link .docker/frankenphp/conf.d/app.prod.ini $PHP_INI_DIR/conf.d/ COPY --link .docker/frankenphp/worker.Caddyfile /etc/caddy/worker.Caddyfile ENV FRANKENPHP_CONFIG="import worker.Caddyfile" RUN mv "$PHP_INI_DIR/php.ini-production" "$PHP_INI_DIR/php.ini" # Install composer ENV COMPOSER_ALLOW_SUPERUSER=1 #COPY --from=composer:latest /usr/bin/composer /usr/bin/composer # Create workdir and set permissions if directory does not exists WORKDIR /app # 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 # copy sources COPY --link . ./ # Install composer and yarn dependencies for Part-DB RUN set -eux; \ mkdir -p var/cache var/log; \ composer dump-autoload --classmap-authoritative --no-dev; \ composer run-script --no-dev post-install-cmd; \ chmod +x bin/console; sync; # Copy built frontend assets from node-builder stage COPY --from=node-builder /app/public/build ./public/build # Use docker env to output logs to stdout ENV APP_ENV=docker ENV DATABASE_URL="sqlite:///%kernel.project_dir%/uploads/app.db" USER root ENTRYPOINT ["docker-entrypoint"] CMD ["frankenphp", "run", "--config", "/etc/caddy/Caddyfile"] # https://httpd.apache.org/docs/2.4/stopping.html#gracefulstop STOPSIGNAL SIGWINCH VOLUME ["/var/www/html/uploads", "/var/www/html/public/media"] HEALTHCHECK --start-period=60s CMD curl -f http://localhost:2019/metrics || exit 1 # See https://caddyserver.com/docs/conventions#file-locations for details ENV XDG_CONFIG_HOME=/config ENV XDG_DATA_HOME=/data EXPOSE 80 EXPOSE 443 EXPOSE 443/udp EXPOSE 2019