initial commit
This commit is contained in:
135
docker/7.4/Dockerfile
Normal file
135
docker/7.4/Dockerfile
Normal file
@@ -0,0 +1,135 @@
|
||||
# Multi-stage Alpine-based PHP 7.4 FPM image optimized for WordPress
|
||||
# - builds extensions in a builder stage (isolation)
|
||||
# - copies only runtime bits into the final image
|
||||
# - minimal runtime packages, production php.ini and opcache tuned
|
||||
# - includes common WordPress extensions: pdo_mysql, mysqli, gd, zip, exif,
|
||||
# intl, xml, xmlrpc (if compiled), bcmath, opcache, mbstring, curl, fileinfo
|
||||
|
||||
ARG BASE_TAG=7.4-fpm-alpine3.16
|
||||
FROM php:${BASE_TAG} AS build
|
||||
|
||||
RUN set -eux; \
|
||||
apk add --no-cache --virtual .build-deps \
|
||||
$PHPIZE_DEPS \
|
||||
autoconf \
|
||||
gcc \
|
||||
g++ \
|
||||
make \
|
||||
pkgconfig \
|
||||
bash \
|
||||
freetype-dev \
|
||||
libjpeg-turbo-dev \
|
||||
libpng-dev \
|
||||
libxml2-dev \
|
||||
zlib-dev \
|
||||
icu-dev \
|
||||
libzip-dev \
|
||||
oniguruma-dev \
|
||||
mariadb-dev \
|
||||
; \
|
||||
# Configure and build common extensions required by WordPress
|
||||
docker-php-ext-configure gd --with-freetype --with-jpeg; \
|
||||
docker-php-ext-install -j"$(nproc)" \
|
||||
gd \
|
||||
mysqli \
|
||||
pdo \
|
||||
pdo_mysql \
|
||||
zip \
|
||||
exif \
|
||||
intl \
|
||||
bcmath \
|
||||
opcache \
|
||||
xml \
|
||||
mbstring \
|
||||
xmlrpc \
|
||||
soap \
|
||||
pcntl \
|
||||
; \
|
||||
pecl channel-update pecl.php.net; \
|
||||
pecl install redis && docker-php-ext-enable redis; \
|
||||
# Use production php.ini as a base
|
||||
cp "$PHP_INI_DIR/php.ini-production" "$PHP_INI_DIR/php.ini"; \
|
||||
# Clean build deps (we'll copy only runtime artifacts to final image)
|
||||
apk del .build-deps; \
|
||||
rm -rf /var/cache/apk/* /tmp/*
|
||||
|
||||
FROM php:${BASE_TAG} AS runtime
|
||||
|
||||
# Install only runtime library packages (no -dev)
|
||||
RUN set -eux; \
|
||||
apk add --no-cache \
|
||||
freetype \
|
||||
libjpeg-turbo \
|
||||
libpng \
|
||||
libxml2 \
|
||||
zlib \
|
||||
icu-libs \
|
||||
libzip \
|
||||
mariadb-client \
|
||||
openssl \
|
||||
ca-certificates \
|
||||
tzdata \
|
||||
; \
|
||||
update-ca-certificates || true
|
||||
|
||||
# Copy built PHP and extensions from the build stage
|
||||
COPY --from=build /usr/local/lib/php /usr/local/lib/php
|
||||
COPY --from=build /usr/local/etc/php /usr/local/etc/php
|
||||
|
||||
# Create a non-root application user and prepare webroot directory
|
||||
RUN addgroup -g 1000 app || true; \
|
||||
adduser -D -u 1000 -G app app || true; \
|
||||
mkdir -p /var/www/html; \
|
||||
chown -R app:app /var/www/html; \
|
||||
# Ensure php-fpm runtime directories exist and are writable by the app user
|
||||
mkdir -p /var/run/php /run/php /var/log/php; \
|
||||
chown -R app:app /var/run/php /run/php /var/log/php
|
||||
|
||||
# Minimal security / production tuning for opcache and PHP
|
||||
RUN set -eux; \
|
||||
{ \
|
||||
echo 'opcache.enable=1'; \
|
||||
echo 'opcache.memory_consumption=128'; \
|
||||
echo 'opcache.interned_strings_buffer=8'; \
|
||||
echo 'opcache.max_accelerated_files=10000'; \
|
||||
echo 'opcache.revalidate_freq=2'; \
|
||||
echo 'opcache.fast_shutdown=1'; \
|
||||
echo 'opcache.enable_file_override=0'; \
|
||||
} > /usr/local/etc/php/conf.d/zz-opcache.ini; \
|
||||
{ \
|
||||
echo 'expose_php = Off'; \
|
||||
echo 'display_errors = Off'; \
|
||||
echo 'log_errors = On'; \
|
||||
echo 'error_log = /proc/self/fd/2'; \
|
||||
} > /usr/local/etc/php/conf.d/zz-hardening.ini
|
||||
|
||||
# Expose FPM socket port (if using TCP); keep default unix socket when preferred
|
||||
EXPOSE 9000
|
||||
|
||||
# Healthcheck: ensure php-fpm master process exists
|
||||
HEALTHCHECK --interval=30s --timeout=3s --start-period=5s --retries=3 CMD pgrep -f "php-fpm" || exit 1
|
||||
|
||||
WORKDIR /var/www/html
|
||||
|
||||
# Copy pool configuration from build context (keep a copy in each lane to
|
||||
# allow building with context set to the lane directory).
|
||||
COPY --chown=root:root docker/php-fpm/www.conf /usr/local/etc/php-fpm.d/www.conf
|
||||
# Copy a shared entrypoint that can optionally fix permissions on the mounted webroot
|
||||
COPY --chown=root:root docker/php-fpm/entrypoint.sh /usr/local/bin/entrypoint.sh
|
||||
RUN chmod 755 /usr/local/bin/entrypoint.sh
|
||||
|
||||
# Use a small entrypoint to optionally chown mounted volumes at container start.
|
||||
ENTRYPOINT ["/usr/local/bin/entrypoint.sh"]
|
||||
|
||||
# Run php-fpm master as root and have workers drop to the non-root `app` user.
|
||||
# This avoids permission surprises while keeping workers unprivileged.
|
||||
USER root
|
||||
|
||||
CMD ["php-fpm"]
|
||||
|
||||
# Notes:
|
||||
# - The build stage compiles extensions and leaves a production php.ini in place.
|
||||
# - The final image copies only the runtime artifacts and installs only runtime libs
|
||||
# to keep it small.
|
||||
# - If you want to run PHP-FPM as a non-root user in container, you will need to
|
||||
# adjust the php-fpm pool user/group configuration in /usr/local/etc/php-fpm.d/www.conf
|
||||
11
docker/nginx/Dockerfile
Normal file
11
docker/nginx/Dockerfile
Normal file
@@ -0,0 +1,11 @@
|
||||
FROM nginx:alpine-slim
|
||||
|
||||
# Add a minimal, secure nginx config that works with the php-fpm service
|
||||
COPY nginx.conf /etc/nginx/conf.d/default.conf
|
||||
|
||||
# Create directories for logs and ensure permissions (nginx user is nginx)
|
||||
RUN mkdir -p /var/www/html /var/log/nginx && chown -R nginx:nginx /var/www/html /var/log/nginx
|
||||
|
||||
EXPOSE 80
|
||||
|
||||
CMD ["nginx", "-g", "daemon off;"]
|
||||
69
docker/nginx/nginx.conf
Normal file
69
docker/nginx/nginx.conf
Normal file
@@ -0,0 +1,69 @@
|
||||
server {
|
||||
listen 80;
|
||||
listen [::]:80;
|
||||
|
||||
server_name _;
|
||||
root /var/www/html;
|
||||
index index.php index.html index.htm;
|
||||
|
||||
# Basic security headers (can be extended per-site)
|
||||
add_header X-Frame-Options "SAMEORIGIN" always;
|
||||
add_header X-Content-Type-Options "nosniff" always;
|
||||
add_header X-XSS-Protection "1; mode=block" always;
|
||||
add_header Referrer-Policy "no-referrer-when-downgrade" always;
|
||||
add_header Strict-Transport-Security "max-age=31536000; includeSubDomains; preload" always;
|
||||
|
||||
# Deny access to hidden files and directories
|
||||
location ~ (^|/)[.] {
|
||||
deny all;
|
||||
access_log off;
|
||||
log_not_found off;
|
||||
}
|
||||
|
||||
# Static files: long cache, immutable where appropriate
|
||||
location ~* \.(?:css|js|gif|jpe?g|png|ico|svg|woff2?|ttf|eot)$ {
|
||||
try_files $uri =404;
|
||||
access_log off;
|
||||
expires 30d;
|
||||
add_header Cache-Control "public, max-age=2592000, immutable";
|
||||
}
|
||||
|
||||
location = /favicon.ico { access_log off; log_not_found off; }
|
||||
location = /robots.txt { access_log off; log_not_found off; allow all; }
|
||||
|
||||
# Main front controller; fall back to index.php
|
||||
location / {
|
||||
try_files $uri $uri/ /index.php$is_args$args;
|
||||
}
|
||||
|
||||
# PHP-FPM handling; pass to php-fpm:9000 (docker service name)
|
||||
location ~ [^/]
|
||||
\.php(/|$) {
|
||||
# Prevent direct access to PHP files in uploads or other writable dirs if necessary
|
||||
try_files $document_root$fastcgi_script_name =404;
|
||||
|
||||
fastcgi_split_path_info ^(.+\.php)(/.+)$;
|
||||
# Use TCP FPM backend service name. Matches the php-fpm image we built.
|
||||
fastcgi_pass php-fpm:9000;
|
||||
fastcgi_index index.php;
|
||||
include fastcgi_params;
|
||||
fastcgi_param SCRIPT_FILENAME $document_root$fastcgi_script_name;
|
||||
fastcgi_param PATH_INFO $fastcgi_path_info;
|
||||
fastcgi_param HTTPS $https if_not_empty;
|
||||
fastcgi_read_timeout 300;
|
||||
}
|
||||
|
||||
# Block access to .ht* files
|
||||
location ~* /\.(?:ht|git) {
|
||||
deny all;
|
||||
}
|
||||
|
||||
# Optional: small buffer for large headers (WordPress with many cookies/plugins)
|
||||
fastcgi_buffers 16 16k;
|
||||
fastcgi_buffer_size 32k;
|
||||
|
||||
# Prevent clickjacking on all responses
|
||||
add_header X-Frame-Options "SAMEORIGIN";
|
||||
}
|
||||
|
||||
# Default server; allow override by mounting /etc/nginx/conf.d/default.conf
|
||||
19
docker/php-fpm/entrypoint.sh
Normal file
19
docker/php-fpm/entrypoint.sh
Normal file
@@ -0,0 +1,19 @@
|
||||
#!/bin/sh
|
||||
set -euo pipefail
|
||||
|
||||
# Entrypoint for php-fpm images.
|
||||
# If CHOWN_ON_START is set to '1' or 'true', recursively chown the webroot
|
||||
# to the 'app' user (UID 1000). This is optional and must be explicitly enabled
|
||||
# via environment (safer for multi-tenant hosts).
|
||||
|
||||
: ${CHOWN_ON_START:=}
|
||||
if [ "${CHOWN_ON_START}" = "1" ] || [ "${CHOWN_ON_START}" = "true" ]; then
|
||||
echo "[entrypoint] CHOWN_ON_START enabled — fixing ownership of /var/www/html"
|
||||
# Only run chown if the directory exists
|
||||
if [ -d /var/www/html ]; then
|
||||
chown -R 1000:1000 /var/www/html || true
|
||||
fi
|
||||
fi
|
||||
|
||||
# Exec the given command (php-fpm by default)
|
||||
exec "$@"
|
||||
43
docker/php-fpm/www.conf
Normal file
43
docker/php-fpm/www.conf
Normal file
@@ -0,0 +1,43 @@
|
||||
; Shared php-fpm pool configuration for containers
|
||||
; Designed to be reused across php-fpm versions in this repo
|
||||
|
||||
[www]
|
||||
; Listen on TCP to be container-friendly
|
||||
listen = 0.0.0.0:9000
|
||||
|
||||
; Run workers as the unprivileged 'app' user
|
||||
user = app
|
||||
group = app
|
||||
|
||||
; Ensure socket ownership/mode if a socket is used
|
||||
listen.owner = app
|
||||
listen.group = app
|
||||
listen.mode = 0660
|
||||
|
||||
; Process management
|
||||
pm = dynamic
|
||||
pm.max_children = 10
|
||||
pm.start_servers = 2
|
||||
pm.min_spare_servers = 1
|
||||
pm.max_spare_servers = 3
|
||||
pm.max_requests = 500
|
||||
|
||||
; Timeouts and logging
|
||||
request_terminate_timeout = 300s
|
||||
request_slowlog_timeout = 5s
|
||||
slowlog = /var/log/php/www-slow.log
|
||||
|
||||
; Helpful logging for debugging worker crashes
|
||||
catch_workers_output = yes
|
||||
access.log = /var/log/php/www-access.log
|
||||
|
||||
; Keep environment variables (useful if you pass DB credentials via env)
|
||||
clear_env = no
|
||||
|
||||
; Security and restart behaviour
|
||||
emergency_restart_threshold = 10
|
||||
emergency_restart_interval = 1m
|
||||
process_control_timeout = 10s
|
||||
|
||||
; Ensure stdout/stderr are visible in container logs
|
||||
; php-fpm will already write logs to paths above; ensure the directory exists in image
|
||||
Reference in New Issue
Block a user