# Stage 0: PHP vendor dependencies for frontend imports FROM composer:2 AS vendor WORKDIR /app COPY composer.json composer.lock ./ RUN composer install \ --no-dev \ --prefer-dist \ --no-interaction \ --no-progress \ --no-scripts \ --no-autoloader # Stage 1: build frontend assets FROM node:20-alpine AS frontend WORKDIR /app COPY package*.json ./ RUN npm ci --no-audit COPY --from=vendor /app/vendor ./vendor COPY . . RUN npm run build # Stage 2: PHP-FPM app FROM php:8.4-fpm-alpine AS app WORKDIR /var/www/html RUN apk add --no-cache \ libpng-dev libjpeg-turbo-dev freetype-dev libzip-dev sqlite sqlite-dev \ oniguruma-dev libxml2-dev \ zip unzip git RUN docker-php-ext-configure gd --with-freetype --with-jpeg \ && docker-php-ext-install pdo pdo_sqlite mbstring dom xml gd zip opcache pcntl COPY --from=composer:2 /usr/bin/composer /usr/bin/composer COPY docker/php/php.ini $PHP_INI_DIR/conf.d/app.ini COPY . . COPY --from=frontend /app/public/build ./public/build RUN composer install --no-dev --optimize-autoloader --no-interaction RUN chown -R www-data:www-data storage bootstrap/cache \ && chmod -R 775 storage bootstrap/cache COPY docker/entrypoint.sh /entrypoint.sh RUN chmod +x /entrypoint.sh EXPOSE 9000 ENTRYPOINT ["/entrypoint.sh"] CMD ["php-fpm"] # Stage 3: nginx with baked-in static assets FROM nginx:1.27-alpine AS web COPY nginx/nginx.conf /etc/nginx/conf.d/default.conf COPY --from=app /var/www/html/public /var/www/html/public