Nginx+PHP8.1部署Google Cloud时端口监听启动失败求助
部署Nginx+PHP8.1到Google Cloud的端口监听问题
本地运行Nginx+PHP8.1环境一切正常,但部署到Google Cloud时触发错误:
The user-provided container failed to start and listen on the port defined provided by the PORT = 8080 environment variable
Google Cloud默认要求容器监听8080端口,单独部署Nginx可正常启动,加入PHP后出现问题,已添加EXPOSE 8080但无效。
相关配置文件
Dockerfile
FROM nginx:alpine as nginx COPY nginx/default.conf /etc/nginx/conf.d/default.conf FROM php:8.1-fpm AS php COPY docker/php/php.ini /usr/local/etc/php/conf.d/docker-php-config.ini RUN apt-get update; \ apt-get upgrade -y; \ apt-get install -y --no-install-recommends \ curl \ libmemcached-dev \ libz-dev \ libpq-dev \ libjpeg-dev \ libpng-dev \ libfreetype6-dev \ libssl-dev \ libwebp-dev \ libxpm-dev \ libmcrypt-dev \ libonig-dev; \ rm -rf /var/lib/apt/lists/* RUN docker-php-ext-install pdo RUN curl -sS https://getcomposer.org/installer | php -- --install-dir=/usr/local/bin --filename=composer WORKDIR /var/www/symfony
Nginx配置文件(nginx/default.conf)
server { listen 8080; server_name localhost; root /var/www/symfony/public; location / { try_files $uri /index.php$is_args$args; } location ~ ^/index\.php(/|$) { if ($request_method = 'OPTIONS') { add_header 'Access-Control-Allow-Origin' '*' always; add_header 'Access-Control-Allow-Methods' 'GET, POST, DELETE, OPTIONS' always; add_header 'Access-Control-Allow-Headers' 'Authorization,DNT,User-Agent,X-Requested-With,If-Modified-Since,Cache-Control,Content-Type,Range' always; add_header 'Access-Control-Max-Age' 1728000 always; add_header 'Content-Type' 'text/plain; charset=utf-8' always; add_header 'Content-Length' 0 always; return 204; } add_header 'Access-Control-Allow-Origin' '*' always; add_header 'Access-Control-Allow-Methods' 'GET, POST, DELETE, OPTIONS' always; add_header 'Access-Control-Allow-Headers' 'Authorization,DNT,User-Agent,X-Requested-With,If-Modified-Since,Cache-Control,Content-Type,Range' always; add_header 'Access-Control-Expose-Headers' 'Content-Length,Content-Range' always; fastcgi_pass php:9000; fastcgi_split_path_info ^(.+\.php)(/.*)$; include fastcgi_params; fastcgi_param SCRIPT_FILENAME $realpath_root$fastcgi_script_name; fastcgi_param DOCUMENT_ROOT $realpath_root; internal; } location ~ \.php$ { return 404; } error_log /dev/stdout info; access_log /var/log/nginx/project_access.log; }
Cloud Logging日志
{ "textPayload": "Step #2: ERROR: (gcloud.beta.run.deploy) The user-provided container failed to start and listen on the port defined provided by the PORT=8080 environment variable. Logs for this revision might contain more information.", "insertId": "8f70f71c-fc36-4b7d-b903-25e9c770342f-2124", "resource": { "type": "build", "labels": { "build_id": "8f70f71c-fc36-4b7d-b903-25e9c770342f", "build_trigger_id": "", "project_id": "adroit-sol-340313" } }, "timestamp": "2022-10-19T11:01:20.973405245Z", "severity": "INFO", "labels": { "build_step": "Step #2" }, "logName": "projects/adroit-sol-340313/logs/cloudbuild", "receiveTimestamp": "2022-10-19T11:01:21.466513119Z" }
问题根源与修复方案
核心问题
当前Dockerfile采用多阶段构建,但最终输出的镜像是php:8.1-fpm阶段,而非Nginx镜像。PHP-FPM默认仅监听9000端口处理FastCGI请求,不会监听8080端口,导致Google Cloud无法检测到端口监听,触发启动失败。
修复步骤
需要构建一个包含Nginx和PHP-FPM的单容器镜像,确保Nginx监听8080端口并转发请求到本地PHP-FPM,同时启动两个服务。以下是修改后的Dockerfile示例:
FROM nginx:alpine # 安装PHP8.1-FPM及所需扩展 RUN apk add --no-cache \ php81-fpm \ php81-pdo \ php81-curl \ php81-mbstring \ php81-gd \ && ln -s /usr/bin/php81 /usr/bin/php \ && ln -s /usr/sbin/php-fpm81 /usr/sbin/php-fpm # 复制Nginx配置 COPY nginx/default.conf /etc/nginx/conf.d/default.conf # 复制PHP配置 COPY docker/php/php.ini /etc/php81/conf.d/docker-php-config.ini # 安装Composer RUN curl -sS https://getcomposer.org/installer | php -- --install-dir=/usr/local/bin --filename=composer # 设置工作目录 WORKDIR /var/www/symfony # 复制项目文件(根据实际情况添加) # COPY . . # 启动脚本:同时启动PHP-FPM和Nginx(Nginx需以非守护进程模式运行) RUN echo '#!/bin/sh\nphp-fpm & nginx -g "daemon off;"' > /start.sh && chmod +x /start.sh CMD ["/start.sh"] # 适配PORT环境变量,避免硬编码 ENV PORT=8080 RUN sed -i 's/listen 8080;/listen ${PORT};/g' /etc/nginx/conf.d/default.conf EXPOSE ${PORT}
额外配置调整
- 修改Nginx配置中的
fastcgi_pass为127.0.0.1:9000(单容器内无需服务名,直接指向本地端口):fastcgi_pass 127.0.0.1:9000; - 确保Nginx日志输出到标准输出/错误,方便Cloud Run日志收集:
error_log /dev/stdout info; access_log /dev/stdout;
排查建议
- 本地验证镜像:构建镜像后用
docker run -p 8080:8080 -e PORT=8080 <镜像ID>启动,访问localhost:8080测试,同时用docker logs <容器ID>查看启动日志,确认Nginx和PHP-FPM是否正常运行。 - 查看Cloud Run详细日志:在Cloud Console中找到对应Revision的日志,排查Nginx或PHP-FPM启动失败的具体原因(如配置错误、权限问题、依赖缺失)。
- 检查端口监听:进入运行中的容器(本地或Cloud Run调试模式),用
netstat -tulpn或ss -tulpn查看8080端口是否被Nginx监听。
内容的提问来源于stack exchange,提问作者KrzysiekW
相关产品推荐
相关产品推荐

