# syntax=docker/dockerfile:1 # --------------------------------------------------------------------------- # Stage 1: build front-end assets with Vite (Node 22 ~ npm 10.9.x) # --------------------------------------------------------------------------- FROM node:22-bookworm-slim AS assets WORKDIR /app # Install JS deps first for better layer caching. No package-lock.json is # committed, so use `npm install` rather than `npm ci`. COPY package.json ./ RUN npm install # Only the inputs Vite needs to produce public/build COPY vite.config.js ./ COPY resources ./resources RUN npm run build # --------------------------------------------------------------------------- # Stage 2: PHP 8.4 dependencies + application code (the "app" / php-fpm image) # --------------------------------------------------------------------------- FROM php:8.4-fpm-bookworm AS app # System libraries required to build the PHP extensions below. RUN apt-get update && apt-get install -y --no-install-recommends \ git \ unzip \ rsync \ libzip-dev \ libpng-dev \ libjpeg-dev \ libfreetype-dev \ libonig-dev \ libicu-dev \ libxml2-dev \ && docker-php-ext-configure gd --with-freetype --with-jpeg \ && docker-php-ext-install -j"$(nproc)" \ pdo_mysql \ mbstring \ bcmath \ gd \ zip \ intl \ exif \ pcntl \ opcache \ && apt-get clean \ && rm -rf /var/lib/apt/lists/* # Composer (pulled from the official image; 2.x line, matches host 2.9.x) COPY --from=composer:2 /usr/bin/composer /usr/bin/composer # PHP runtime configuration COPY docker/php/php.ini /usr/local/etc/php/conf.d/zz-app.ini WORKDIR /var/www/html # Install PHP dependencies first (better caching). Skip scripts/autoloader # until the full source tree is present. COPY composer.json composer.lock ./ RUN composer install \ --no-dev \ --no-scripts \ --no-autoloader \ --prefer-dist \ --no-interaction \ --no-progress # Application source + freshly built front-end assets COPY . . COPY --from=assets /app/public/build ./public/build # Optimised autoloader (package discovery runs at container start instead, # where the environment is available). RUN composer dump-autoload --no-dev --optimize --no-interaction \ && chown -R www-data:www-data storage bootstrap/cache \ && chmod -R ug+rwX storage bootstrap/cache # Entrypoint prepares storage, caches config, runs migrations, then runs the # given command (php-fpm by default). COPY docker/php/entrypoint.sh /usr/local/bin/entrypoint RUN chmod +x /usr/local/bin/entrypoint EXPOSE 9000 ENTRYPOINT ["entrypoint"] CMD ["php-fpm"] # --------------------------------------------------------------------------- # Stage 3: nginx serving the static assets + proxying PHP to the app container # --------------------------------------------------------------------------- FROM nginx:1.27-alpine AS web # Baked copy of the public root so nginx can serve static files directly. COPY --from=app /var/www/html/public /var/www/html/public COPY docker/nginx/default.conf /etc/nginx/conf.d/default.conf EXPOSE 80