Skip to content

Commit d04f20f

Browse files
committed
refactor(docker, php): modernize image architecture and harden PHP configurations
Refactored the Docker image architecture and PHP configuration to fix vulnerabilities, improve performance, and align with production best practices. - Removed Supervisor (CVE-2023-27482) and adopted Docker’s single-process model with `docker-entrypoint.sh` managing Redis/PHP-FPM in background and Nginx in foreground. - Added configurable `ALPINE_VERSION` in `.env` and build scripts for easier base image upgrades. - Moved critical OPcache directives (INI_SYSTEM) from `www.conf` to `php.ini` to fix FPM initialization errors. - Removed deprecated OPcache directives (`opcache.fast_shutdown`, `opcache.consistency_checks`). - Enabled `opcache.save_comments` for framework compatibility (Symfony, Laravel). - Fixed `session.save_path` to `tcp://redis:6379` for proper container communication. - Adjusted `disable_functions` list to allow required functions like `curl_exec`. - Updated Makefile: replaced `supervisorctl` with `nginx -s reload` and added `--env-file .env` to `docker run` for proper environment injection. BREAKING CHANGE: Supervisor was removed. Process management is now handled by `docker-entrypoint.sh`. Commands using `supervisorctl` will no longer work. To reload Nginx use `docker exec <container> nginx -s reload`.
1 parent 4daffad commit d04f20f

12 files changed

Lines changed: 56 additions & 31 deletions

File tree

.env.example

Lines changed: 5 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -7,6 +7,7 @@
77
PHP_VERSION=8.4
88
NGINX_VERSION=1.27.3
99
REDIS_VERSION=7.2
10+
ALPINE_VERSION=3.21
1011
COMPOSER_VERSION=2.8.12
1112
SYMFONY_CLI_VERSION=7.3.0
1213

@@ -61,7 +62,7 @@ PHP_SESSION_SAVE_PATH="tcp://redis:6379"
6162

6263
# PHP-FPM Configuration
6364
PHP_FPM_PM=dynamic
64-
PHP_FPM_PM_MAX_CHILDREN=50
65+
PHP_FPM_PM_MAX_CHILDREN=60
6566
PHP_FPM_PM_START_SERVERS=5
6667
PHP_FPM_PM_MIN_SPARE_SERVERS=5
6768
PHP_FPM_PM_MAX_SPARE_SERVERS=10
@@ -94,9 +95,9 @@ REDIS_LOG_FILE=/var/log/redis/redis.log
9495
REDIS_SAVE="900 1 300 10 60 10000"
9596

9697
# Supervisor Configuration
97-
SUPERVISOR_LOG_LEVEL=info
98-
SUPERVISOR_LOG_FILE=/var/log/supervisor/supervisord.log
99-
SUPERVISOR_PID_FILE=/var/run/supervisord.pid
98+
# SUPERVISOR_LOG_LEVEL=info
99+
# SUPERVISOR_LOG_FILE=/var/log/supervisor/supervisord.log
100+
# SUPERVISOR_PID_FILE=/var/run/supervisord.pid
100101

101102
# Security Settings
102103
SECURITY_HEADERS=true

.github/workflows/publish.yml

Whitespace-only changes.

DOCKER_HUB_OVERVIEW.md

Whitespace-only changes.

Dockerfile

Lines changed: 8 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -6,6 +6,7 @@
66
ARG PHP_VERSION=8.4
77
ARG NGINX_VERSION=1.27.3
88
ARG REDIS_VERSION=7.2
9+
ARG ALPINE_VERSION=3.21
910
ARG VERSION=1.2.0
1011

1112
# Stage 1: Redis binaries
@@ -15,7 +16,7 @@ FROM redis:${REDIS_VERSION}-alpine AS redis-build
1516
FROM nginx:${NGINX_VERSION}-alpine AS nginx-build
1617

1718
# Stage 3: Main application
18-
FROM php:${PHP_VERSION}-fpm-alpine AS base
19+
FROM php:${PHP_VERSION}-fpm-alpine${ALPINE_VERSION} AS base
1920

