# syntax=docker/dockerfile:1

# =============================================================================
# Stage 1 — PHP dependencies (no dev, production autoloader)
# =============================================================================
FROM composer:2 AS vendor

WORKDIR /app

# --no-scripts: artisan isn't available yet, package discovery would fail.
# Autoload is optimized in the runtime stage once the full source is present.
COPY composer.json composer.lock ./
RUN composer install \
        --no-interaction \
        --no-dev \
        --prefer-dist \
        --no-progress \
        --no-scripts \
        --ignore-platform-reqs

# =============================================================================
# Stage 2 — Frontend assets (Vite + Tailwind)
# =============================================================================
FROM node:20-alpine AS assets

WORKDIR /app

COPY package.json package-lock.json* ./
RUN if [ -f package-lock.json ]; then \
        npm ci --no-audit --no-fund; \
    else \
        npm install --no-audit --no-fund; \
    fi

# Tailwind 4 scans blade/php sources for class names, so they must be present.
COPY vite.config.js ./
COPY resources ./resources
COPY app ./app
COPY config ./config
RUN npm run build

# =============================================================================
# Stage 3 — Runtime
# =============================================================================
FROM php:8.3-fpm AS runtime

# nginx + supervisor run in-image alongside php-fpm: a separate nginx container
# would need its own copy of public/ plus the storage volume just to serve
# static files, which is more moving parts than this app warrants.
# poppler-utils provides pdftoppm/pdfinfo used by TerritorioThumbnailService.
# Node is deliberately absent here: assets are built in stage 2.
# The -dev packages are kept rather than purged. Their runtime counterparts
# are named per Debian release (libicu72 vs libicu76, libzip4 vs libzip5), so
# purging means pinning package names that break whenever the php base image
# moves to a new Debian. A few tens of MB is worth not having that breakage.
RUN apt-get update && apt-get install -y --no-install-recommends \
        curl \
        netcat-openbsd \
        procps \
        nginx \
        supervisor \
        poppler-utils \
        libpng-dev \
        libjpeg62-turbo-dev \
        libfreetype6-dev \
        libonig-dev \
        libxml2-dev \
        libzip-dev \
        libicu-dev \
    && docker-php-ext-configure gd --with-freetype --with-jpeg \
    && docker-php-ext-install -j"$(nproc)" \
        pdo_mysql \
        mbstring \
        exif \
        pcntl \
        bcmath \
        gd \
        intl \
        zip \
        opcache \
    && pecl install redis \
    && docker-php-ext-enable redis \
    && apt-get clean \
    && rm -rf /var/lib/apt/lists/*

# Kept only so `composer dump-autoload` can run below; harmless at runtime.
COPY --from=composer:2 /usr/bin/composer /usr/bin/composer

COPY docker/php/php.ini /usr/local/etc/php/conf.d/custom.ini
COPY docker/php/www.conf /usr/local/etc/php-fpm.d/www.conf
COPY docker/nginx/default.conf /etc/nginx/sites-available/default
COPY docker/supervisor/supervisord.conf /etc/supervisor/conf.d/supervisord.conf

WORKDIR /var/www/html

# Everything the app needs is baked into the image. Runtime containers do NOT
# bind-mount the source, so there is no composer/npm work at boot.
COPY --chown=www-data:www-data . .
COPY --from=vendor --chown=www-data:www-data /app/vendor ./vendor
COPY --from=assets --chown=www-data:www-data /app/public/build ./public/build

# Writable paths. storage/ is replaced by a named volume at runtime; this is
# the skeleton the entrypoint repopulates when that volume starts out empty.
RUN mkdir -p \
        storage/framework/cache/data \
        storage/framework/sessions \
        storage/framework/views \
        storage/logs \
        storage/app/public \
        bootstrap/cache \
    && chown -R www-data:www-data storage bootstrap/cache \
    && chmod -R 775 storage bootstrap/cache

RUN composer dump-autoload --optimize --no-dev --no-interaction \
    && php artisan package:discover --ansi

COPY docker/php/entrypoint.sh /usr/local/bin/entrypoint.sh
COPY docker/php/queue-entrypoint.sh /usr/local/bin/queue-entrypoint.sh
RUN chmod +x /usr/local/bin/entrypoint.sh /usr/local/bin/queue-entrypoint.sh

EXPOSE 80

# /up is Laravel's built-in health endpoint (registered in bootstrap/app.php),
# so this exercises the full nginx -> php-fpm -> framework path, not just a port.
HEALTHCHECK --interval=10s --timeout=5s --start-period=120s --retries=12 \
    CMD curl -fsS http://127.0.0.1/up >/dev/null || exit 1

ENTRYPOINT ["entrypoint.sh"]
CMD ["/usr/bin/supervisord", "-c", "/etc/supervisor/conf.d/supervisord.conf"]
