Files
My-KOPKB/be/docker/common/unified/Dockerfile
T
ismailmasseran 580c7d2392
Build Docker Image / build-backend (push) Failing after 23s
Build Docker Image / build-frontend (push) Successful in 21s
DONE: fix error where image not showing on digital card, generate letter not working on prod (#5)
Co-authored-by: ISMAIL MASSERAN <topaz@ISMAILs-Macbook.local>
Reviewed-on: #5
2026-07-06 13:24:42 +08:00

202 lines
6.4 KiB
Docker

# Stage 1: Build environment and Composer dependencies
FROM php:8.4-fpm AS builder
LABEL maintainer="Topaz"
# Install system dependencies and PHP extensions for Laravel with MySQL/PostgreSQL support.
RUN apt-get update && apt-get install -y --no-install-recommends \
curl \
unzip \
libpq-dev \
libonig-dev \
libssl-dev \
libxml2-dev \
libcurl4-openssl-dev \
libicu-dev \
libzip-dev \
libjpeg-dev \
libpng-dev \
libfreetype6-dev \
&& docker-php-ext-configure gd --with-freetype --with-jpeg \
&& docker-php-ext-install -j$(nproc) \
pdo_mysql \
pdo_pgsql \
pgsql \
opcache \
intl \
zip \
bcmath \
soap \
gd \
pcntl \
&& pecl install redis \
&& docker-php-ext-enable redis \
&& apt-get autoremove -y && apt-get clean && rm -rf /var/lib/apt/lists/* /tmp/* /var/tmp/*
# Set the working directory inside the container
WORKDIR /var/www
# Copy the entire Laravel application code into the container
COPY be/ /var/www
# Copy Composer from official image (avoids flaky getcomposer.org in CI)
COPY --from=composer:2 /usr/bin/composer /usr/local/bin/composer
# Install PHP dependencies
RUN composer install --no-dev --optimize-autoloader --no-interaction --no-progress --prefer-dist --no-scripts \
&& rm -rf bootstrap/cache/services.php bootstrap/cache/packages.php
# Stage 1b: Node + Puppeteer for Browsershot PDF generation
FROM node:22-bookworm-slim AS node-deps
WORKDIR /var/www
COPY be/package.json be/package-lock.json ./
RUN npm ci --omit=dev
ENV PUPPETEER_CACHE_DIR=/var/www/.cache/puppeteer
RUN npx puppeteer browsers install chrome-headless-shell
# Stage 2: Unified production image with PHP-FPM + Nginx
FROM php:8.4-fpm AS base
LABEL maintainer="Topaz"
# Set system timezone to Asia/Kuala_Lumpur
RUN apt-get update && apt-get install -y --no-install-recommends tzdata \
&& ln -snf /usr/share/zoneinfo/Asia/Kuala_Lumpur /etc/localtime \
&& echo "Asia/Kuala_Lumpur" > /etc/timezone \
&& dpkg-reconfigure -f noninteractive tzdata \
&& apt-get clean && rm -rf /var/lib/apt/lists/* /tmp/* /var/tmp/*
# Install Nginx and all runtime dependencies
RUN apt-get update && apt-get install -y --no-install-recommends \
nginx \
libpq-dev \
libicu-dev \
libzip-dev \
libpng-dev \
libjpeg-dev \
libfreetype6-dev \
libfcgi-bin \
procps \
netcat-openbsd \
supervisor \
nano \
curl \
&& docker-php-ext-configure gd --with-freetype --with-jpeg \
&& docker-php-ext-install gd \
&& pecl install redis \
&& docker-php-ext-enable redis \
&& apt-get autoremove -y && apt-get clean && rm -rf /var/lib/apt/lists/* /tmp/* /var/tmp/*
# Chromium runtime libraries for Puppeteer (Browsershot PDF generation)
RUN apt-get update && apt-get install -y --no-install-recommends \
ca-certificates \
fonts-liberation \
libasound2 \
libatk-bridge2.0-0 \
libatk1.0-0 \
libcairo2 \
libcups2 \
libdbus-1-3 \
libdrm2 \
libexpat1 \
libfontconfig1 \
libgbm1 \
libglib2.0-0 \
libnspr4 \
libnss3 \
libpango-1.0-0 \
libpangocairo-1.0-0 \
libx11-6 \
libx11-xcb1 \
libxcb1 \
libxcomposite1 \
libxdamage1 \
libxext6 \
libxfixes3 \
libxkbcommon0 \
libxrandr2 \
libxrender1 \
&& apt-get autoremove -y && apt-get clean && rm -rf /var/lib/apt/lists/* /tmp/* /var/tmp/*
# Download and install php-fpm health check script
RUN curl -o /usr/local/bin/php-fpm-healthcheck \
https://raw.githubusercontent.com/renatomefi/php-fpm-healthcheck/master/php-fpm-healthcheck \
&& chmod +x /usr/local/bin/php-fpm-healthcheck
# Copy the initialization script
COPY be/docker/common/unified/entrypoint.sh /usr/local/bin/entrypoint.sh
RUN chmod +x /usr/local/bin/entrypoint.sh
# Copy supervisor configuration files
COPY be/docker/common/unified/supervisor/supervisord.conf /etc/supervisor/supervisord.conf
# Create supervisor conf.d directory
RUN mkdir -p /etc/supervisor/conf.d
# Use common supervisor and nginx config inside the image.
# If you need environment-specific behavior (training vs production), override at runtime
# by mounting files into:
# - /etc/nginx/nginx.conf
# - /etc/supervisor/conf.d/
COPY be/docker/common/unified/supervisor/unified.conf /etc/supervisor/conf.d/unified.conf
COPY be/docker/common/unified/nginx/nginx.conf /etc/nginx/nginx.conf
# Copy the initial storage structure
COPY be/storage /var/www/storage-init
# Copy PHP extensions and libraries from the builder stage
COPY --from=builder /usr/local/lib/php/extensions/ /usr/local/lib/php/extensions/
COPY --from=builder /usr/local/etc/php/conf.d/ /usr/local/etc/php/conf.d/
COPY --from=builder /usr/local/bin/docker-php-ext-* /usr/local/bin/
# Use the recommended production PHP configuration
RUN mv "$PHP_INI_DIR/php.ini-production" "$PHP_INI_DIR/php.ini"
# Enable PHP-FPM status page via separate config file (avoid modifying zz-docker.conf)
RUN echo '[www]' > /usr/local/etc/php-fpm.d/zzz-status.conf && \
echo 'pm.status_path = /status' >> /usr/local/etc/php-fpm.d/zzz-status.conf
# Copy the application code and dependencies from the build stage first
COPY --from=builder /var/www /var/www
# Node runtime + Puppeteer for Browsershot (letter PDF generation)
COPY --from=node-deps /usr/local/bin/node /usr/local/bin/node
COPY --from=node-deps /var/www/node_modules /var/www/node_modules
COPY --from=node-deps /var/www/.cache/puppeteer /var/www/.cache/puppeteer
ENV PUPPETEER_CACHE_DIR=/var/www/.cache/puppeteer \
BROWSERSHOT_NO_SANDBOX=true \
BROWSERSHOT_NODE_BINARY=/usr/local/bin/node
# Set working directory
WORKDIR /var/www
# Ensure correct permissions
RUN chown -R www-data:www-data /var/www /var/www/.cache/puppeteer
# Create Nginx log directory
RUN mkdir -p /var/log/nginx && chown -R www-data:www-data /var/log/nginx
# Run the entrypoint script
ENTRYPOINT ["/usr/local/bin/entrypoint.sh"]
# Expose port 80 (Nginx) and 9000 (PHP-FPM for health checks)
EXPOSE 80 9000
# Start supervisor which manages both Nginx and PHP-FPM
CMD ["supervisord", "-c", "/etc/supervisor/supervisord.conf"]
# CI: install dev dependencies and run PHPUnit (build with --target backend-test)
FROM builder AS backend-test
ENV APP_KEY=base64:2fl3rk3lI6+k9tJ0lZp2aXh6sL9mN4pQ7rT1vW5yZ8A=
RUN composer install --no-interaction --prefer-dist --no-scripts \
&& ./vendor/bin/phpunit --no-coverage
# Default production image target (use --target base for deploy builds)
FROM base AS production