Attempt to be prod ready
This commit is contained in:
@@ -1,118 +1,136 @@
|
||||
# FROM php:8.2-fpm
|
||||
|
||||
# # Install dependencies
|
||||
# RUN apt-get update && apt-get install -y \
|
||||
# git \
|
||||
# unzip \
|
||||
# libzip-dev \
|
||||
# libpng-dev \
|
||||
# libjpeg-dev \
|
||||
# libonig-dev \
|
||||
# libxml2-dev \
|
||||
# zip \
|
||||
# && docker-php-ext-install pdo pdo_mysql zip gd mbstring exif pcntl bcmath intl opcache
|
||||
|
||||
# # Install Composer
|
||||
# COPY --from=composer:2 /usr/bin/composer /usr/bin/composer
|
||||
|
||||
# # Copy PHP config
|
||||
# COPY docker/php/php.ini /usr/local/etc/php/
|
||||
|
||||
# WORKDIR /var/www/html
|
||||
|
||||
# -----------------------------------------------------------------------------
|
||||
# Base PHP-FPM with Composer + Symfony-friendly extensions
|
||||
# -----------------------------------------------------------------------------
|
||||
FROM php:8.2-fpm-alpine AS base
|
||||
WORKDIR /var/www/html
|
||||
|
||||
# System dependencies
|
||||
RUN apk add --no-cache \
|
||||
bash git unzip icu-dev libpng-dev libjpeg-turbo-dev libwebp-dev \
|
||||
libzip-dev oniguruma-dev libxml2-dev postgresql-dev zlib-dev
|
||||
|
||||
# PHP extensions commonly used by Symfony
|
||||
RUN docker-php-ext-configure gd --with-jpeg --with-webp \
|
||||
&& docker-php-ext-install -j"$(nproc)" \
|
||||
intl \
|
||||
gd \
|
||||
pdo_pgsql \
|
||||
opcache \
|
||||
mbstring \
|
||||
zip \
|
||||
xml
|
||||
|
||||
# Composer available in the running container (dev + prod)
|
||||
COPY --from=composer:2.7 /usr/bin/composer /usr/bin/composer
|
||||
|
||||
# Recommended PHP settings (tweak as needed)
|
||||
RUN { \
|
||||
echo "memory_limit=512M"; \
|
||||
echo "upload_max_filesize=50M"; \
|
||||
echo "post_max_size=50M"; \
|
||||
echo "date.timezone=UTC"; \
|
||||
} > /usr/local/etc/php/conf.d/php-recommended.ini \
|
||||
&& { \
|
||||
echo "opcache.enable=1"; \
|
||||
echo "opcache.enable_cli=1"; \
|
||||
echo "opcache.memory_consumption=256"; \
|
||||
echo "opcache.interned_strings_buffer=16"; \
|
||||
echo "opcache.max_accelerated_files=20000"; \
|
||||
echo "opcache.validate_timestamps=0"; \
|
||||
echo "opcache.jit=tracing"; \
|
||||
echo "opcache.jit_buffer_size=128M"; \
|
||||
} > /usr/local/etc/php/conf.d/opcache-recommended.ini
|
||||
|
||||
# Small healthcheck file for Nginx
|
||||
RUN mkdir -p public && printf "OK" > public/healthz
|
||||
|
||||
# Ensure correct user
|
||||
RUN addgroup -g 1000 app && adduser -D -G app -u 1000 app
|
||||
# php-fpm uses www-data; keep both available
|
||||
RUN chown -R www-data:www-data /var/www
|
||||
|
||||
# -----------------------------------------------------------------------------
|
||||
# Development image (mount your code via docker-compose volumes)
|
||||
# -----------------------------------------------------------------------------
|
||||
FROM base AS dev
|
||||
ENV APP_ENV=dev
|
||||
# Optional: enable Xdebug (uncomment to use)
|
||||
# RUN apk add --no-cache $PHPIZE_DEPS \
|
||||
# && pecl install xdebug \
|
||||
# && docker-php-ext-enable xdebug \
|
||||
# && { \
|
||||
# echo "xdebug.mode=debug,develop"; \
|
||||
# echo "xdebug.client_host=host.docker.internal"; \
|
||||
# } > /usr/local/etc/php/conf.d/xdebug.ini
|
||||
# Composer cache directory (faster installs inside container)
|
||||
ENV COMPOSER_CACHE_DIR=/tmp/composer
|
||||
CMD ["php-fpm"]
|
||||
|
||||
# -----------------------------------------------------------------------------
|
||||
# Production image (copies your app + installs deps + warms cache)
|
||||
# -----------------------------------------------------------------------------
|
||||
FROM base AS prod
|
||||
ENV APP_ENV=prod
|
||||
# Copy only manifests first (better layer caching); ignore if missing
|
||||
COPY composer.json composer.lock* symfony.lock* ./
|
||||
# Install vendors (no scripts here; run later with console if needed)
|
||||
RUN --mount=type=cache,target=/tmp/composer \
|
||||
if [ -f composer.json ]; then \
|
||||
composer install --no-dev --prefer-dist --no-interaction --no-progress --no-scripts; \
|
||||
fi
|
||||
|
||||
# Copy the rest of the app
|
||||
COPY . /var/www/html
|
||||
|
||||
# If Symfony console exists, finalize install & warm cache
|
||||
RUN if [ -f bin/console ]; then \
|
||||
set -ex; \
|
||||
composer dump-autoload --no-dev --optimize; \
|
||||
php bin/console cache:clear --no-warmup; \
|
||||
php bin/console cache:warmup; \
|
||||
mkdir -p var && chown -R www-data:www-data var; \
|
||||
fi
|
||||
|
||||
USER www-data
|
||||
CMD ["php-fpm"]
|
||||
FROM php:8.2-fpm-alpine AS base
|
||||
|
||||
ARG APP_ENV=dev
|
||||
ENV APP_ENV=${APP_ENV}
|
||||
|
||||
WORKDIR /var/www/html
|
||||
|
||||
# System dependencies shared across images
|
||||
RUN apk add --no-cache \
|
||||
bash \
|
||||
git \
|
||||
unzip \
|
||||
icu-dev \
|
||||
libpng-dev \
|
||||
libjpeg-turbo-dev \
|
||||
libwebp-dev \
|
||||
libzip-dev \
|
||||
oniguruma-dev \
|
||||
libxml2-dev \
|
||||
postgresql-dev \
|
||||
sqlite-dev \
|
||||
zlib-dev \
|
||||
su-exec
|
||||
|
||||
# PHP extensions commonly used by Symfony (plus both Postgres + SQLite)
|
||||
RUN docker-php-ext-configure gd --with-jpeg --with-webp \
|
||||
&& docker-php-ext-install -j"$(nproc)" \
|
||||
intl \
|
||||
gd \
|
||||
pdo_pgsql \
|
||||
pdo_sqlite \
|
||||
opcache \
|
||||
mbstring \
|
||||
zip \
|
||||
xml
|
||||
|
||||
# Composer available in every stage (dev + prod)
|
||||
COPY --from=composer:2.7 /usr/bin/composer /usr/bin/composer
|
||||
|
||||
# Recommended PHP settings (tweak as needed)
|
||||
RUN { \
|
||||
echo "memory_limit=512M"; \
|
||||
echo "upload_max_filesize=50M"; \
|
||||
echo "post_max_size=50M"; \
|
||||
echo "date.timezone=UTC"; \
|
||||
} > /usr/local/etc/php/conf.d/php-recommended.ini \
|
||||
&& { \
|
||||
echo "opcache.enable=1"; \
|
||||
echo "opcache.enable_cli=1"; \
|
||||
echo "opcache.memory_consumption=256"; \
|
||||
echo "opcache.interned_strings_buffer=16"; \
|
||||
echo "opcache.max_accelerated_files=20000"; \
|
||||
echo "opcache.validate_timestamps=0"; \
|
||||
echo "opcache.jit=tracing"; \
|
||||
echo "opcache.jit_buffer_size=128M"; \
|
||||
} > /usr/local/etc/php/conf.d/opcache-recommended.ini
|
||||
|
||||
# Small healthcheck file for HTTP probes
|
||||
RUN mkdir -p public && printf "OK" > public/healthz
|
||||
|
||||
# Ensure unprivileged app user exists
|
||||
RUN addgroup -g 1000 app && adduser -D -G app -u 1000 app \
|
||||
&& chown -R www-data:www-data /var/www
|
||||
|
||||
# -----------------------------------------------------------------------------
|
||||
# Development image (mount your code via docker-compose volumes)
|
||||
# -----------------------------------------------------------------------------
|
||||
FROM base AS dev
|
||||
ARG APP_ENV=dev
|
||||
ENV APP_ENV=${APP_ENV}
|
||||
ENV APP_DEBUG=1
|
||||
|
||||
# Optional: enable Xdebug by uncommenting below
|
||||
# RUN apk add --no-cache $PHPIZE_DEPS \
|
||||
# && pecl install xdebug \
|
||||
# && docker-php-ext-enable xdebug \
|
||||
# && { \
|
||||
# echo "xdebug.mode=debug,develop"; \
|
||||
# echo "xdebug.client_host=host.docker.internal"; \
|
||||
# } > /usr/local/etc/php/conf.d/xdebug.ini
|
||||
|
||||
ENV COMPOSER_CACHE_DIR=/tmp/composer
|
||||
CMD ["php-fpm"]
|
||||
|
||||
# -----------------------------------------------------------------------------
|
||||
# Production image (copies your app + installs deps + warms cache)
|
||||
# -----------------------------------------------------------------------------
|
||||
FROM base AS prod
|
||||
ARG APP_ENV=prod
|
||||
ENV APP_ENV=${APP_ENV}
|
||||
ENV APP_DEBUG=0 \
|
||||
DATABASE_DRIVER=sqlite \
|
||||
DATABASE_SQLITE_PATH=/var/www/html/var/data/database.sqlite \
|
||||
RUN_MIGRATIONS_ON_START=1
|
||||
|
||||
# Copy only composer manifests for layer caching
|
||||
COPY composer.json composer.lock* symfony.lock* ./
|
||||
|
||||
# Install vendors (cached)
|
||||
RUN --mount=type=cache,target=/tmp/composer \
|
||||
if [ -f composer.json ]; then \
|
||||
composer install --no-dev --prefer-dist --no-interaction --no-progress --no-scripts; \
|
||||
fi
|
||||
|
||||
# Copy the rest of the app
|
||||
COPY . /var/www/html
|
||||
|
||||
# Finalize install & warm cache
|
||||
RUN if [ -f bin/console ]; then \
|
||||
set -ex; \
|
||||
composer dump-autoload --no-dev --optimize; \
|
||||
php bin/console cache:clear --no-warmup; \
|
||||
php bin/console cache:warmup; \
|
||||
mkdir -p var var/data public/uploads; \
|
||||
chown -R www-data:www-data var public/uploads; \
|
||||
fi
|
||||
|
||||
# Runtime web stack (nginx + supervisor) for a single immutable container
|
||||
RUN apk add --no-cache nginx supervisor curl
|
||||
|
||||
COPY docker/prod/nginx.conf /etc/nginx/http.d/default.conf
|
||||
COPY docker/prod/supervisord.conf /etc/supervisor/conf.d/app.conf
|
||||
COPY docker/prod/entrypoint.sh /entrypoint.sh
|
||||
|
||||
RUN chmod +x /entrypoint.sh \
|
||||
&& mkdir -p /run/nginx /var/log/supervisor \
|
||||
&& chown -R www-data:www-data /var/www/html
|
||||
|
||||
EXPOSE 8080
|
||||
|
||||
ENTRYPOINT ["/entrypoint.sh"]
|
||||
CMD ["supervisord", "-c", "/etc/supervisor/conf.d/app.conf"]
|
||||
|
||||
19
docker/prod/entrypoint.sh
Executable file
19
docker/prod/entrypoint.sh
Executable file
@@ -0,0 +1,19 @@
|
||||
#!/bin/sh
|
||||
set -eu
|
||||
|
||||
if [ "${RUN_MIGRATIONS_ON_START:-1}" = "1" ] && [ -f bin/console ]; then
|
||||
if [ "${DATABASE_DRIVER:-sqlite}" = "sqlite" ]; then
|
||||
SQLITE_PATH="${DATABASE_SQLITE_PATH:-/var/www/html/var/data/database.sqlite}"
|
||||
SQLITE_DIR=$(dirname "${SQLITE_PATH}")
|
||||
mkdir -p "${SQLITE_DIR}"
|
||||
if [ ! -f "${SQLITE_PATH}" ]; then
|
||||
touch "${SQLITE_PATH}"
|
||||
fi
|
||||
chown -R www-data:www-data "${SQLITE_DIR}"
|
||||
fi
|
||||
|
||||
su-exec www-data php bin/console doctrine:migrations:migrate --no-interaction --allow-no-migration
|
||||
fi
|
||||
|
||||
exec "$@"
|
||||
|
||||
29
docker/prod/nginx.conf
Normal file
29
docker/prod/nginx.conf
Normal file
@@ -0,0 +1,29 @@
|
||||
server {
|
||||
listen 8080;
|
||||
server_name _;
|
||||
root /var/www/html/public;
|
||||
|
||||
index index.php;
|
||||
|
||||
location / {
|
||||
try_files $uri /index.php$is_args$args;
|
||||
}
|
||||
|
||||
location ~ \.php$ {
|
||||
include fastcgi_params;
|
||||
fastcgi_pass 127.0.0.1:9000;
|
||||
fastcgi_param SCRIPT_FILENAME $realpath_root$fastcgi_script_name;
|
||||
fastcgi_param DOCUMENT_ROOT $realpath_root;
|
||||
internal;
|
||||
}
|
||||
|
||||
location = /healthz {
|
||||
access_log off;
|
||||
add_header Content-Type text/plain;
|
||||
return 200 "OK";
|
||||
}
|
||||
|
||||
error_log /var/log/nginx/error.log;
|
||||
access_log /var/log/nginx/access.log;
|
||||
}
|
||||
|
||||
21
docker/prod/supervisord.conf
Normal file
21
docker/prod/supervisord.conf
Normal file
@@ -0,0 +1,21 @@
|
||||
[supervisord]
|
||||
nodaemon=true
|
||||
logfile=/var/log/supervisor/supervisord.log
|
||||
pidfile=/var/run/supervisord.pid
|
||||
|
||||
[program:php-fpm]
|
||||
command=/usr/local/sbin/php-fpm --nodaemonize
|
||||
autorestart=true
|
||||
stdout_logfile=/dev/stdout
|
||||
stdout_logfile_maxbytes=0
|
||||
stderr_logfile=/dev/stderr
|
||||
stderr_logfile_maxbytes=0
|
||||
|
||||
[program:nginx]
|
||||
command=/usr/sbin/nginx -g "daemon off;"
|
||||
autorestart=true
|
||||
stdout_logfile=/dev/stdout
|
||||
stdout_logfile_maxbytes=0
|
||||
stderr_logfile=/dev/stderr
|
||||
stderr_logfile_maxbytes=0
|
||||
|
||||
Reference in New Issue
Block a user