# ── Stage 1 : compilation des assets ──────────────────────────────────────── FROM node:20-slim AS assets WORKDIR /build COPY package.json package-lock.json ./ # Layer séparé : npm ci n'est relancé que si package-lock.json change. # npm run build est dans un layer distinct : toute modification dans assets/ # invalide uniquement ce layer, sans réinstaller les packages. RUN npm ci COPY assets/ assets/ RUN npm run build # ── Stage 2 : image PHP de production ─────────────────────────────────────── FROM php:8.3-fpm # Extensions système et PHP dans un seul layer RUN apt-get update && apt-get install -y --no-install-recommends \ libsqlite3-dev libxml2-dev libonig-dev \ libpng-dev libjpeg62-turbo-dev libwebp-dev unzip \ && rm -rf /var/lib/apt/lists/* \ && docker-php-ext-configure gd --with-webp --with-jpeg \ && docker-php-ext-install pdo_sqlite mbstring dom fileinfo gd COPY docker/php/php.ini /usr/local/etc/php/conf.d/custom.ini COPY --from=composer:2 /usr/bin/composer /usr/bin/composer WORKDIR /var/www/app # Dépendances Composer — layer mis en cache tant que les lock files n'ont pas changé COPY composer.json composer.lock ./ RUN composer install --no-dev --optimize-autoloader --no-interaction # Code source + assets compilés depuis le stage 1 COPY . . COPY --from=assets /build/public/assets/ public/assets/ # Archive les migrations hors du WORKDIR : le bind mount ./data/database/ # écrase /var/www/app/database/ au démarrage — l'entrypoint recopie depuis ici. RUN cp -r database /database.baked COPY --chmod=755 docker/php/entrypoint.sh /usr/local/bin/entrypoint.sh ENTRYPOINT ["entrypoint.sh"] CMD ["php-fpm"]