# --- Stage 1: Build backend --- FROM php:8.4-cli AS backend-build RUN apt-get update && apt-get install -y \ libicu-dev libpq-dev libpng-dev libzip-dev libxml2-dev \ unzip curl git \ && docker-php-ext-install -j$(nproc) intl pdo_pgsql zip gd opcache \ && rm -rf /var/lib/apt/lists/* COPY --from=composer:2 /usr/bin/composer /usr/bin/composer WORKDIR /app COPY composer.json composer.lock symfony.lock ./ RUN APP_ENV=prod APP_DEBUG=0 composer install --no-dev --no-scripts --no-interaction COPY bin bin/ COPY config config/ COPY migrations migrations/ COPY public public/ COPY src src/ RUN composer dump-autoload --optimize --no-dev # --- Stage 2: Build frontend --- FROM node:lts-alpine AS frontend-build WORKDIR /app/frontend COPY frontend/package.json frontend/package-lock.json ./ RUN npm ci COPY frontend/ ./ ENV CI=1 \ NUXT_TELEMETRY_DISABLED=1 \ NUXT_PUBLIC_API_BASE=/api \ NUXT_PUBLIC_APP_BASE=/ RUN npm run generate # --- Stage 3: Production image --- FROM php:8.4-fpm AS production RUN apt-get update && apt-get install -y \ libicu-dev libpq-dev libpng-dev libzip-dev libxml2-dev \ nginx supervisor docker.io curl \ && docker-php-ext-install -j$(nproc) intl pdo_pgsql zip gd opcache \ && rm -rf /var/lib/apt/lists/* # Install Docker Compose plugin RUN DOCKER_COMPOSE_VERSION=$(curl -s https://api.github.com/repos/docker/compose/releases/latest | grep '"tag_name"' | sed 's/.*"v\(.*\)".*/\1/') \ && mkdir -p /usr/local/lib/docker/cli-plugins \ && curl -SL "https://github.com/docker/compose/releases/download/v${DOCKER_COMPOSE_VERSION}/docker-compose-linux-x86_64" -o /usr/local/lib/docker/cli-plugins/docker-compose \ && chmod +x /usr/local/lib/docker/cli-plugins/docker-compose # PHP production config RUN mv "$PHP_INI_DIR/php.ini-production" "$PHP_INI_DIR/php.ini" # PHP-FPM: forward worker output to stderr for docker logs RUN echo "catch_workers_output = yes" >> /usr/local/etc/php-fpm.d/www.conf \ && echo "decorate_workers_output = no" >> /usr/local/etc/php-fpm.d/www.conf # Nginx: log to stdout/stderr RUN ln -sf /dev/stdout /var/log/nginx/access.log \ && ln -sf /dev/stderr /var/log/nginx/error.log # Remove default nginx site RUN rm -f /etc/nginx/sites-enabled/default # Configs COPY infra/prod/supervisord.conf /etc/supervisor/conf.d/app.conf COPY infra/prod/nginx.conf /etc/nginx/sites-enabled/central.conf # Backend from stage 1 COPY --from=backend-build /app /var/www/html # Frontend from stage 2 COPY --from=frontend-build /app/frontend/.output/public /var/www/html/frontend/.output/public # Symfony needs a .env file to boot (variables are overridden by env_file in docker-compose) RUN echo "APP_ENV=prod" > /var/www/html/.env # Permissions + directories RUN mkdir -p /var/www/html/var/log /var/www/html/var/uploads \ && chown -R www-data:www-data /var/www/html/var # Allow www-data to use Docker socket (GID 987 matches host's docker group) RUN groupadd -g 987 dockerhost 2>/dev/null; usermod -aG dockerhost www-data WORKDIR /var/www/html EXPOSE 80 CMD ["supervisord", "-n", "-c", "/etc/supervisor/conf.d/app.conf"]