# ───────────────────────────────────────────── # Stage 1 – Build frontend assets (Node) # ───────────────────────────────────────────── FROM node:22-alpine AS node-builder WORKDIR /app COPY package.json package-lock.json ./ RUN npm ci --ignore-scripts COPY vite.config.js ./ COPY resources/ resources/ COPY public/ public/ RUN npm run build # ───────────────────────────────────────────── # Stage 2 – PHP runtime # ───────────────────────────────────────────── FROM php:8.3-fpm-alpine AS runtime # ── System packages ────────────────────────── RUN apk add --no-cache \ nginx \ supervisor \ sqlite \ curl \ git \ unzip \ libpng-dev \ libjpeg-turbo-dev \ freetype-dev \ libxml2-dev \ libzip-dev \ icu-dev \ oniguruma-dev # ── PHP extensions ─────────────────────────── # GD (needed by dompdf for image rendering) RUN docker-php-ext-configure gd \ --with-freetype \ --with-jpeg \ && docker-php-ext-install -j"$(nproc)" \ pdo \ pdo_sqlite \ mbstring \ fileinfo \ xml \ dom \ bcmath \ zip \ intl \ gd \ opcache \ pcntl # ── Composer ───────────────────────────────── COPY --from=composer:2 /usr/bin/composer /usr/bin/composer # ── App directory ──────────────────────────── WORKDIR /var/www/html # Install PHP dependencies first (better layer caching) COPY composer.json composer.lock ./ RUN composer install \ --no-dev \ --no-interaction \ --no-scripts \ --optimize-autoloader \ --prefer-dist # Copy full application COPY . . # Inject compiled frontend assets from Stage 1 COPY --from=node-builder /app/public/build public/build/ # ── Docker helper files ─────────────────────── COPY docker/nginx.conf /etc/nginx/nginx.conf COPY docker/supervisord.conf /etc/supervisord.conf COPY docker/entrypoint.sh /entrypoint.sh RUN chmod +x /entrypoint.sh # ── File system ────────────────────────────── RUN mkdir -p \ storage/app/private/talent-assets \ storage/logs \ storage/framework/cache \ storage/framework/sessions \ storage/framework/views \ bootstrap/cache \ database \ && chown -R www-data:www-data \ storage \ bootstrap/cache \ database \ && chmod -R 775 \ storage \ bootstrap/cache \ database # ── PHP-FPM: run as www-data ───────────────── RUN sed -i 's/user = www-data/user = www-data/' /usr/local/etc/php-fpm.d/www.conf 2>/dev/null || true \ && sed -i 's/group = www-data/group = www-data/' /usr/local/etc/php-fpm.d/www.conf 2>/dev/null || true # ── OPcache tuning ─────────────────────────── RUN { \ echo "opcache.enable=1"; \ echo "opcache.memory_consumption=128"; \ echo "opcache.interned_strings_buffer=8"; \ echo "opcache.max_accelerated_files=10000"; \ echo "opcache.validate_timestamps=0"; \ echo "opcache.fast_shutdown=1"; \ } > /usr/local/etc/php/conf.d/opcache.ini EXPOSE 80 ENTRYPOINT ["/entrypoint.sh"]