# syntax=docker/dockerfile:1

# ---------------------------------------------------------------------------
# Base image: PHP 8.4 FPM + required extensions + composer
# ---------------------------------------------------------------------------
FROM php:8.4-fpm AS base

RUN apt-get update && apt-get install -y --no-install-recommends \
        git \
        unzip \
        libzip-dev \
        libpng-dev \
        libjpeg-dev \
        libfreetype6-dev \
        libonig-dev \
        libxml2-dev \
        default-mysql-client \
    && docker-php-ext-configure gd --with-freetype --with-jpeg \
    && docker-php-ext-install -j"$(nproc)" pdo_mysql mbstring zip exif pcntl bcmath gd opcache \
    && rm -rf /var/lib/apt/lists/*

COPY --from=composer:2 /usr/bin/composer /usr/bin/composer

WORKDIR /var/www/html

COPY docker/entrypoint.sh /usr/local/bin/entrypoint.sh
RUN chmod +x /usr/local/bin/entrypoint.sh
ENTRYPOINT ["entrypoint.sh"]

# ---------------------------------------------------------------------------
# Development target: code is bind-mounted, dependencies installed on start
# ---------------------------------------------------------------------------
FROM base AS dev

ENV APP_ENV=local

# Code is bind-mounted in dev, so OPcache must re-check every request. Without
# this the shared opcache.ini defaults would serve stale opcodes for up to 2s
# after each edit.
RUN { \
        echo 'opcache.validate_timestamps=1'; \
        echo 'opcache.revalidate_freq=0'; \
    } > /usr/local/etc/php/conf.d/zz-opcache-dev.ini

EXPOSE 8000
CMD ["php", "artisan", "serve", "--host=0.0.0.0", "--port=8000"]

# ---------------------------------------------------------------------------
# Build target: install production dependencies with baked-in source
# ---------------------------------------------------------------------------
FROM base AS build

COPY . .
RUN composer install --no-dev --optimize-autoloader --no-interaction --no-scripts

# ---------------------------------------------------------------------------
# Production target: PHP-FPM serving the optimized application
# ---------------------------------------------------------------------------
FROM base AS prod

ENV APP_ENV=production

# Production PHP + FPM tuning. Loaded from conf.d so it takes effect after the
# image's own ini files. Before these existed the container ran on PHP's
# compiled-in defaults (no OPcache, upload_max_filesize=2M) and on the stock
# FPM pool (pm.max_children=5).
COPY docker/php/php.ini  /usr/local/etc/php/conf.d/zz-pms.ini
COPY docker/php/www.conf /usr/local/etc/php-fpm.d/www.conf

COPY --from=build /var/www/html /var/www/html

RUN chown -R www-data:www-data storage bootstrap/cache \
    && mkdir -p /tmp/opcache \
    && chown www-data:www-data /tmp/opcache

EXPOSE 9000
CMD ["php-fpm"]

# ---------------------------------------------------------------------------
# Web target: nginx serving the application's public/ directory.
#
# Built from the SAME build stage as prod, so the web server and PHP-FPM can
# never drift apart. This replaces the previous approach of sharing a
# `backend_app` named volume between the two containers - Docker only seeds a
# named volume when it is EMPTY, so after the first deploy that volume masked
# every subsequent image build and deploys became silent no-ops.
#
# nginx only needs public/ (a few KB), not the whole application.
# The server config itself is still bind-mounted from docker/nginx/backend.conf
# by docker-compose so it can be tuned without a rebuild.
# ---------------------------------------------------------------------------
FROM nginx:alpine AS web

COPY --from=build /var/www/html/public /var/www/html/public

EXPOSE 80
CMD ["nginx", "-g", "daemon off;"]