2021
# Set shell with pipefail for robust error handling
2122
# Reference: https://docs.docker.com/engine/reference/builder/#shell
@@ -25,6 +26,7 @@ SHELL ["/bin/ash", "-o", "pipefail", "-c"]
2526
ARG PHP_VERSION
2627
ARG NGINX_VERSION
2728
ARG REDIS_VERSION
29+
ARG ALPINE_VERSION
2830
ARG COMPOSER_VERSION=2.8.12
2931
ARG SYMFONY_CLI_VERSION=7.3.0
3032
ARG PHP_CORE_EXTENSIONS="pdo pdo_mysql opcache intl zip bcmath gd mbstring xml"
@@ -69,7 +71,7 @@ RUN set -eux; \
6971
shadow \
7072
su-exec \
7173
tini \
72-
supervisor \
74+
# supervisor \
7375
git \
7476
curl \
7577
wget \
@@ -280,7 +282,7 @@ RUN set -eux; \
280282
/var/log/nginx \
281283
/var/log/php \
282284
/var/log/redis \
283-
/var/log/supervisor \
285+
# /var/log/supervisor \
284286
/var/log/symfony \
285287
/var/run \
286288
/var/run/php \
@@ -345,7 +347,7 @@ COPY php/php.ini /usr/local/etc/php/php.ini.template
345347
COPY php/php-fpm.conf /usr/local/etc/php-fpm.conf.template
346348
COPY php/www.conf /usr/local/etc/php-fpm.d/www.conf.template
347349
COPY redis/redis.conf /etc/redis/redis.conf.template
348-
COPY supervisor/supervisord.conf /etc/supervisor/supervisord.conf
350+
# COPY supervisor/supervisord.conf /etc/supervisor/supervisord.conf
349351

350352
# Copy entrypoint script
351353
COPY docker-entrypoint.sh /usr/local/bin/docker-entrypoint
@@ -421,4 +423,5 @@ VOLUME ["/var/www/html", "/var/log", "/var/lib/redis"]
421423
# Use tini as init system for proper signal handling
422424
# Reference: https://github.com/krallin/tini
423425
ENTRYPOINT ["/sbin/tini", "--", "docker-entrypoint"]
424-
CMD ["supervisord", "-c", "/etc/supervisor/supervisord.conf"]
426+
# CMD ["supervisord", "-c", "/etc/supervisor/supervisord.conf"]
427+
CMD ["start"]

Makefile

Lines changed: 5 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -136,6 +136,7 @@ run-test: ## run test container with comprehensive health check
136136
@docker run -d \
137137
--name $(TEST_CONTAINER) \
138138
-p 8080:80 \
139+
--env-file .env \
139140
-v $(PWD)/logs:/var/log \
140141
$(FULL_IMAGE):test
141142
@echo ""
@@ -275,6 +276,7 @@ run: ## Run local container for demo/testing
275276
@docker run -d \
276277
--name $(LOCAL_CONTAINER) \
277278
-p 8080:80 \
279+
--env-file .env \
278280
-v $(PWD)/logs:/var/log \
279281
$(FULL_IMAGE):latest
280282
@echo "$(GREEN)✓ Container running at http://localhost:8080$(NC)"
@@ -309,6 +311,7 @@ run-with-app: ## Run local container with mounted application
309311
@docker run -d \
310312
--name $(LOCAL_CONTAINER) \
311313
-p 8080:80 \
314+
--env-file .env \
312315
-v $(PWD)/app:/var/www/html \
313316
-v $(PWD)/logs:/var/log \
314317
$(FULL_IMAGE):latest
@@ -317,7 +320,8 @@ run-with-app: ## Run local container with mounted application
317320
@echo ""
318321
@echo "$(BLUE)Next steps:$(NC)"
319322
@echo " 1. Create your $(CYAN)app/public/index.php$(NC)"
320-
@echo " 2. Run $(CYAN)docker exec $(LOCAL_CONTAINER) supervisorctl restart nginx$(NC)"
323+
# @echo " 2. Run $(CYAN)docker exec $(LOCAL_CONTAINER) supervisorctl restart nginx$(NC)"
324+
@echo " 2. Run $(CYAN)docker exec $(LOCAL_CONTAINER) nginx -s reload$(NC)"
321325
@echo " 3. Visit http://localhost:8080"
322326

323327
.PHONY: stop

README.md

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -100,7 +100,7 @@ All configurations via `.env` file:
100100
PHP_MEMORY_LIMIT=256M
101101
PHP_OPCACHE_MEMORY=256
102102
PHP_OPCACHE_JIT=tracing
103-
PHP_FPM_PM_MAX_CHILDREN=50
103+
PHP_FPM_PM_MAX_CHILDREN=60
104104

105105
# Environment
106106
APP_ENV=production

TESTING.md

Lines changed: 1 addition & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1659,6 +1659,4 @@ For testing issues:
16591659
- [IMAGE_USAGE_GUIDE.md](IMAGE_USAGE_GUIDE.md) - Learn how to use the published image
16601660
- [README.md](README.md) - Project overview
16611661

1662-
---
1663-
1664-
<sub>Last updated: $(date +%Y-%m-%d) | Version: $(cat VERSION)</sub>
1662+
---

