# Production Dockerfile with FrankenPHP FROM dunglas/frankenphp:latest-php8.3-alpine # Install system dependencies (except Node - Alpine's is too old for Vite 7) RUN apk add --no-cache \ git \ mysql-client \ curl # Install Node.js 20.19.0+ (Vite 7 requires 20.19+) RUN curl -fsSL https://unofficial-builds.nodejs.org/download/release/v20.19.0/node-v20.19.0-linux-x64-musl.tar.xz | tar -xJ -C /usr/local --strip-components=1 # Install PHP extensions RUN install-php-extensions \ pdo_mysql \ opcache \ zip \ gd \ intl # Install Composer COPY --from=composer:2 /usr/bin/composer /usr/bin/composer # Set working directory WORKDIR /app # Set fixed production environment variables ENV APP_ENV=production \ APP_DEBUG=false \ DB_CONNECTION=mysql \ DB_HOST=db \ DB_PORT=3306 \ SESSION_DRIVER=database \ CACHE_DRIVER=file \ QUEUE_CONNECTION=database \ LOG_CHANNEL=stack \ LOG_LEVEL=error \ MAIL_MAILER=smtp \ MAIL_ENCRYPTION=tls # Copy application code first COPY . . # Install PHP dependencies (production only) RUN composer install --no-dev --no-interaction --optimize-autoloader # Install ALL Node dependencies (including dev for building) RUN npm install # Build frontend assets RUN npm run build # Remove node_modules after build to save space RUN rm -rf node_modules # Laravel optimizations RUN php artisan config:cache \ && php artisan route:cache \ && composer dump-autoload --optimize # Set permissions RUN chown -R www-data:www-data /app/storage /app/bootstrap/cache # Configure Caddy RUN cat > /etc/caddy/Caddyfile < /start-prod.sh <<'EOF' #!/bin/sh set -e # Wait for database to be ready echo "Waiting for database..." for i in $(seq 1 30); do if php artisan db:monitor --database=mysql 2>/dev/null | grep -q "OK"; then echo "Database is ready!" break fi echo "Waiting for database... ($i/30)" sleep 2 done # Run migrations echo "Running migrations..." php artisan migrate --force || echo "Migrations failed or already up-to-date" # Start FrankenPHP exec frankenphp run --config /etc/caddy/Caddyfile EOF RUN chmod +x /start-prod.sh # Start with our script CMD ["/start-prod.sh"]