AWS ECS中PHP-FPM容器启动后立即终止问题求助
我正尝试将容器化的Nginx + PHP-FPM应用部署到AWS ECS服务。本地Docker Compose环境中一切运行正常,但在AWS ECS创建任务定义并启动任务时,PHP-FPM容器启动后会在1秒内立即退出。我以非root用户运行PHP-FPM容器,已尝试本地运行(正常)、编译生产镜像并使用docker run测试容器、调整任务定义(如禁用卷挂载),也尝试过ECS服务和直接启动任务,但结果一致。
相关细节
Dockerfile
FROM composer:2.6 AS composer FROM php:8.2-fpm-alpine AS php-base ARG UID=1000 ARG GID=1000 RUN apk upgrade --no-cache \ && apk add --no-cache --update --virtual buildDeps gcc=13.2.1_git20231014-r0 \ make=4.4.1-r2 g++=13.2.1_git20231014-r0 autoconf=2.71-r2 linux-headers=6.5-r0 fcgi=2.4.2-r4 RUN docker-php-ext-install mysqli pdo pdo_mysql && docker-php-ext-enable pdo_mysql RUN deluser --remove-home www-data && addgroup -g ${GID} www-data && adduser -u ${UID} -D --ingroup www-data www-data COPY . /var/www/html COPY --from=composer /usr/bin/composer /usr/bin/composer #Install PHP healhcheck script RUN wget -q -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 \ && echo "pm.status_path = /status" >> /usr/local/etc/php-fpm.d/zz-docker.conf #HEALTHCHECK --start-period=3s --interval=5s --timeout=2s CMD php-fpm-healhcheck || exit 1 FROM php-base AS php-prod RUN mv "$PHP_INI_DIR/php.ini-production" "$PHP_INI_DIR/php.ini" \ && composer install --no-ansi --no-dev --no-interaction --no-plugins --no-progress --no-scripts --optimize-autoloader FROM php-base AS php-dev RUN mv "$PHP_INI_DIR/php.ini-development" "$PHP_INI_DIR/php.ini" \ && pecl install xdebug \ && docker-php-ext-enable xdebug \ && echo "xdebug.mode=develop,debug" >> /usr/local/etc/php/conf.d/docker-php-ext-xdebug.ini \ && echo "xdebug.client_host=host.docker.internal" >> /usr/local/etc/php/conf.d/docker-php-ext-xdebug.ini \ && composer install FROM php-prod AS portfolio-prod COPY docker/php-fpm/php-conf.ini $PHP_INI_DIR/conf.d/ RUN mkdir -p /files/profile && mkdir -p /files/portfolio && chown -R www-data:www-data /files USER www-data FROM php-dev AS portfolio-dev COPY docker/php-fpm/php-conf.ini $PHP_INI_DIR/conf.d/ RUN mkdir -p /files/profile && mkdir -p /files/portfolio && chown -R www-data:www-data /files USER www-data
任务定义JSON
{ "taskDefinitionArn": "arn:aws:ecs:eu-central-1:825247853638:task-definition/Mariia-portfolio-task:4", "containerDefinitions": [ { "name": "nginx", "image": "825247853638.dkr.ecr.eu-central-1.amazonaws.com/mariia_portfolio_nginx:latest", "cpu": 512, "memory": 256, "memoryReservation": 128, "portMappings": [ { "name": "nginx-80-tcp", "containerPort": 80, "hostPort": 80, "protocol": "tcp", "appProtocol": "http" } ], "essential": true, "environment": [], "environmentFiles": [], "mountPoints": [], "volumesFrom": [], "dependsOn": [ { "containerName": "php-fpm", "condition": "START" } ], "workingDirectory": "/var/www/html", "ulimits": [], "logConfiguration": { "logDriver": "awslogs", "options": { "awslogs-create-group": "true", "awslogs-group": "/ecs/Mariia-portfolio-task", "awslogs-region": "eu-central-1", "awslogs-stream-prefix": "ecs" }, "secretOptions": [] }, "systemControls": [] }, { "name": "php-fpm", "image": "825247853638.dkr.ecr.eu-central-1.amazonaws.com/mariia_portfolio_php_fpm:latest", "cpu": 1536, "memory": 512, "memoryReservation": 256, "portMappings": [], "essential": true, "environment": [], "environmentFiles": [], "mountPoints": [], "volumesFrom": [], "workingDirectory": "/var/www/html", "logConfiguration": { "logDriver": "awslogs", "options": { "awslogs-create-group": "true", "awslogs-group": "/ecs/Mariia-portfolio-task", "awslogs-region": "eu-central-1", "awslogs-stream-prefix": "ecs" }, "secretOptions": [] }, "systemControls": [] } ], "family": "Mariia-portfolio-task", "taskRoleArn": "arn:aws:iam::825247853638:role/ECSTaskRole", "executionRoleArn": "arn:aws:iam::825247853638:role/ecsTaskExecutionRole", "networkMode": "awsvpc", "revision": 4, "volumes": [], "status": "ACTIVE", "requiresAttributes": [ { "name": "com.amazonaws.ecs.capability.logging-driver.awslogs" }, { "name": "ecs.capability.execution-role-awslogs" }, { "name": "com.amazonaws.ecs.capability.ecr-auth" }, { "name": "com.amazonaws.ecs.capability.docker-remote-api.1.19" }, { "name": "com.amazonaws.ecs.capability.docker-remote-api.1.17" }, { "name": "com.amazonaws.ecs.capability.docker-remote-api.1.21" }, { "name": "com.amazonaws.ecs.capability.task-iam-role" }, { "name": "ecs.capability.container-ordering" }, { "name": "ecs.capability.execution-role-ecr-pull" }, { "name": "com.amazonaws.ecs.capability.docker-remote-api.1.18" }, { "name": "ecs.capability.task-eni" }, { "name": "com.amazonaws.ecs.capability.docker-remote-api.1.29" } ], "placementConstraints": [], "compatibilities": [ "EC2" ], "requiresCompatibilities": [ "EC2" ], "cpu": "2048", "memory": "800", "runtimePlatform": { "cpuArchitecture": "X86_64", "operatingSystemFamily": "LINUX" }, "registeredAt": "2024-03-09T16:21:08.835Z", "registeredBy": "arn:aws:iam::825247853638:user/dmytro", "tags": [] }
CloudWatch日志
2024-03-12T19:44:26.996+01:00 [12-Mar-2024 18:44:26] NOTICE: [pool www] 'group' directive is ignored when FPM is not running as root 2024-03-12T19:44:26.996+01:00 [12-Mar-2024 18:44:26] NOTICE: fpm is running, pid 1 2024-03-12T19:44:26.997+01:00 [12-Mar-2024 18:44:26] NOTICE: ready to handle connections 2024-03-12T19:44:27.536+01:00 [12-Mar-2024 18:44:27] NOTICE: Finishing ... [12-Mar-2024 18:44:27] NOTICE: Finishing ... 2024-03-12T19:44:27.536+01:00 [12-Mar-2024 18:44:27] NOTICE: exiting, bye-bye!
问题分析与解决建议
从日志可见,PHP-FPM进程正常启动并准备处理连接,但随即主动退出,结合非root运行的场景,核心问题大概率是监听资源的权限问题,以下是具体排查方向和解决步骤:
1. 调整PHP-FPM监听配置(优先尝试)
默认PHP-FPM可能监听Unix套接字(如/run/php-fpm.sock),非root用户通常没有该路径的读写权限,导致进程启动后无法正常监听,进而退出。可以修改为监听TCP端口:
在Dockerfile的portfolio-prod和portfolio-dev阶段,切换用户前添加以下命令:
RUN echo "listen = 0.0.0.0:9000" >> /usr/local/etc/php-fpm.d/zz-docker.conf
同时确保Nginx配置中的fastcgi_pass指向php-fpm:9000(同一ECS任务内的容器可通过名称直接通信)。
2. 修复HEALTHCHECK配置并调整容器依赖
Dockerfile中注释的HEALTHCHECK存在拼写错误(php-fpm-healhcheck应为php-fpm-healthcheck),启用后可以让Nginx等待PHP-FPM健康后再启动,避免依赖时序问题:
HEALTHCHECK --start-period=3s --interval=5s --timeout=2s CMD php-fpm-healthcheck || exit 1
然后在任务定义中,将Nginx的dependsOn条件从START改为HEALTHY:
"dependsOn": [ { "containerName": "php-fpm", "condition": "HEALTHY" } ]
3. 验证目录权限
确认/var/www/html和/files目录的权限正确,非root用户www-data拥有读写权限:
在Dockerfile的portfolio-prod和portfolio-dev阶段,补充检查/var/www/html的权限:
RUN chown -R www-data:www-data /var/www/html
4. 检查资源限制
虽然日志未显示OOM,但可以尝试调整任务定义中PHP-FPM容器的CPU和内存分配,确保资源充足,避免因资源不足被系统终止。
完成上述修改后,重新构建镜像并推送至ECR,更新任务定义后再次测试。
内容的提问来源于stack exchange,提问作者Dmytro