build-from-env.sh

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -141,6 +141,7 @@ echo -e "${YELLOW}Stack Versions:${NC}"
141141
echo " • PHP: ${PHP_VERSION}"
142142
echo " • Nginx: ${NGINX_VERSION}"
143143
echo " • Redis: ${REDIS_VERSION}"
144+
echo " • Alpine: ${ALPINE_VERSION}"
144145
echo " • Composer: ${COMPOSER_VERSION}"
145146
echo " • Symfony CLI: ${SYMFONY_CLI_VERSION}"
146147
echo ""
@@ -212,6 +213,7 @@ BUILD_CMD="$BUILD_CMD \
212213
--build-arg PHP_VERSION=${PHP_VERSION} \
213214
--build-arg NGINX_VERSION=${NGINX_VERSION} \
214215
--build-arg REDIS_VERSION=${REDIS_VERSION} \
216+
--build-arg ALPINE_VERSION=${ALPINE_VERSION} \
215217
--build-arg COMPOSER_VERSION=${COMPOSER_VERSION} \
216218
--build-arg SYMFONY_CLI_VERSION=${SYMFONY_CLI_VERSION} \
217219
--build-arg PHP_CORE_EXTENSIONS=\"${PHP_CORE_EXTENSIONS}\" \

docker-entrypoint.sh

Lines changed: 29 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -119,7 +119,7 @@ fi
119119
log_info "Creating required directories..."
120120
chown -R nginx:nginx /var/log/php /var/log/nginx /var/run/php
121121
chown -R redis:redis /var/log/redis || true
122-
chown -R root:root /var/log/supervisor
122+
# chown -R root:root /var/log/supervisor
123123
chown -R nginx:nginx /var/run/nginx # Nginx run dir
124124

125125
# Fix permissions for session directory if using files
@@ -294,12 +294,30 @@ fi
294294
# ==============================================================================
295295
# START SERVICES BASED ON COMMAND
296296
# ==============================================================================
297-
298-
# Comandos específicos
297+
# removed:
298+
# supervisord|supervisor)
299+
# log_info "Starting all services with Supervisor..."
300+
# exec /usr/bin/supervisord -c /etc/supervisor/supervisord.conf
301+
# ;;
302+
# Especifics commands
299303
case "$1" in
300-
supervisord|supervisor)
301-
log_info "Starting all services with Supervisor..."
302-
exec /usr/bin/supervisord -c /etc/supervisor/supervisord.conf
304+
start)
305+
log_info "Starting all services..."
306+
307+
# Start Redis in background (daemonize)
308+
log_info " -> Starting Redis..."
309+
redis-server /etc/redis/redis.conf --daemonize yes
310+
311+
# Start PHP-FPM in background (daemonize)
312+
log_info " -> Starting PHP-FPM..."
313+
php-fpm -D
314+
315+
# Start Nginx in foreground. The `exec` command is crucial here.
316+
# It replaces the script process with the Nginx process, making Nginx
317+
# the main container process (PID 1). This ensures it receives
318+
# Docker signals correctly (e.g., docker stop).
319+
log_info " -> Starting Nginx (foreground)..."
320+
exec nginx -g 'daemon off;'
303321
;;
304322
php-fpm)
305323
log_info "Starting PHP-FPM only..."
@@ -320,12 +338,12 @@ case "$1" in
320338
;;
321339
*)
322340
# Default: start supervisord if no command given
323-
if [ "$#" -eq 0 ]; then
324-
log_info "Starting all services with Supervisor (default)..."
325-
exec /usr/bin/supervisord -c /etc/supervisor/supervisord.conf
326-
else
341+
# if [ "$#" -eq 0 ]; then
342+
# log_info "Starting all services with Supervisor (default)..."
343+
# exec /usr/bin/supervisord -c /etc/supervisor/supervisord.conf
344+
# else
327345
# Pass through any command
328346
exec "$@"
329-
fi
347+
# fi
330348
;;
331349
esac

php/php.ini

Lines changed: 1 addition & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -104,11 +104,10 @@ opcache.revalidate_freq = ${PHP_OPCACHE_REVALIDATE_FREQ}
104104
opcache.revalidate_path = 0
105105
opcache.save_comments = 1
106106
opcache.enable_file_override = 0
107-
opcache.optimization_level = 0x7FFFBFFF
107+
opcache.optimization_level = 0x7FFEBFFF
108108
opcache.dups_fix = 0
109109
opcache.blacklist_filename =
110110
opcache.max_file_size = 0
111-
opcache.consistency_checks = 0
112111
opcache.force_restart_timeout = 180
113112
opcache.error_log =
114113
opcache.log_verbosity_level = 1

0 commit comments

Comments
 (0)