# ============================================================ # Stage 1: Node — build frontend assets # ============================================================ FROM node:20-alpine AS node-builder WORKDIR /app COPY package.json package-lock.json* ./ RUN npm ci COPY . . RUN npm run build # ============================================================ # Stage 2: PHP — install Composer dependencies # ============================================================ FROM composer:2 AS composer-builder WORKDIR /app COPY composer.json composer.lock* ./ RUN composer install \ --no-dev \ --no-interaction \ --no-scripts \ --optimize-autoloader \ --prefer-dist COPY . . RUN composer dump-autoload --optimize --no-dev # ============================================================ # Stage 3: Production image # ============================================================ FROM php:8.2-fpm-alpine # Install system dependencies + PHP extensions RUN apk add --no-cache \ nginx \ supervisor \ curl \ libpng-dev \ libjpeg-turbo-dev \ libwebp-dev \ freetype-dev \ libzip-dev \ icu-dev \ oniguruma-dev \ sqlite-dev \ postgresql-dev \ postgresql-client \ libxml2-dev \ && docker-php-ext-configure gd \ --with-freetype \ --with-jpeg \ --with-webp \ && docker-php-ext-install -j$(nproc) \ pdo \ pdo_pgsql \ pdo_sqlite \ mbstring \ xml \ curl \ zip \ gd \ intl \ bcmath \ opcache \ pcntl WORKDIR /var/www/html # Copy application files COPY --from=composer-builder /app /var/www/html COPY --from=node-builder /app/public/build /var/www/html/public/build # Copy runtime configs COPY docker/nginx.conf /etc/nginx/nginx.conf COPY docker/supervisord.conf /etc/supervisor/conf.d/supervisord.conf COPY docker/php.ini /usr/local/etc/php/conf.d/app.ini COPY docker/entrypoint.sh /entrypoint.sh RUN chmod +x /entrypoint.sh \ && mkdir -p storage/logs storage/framework/{cache,sessions,views} bootstrap/cache \ && chown -R www-data:www-data /var/www/html \ && chmod -R 775 storage bootstrap/cache EXPOSE 80 ENTRYPOINT ["/entrypoint.sh"]