# Multi-stage build for Trip Planner production image # This creates a single Debian-based image with all services # Stage 1: Build Frontend FROM node:20-bookworm-slim AS frontend-builder WORKDIR /app/frontend COPY frontend/package*.json ./ RUN npm ci COPY frontend/ ./ RUN npm run build # Stage 2: Build Backend FROM php:8.3-fpm-bookworm AS backend-builder # Install system dependencies RUN apt-get update && apt-get install -y \ libpng-dev \ libonig-dev \ libxml2-dev \ zip \ unzip \ && rm -rf /var/lib/apt/lists/* # Install PHP extensions RUN docker-php-ext-install pdo_mysql mbstring exif pcntl bcmath gd opcache # Install Composer COPY --from=composer:latest /usr/bin/composer /usr/bin/composer WORKDIR /app/backend # Copy composer files COPY backend/composer.json backend/composer.lock ./ # Install dependencies (no dev) RUN composer install --no-dev --no-scripts --no-autoloader --prefer-dist # Copy application COPY backend/ ./ # Generate optimized autoloader RUN composer dump-autoload --optimize --classmap-authoritative # Stage 3: Final Production Image FROM debian:bookworm-slim # Install runtime dependencies RUN apt-get update && apt-get install -y \ nginx \ supervisor \ mariadb-server \ php8.3-fpm \ php8.3-mysql \ php8.3-mbstring \ php8.3-xml \ php8.3-bcmath \ php8.3-gd \ php8.3-opcache \ curl \ && rm -rf /var/lib/apt/lists/* # Create application directory WORKDIR /var/www/html # Copy backend from builder COPY --from=backend-builder /app/backend ./ # Copy frontend build to Laravel public directory RUN mkdir -p /var/www/html/public/app COPY --from=frontend-builder /app/frontend/dist /var/www/html/public/app # Copy production configuration files COPY docker/production/nginx.conf /etc/nginx/sites-available/default COPY docker/production/supervisord.conf /etc/supervisor/conf.d/trip-planner.conf COPY docker/production/init-db.sh /usr/local/bin/init-db.sh COPY docker/production/php-fpm.conf /etc/php/8.3/fpm/pool.d/www.conf # Make init script executable RUN chmod +x /usr/local/bin/init-db.sh # Configure PHP for production RUN echo "opcache.enable=1" >> /etc/php/8.3/fpm/conf.d/99-opcache.ini \ && echo "opcache.memory_consumption=128" >> /etc/php/8.3/fpm/conf.d/99-opcache.ini \ && echo "opcache.max_accelerated_files=10000" >> /etc/php/8.3/fpm/conf.d/99-opcache.ini \ && echo "opcache.validate_timestamps=0" >> /etc/php/8.3/fpm/conf.d/99-opcache.ini # Ensure all storage subdirectories exist RUN mkdir -p /var/www/html/storage/framework/cache/data \ /var/www/html/storage/framework/sessions \ /var/www/html/storage/framework/views \ /var/www/html/storage/logs # Set permissions RUN chown -R www-data:www-data /var/www/html/storage /var/www/html/bootstrap/cache \ && chmod -R 775 /var/www/html/storage /var/www/html/bootstrap/cache # Create data directory for MariaDB persistence RUN mkdir -p /var/lib/mysql-data \ && chown -R mysql:mysql /var/lib/mysql-data # Expose port 80 EXPOSE 80 # Health check HEALTHCHECK --interval=30s --timeout=3s --start-period=40s --retries=3 \ CMD curl -f http://localhost/api/health || exit 1 # Start supervisord CMD ["/usr/bin/supervisord", "-c", "/etc/supervisor/conf.d/trip-planner.conf"]