# Stage 1: Build frontend assets with Vite. FROM node:20-alpine AS assets-builder WORKDIR /app COPY package.json package-lock.json* ./ RUN if [ -f package-lock.json ]; then npm ci; else npm install; fi COPY . . RUN npm run build # Stage 2: Production Laravel runtime. FROM php:8.3-apache ENV APACHE_DOCUMENT_ROOT=/app/public \ COMPOSER_ALLOW_SUPERUSER=1 RUN apt-get update \ && apt-get install -y --no-install-recommends \ curl \ git \ libicu-dev \ libzip-dev \ unzip \ && docker-php-ext-install intl opcache pdo_mysql zip \ && a2enmod headers rewrite \ && sed -ri -e 's!/var/www/html!/app/public!g' /etc/apache2/sites-available/000-default.conf \ && printf '\n AllowOverride All\n Require all granted\n\n' > /etc/apache2/conf-available/laravel.conf \ && a2enconf laravel \ && rm -rf /var/lib/apt/lists/* RUN { \ echo 'opcache.enable=1'; \ echo 'opcache.enable_cli=1'; \ echo 'opcache.validate_timestamps=0'; \ echo 'opcache.memory_consumption=128'; \ echo 'opcache.max_accelerated_files=10000'; \ } > /usr/local/etc/php/conf.d/opcache-production.ini COPY --from=composer:2 /usr/bin/composer /usr/bin/composer WORKDIR /app COPY . . COPY --from=assets-builder /app/public/build ./public/build RUN composer install --no-dev --no-interaction --no-progress --prefer-dist --optimize-autoloader \ && mkdir -p storage/framework/cache storage/framework/sessions storage/framework/views storage/logs bootstrap/cache \ && chown -R www-data:www-data storage bootstrap/cache public/build \ && chmod +x docker/entrypoint.sh EXPOSE 80 HEALTHCHECK --interval=30s --timeout=5s --start-period=30s --retries=3 \ CMD curl -fsS http://127.0.0.1/ >/dev/null || exit 1 ENTRYPOINT ["docker/entrypoint.sh"] CMD ["apache2-foreground"]