Docker环境下Nginx连接Perl容器出现502连接拒绝错误求助
搭建PHP/Perl/Nginx Docker环境时Perl脚本返回502错误的排查与解决
自行搭建了包含PHP、Perl、Nginx的Docker环境,PHP服务正常,但访问.cgi或.pl文件时返回502错误。
相关配置文件
Perl Dockerfile
FROM perl:5.36 COPY perl/src /usr/share/nginx/html
Nginx配置文件
server { listen 80; root /usr/share/nginx/html; location ~ \.php$ { # index index.php index.html index.htm; fastcgi_pass php-mt:9000; # fastcgi_index index.php; fastcgi_param SCRIPT_FILENAME $document_root$fastcgi_script_name; include fastcgi_params; } location ~ \.(cgi|pl)$ { # index index.cgi index.html index.htm; fastcgi_pass perl-mt:9001; # fastcgi_index index.cgi; fastcgi_param SCRIPT_FILENAME $document_root$fastcgi_script_name; include fastcgi_params; } }
docker-compose.yml
version: '3' services: php-mt: restart: always build: context: . dockerfile: ./php/Dockerfile nginx-mt: restart: always ports: - 80:80 build: context: . dockerfile: ./nginx/Dockerfile perl-mt: # restart: always tty: true expose: - 9001 build: context: . dockerfile: ./perl/Dockerfile
容器运行状态
执行docker ps返回:
CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES ce6f7d61cd4a docker-mt_nginx-mt "/docker-entrypoint.…" 20 minutes ago Up 20 minutes 0.0.0.0:80->80/tcp docker-mt_nginx-mt_1 62fd1c445dd2 docker-mt_perl-mt "perl5.36.0 -de0" 27 minutes ago Up 20 minutes 9001/tcp docker-mt_perl-mt_1 c5ed035c144b docker-mt_php-mt "docker-php-entrypoi…" 3 hours ago Up 20 minutes 9000/tcp docker-mt_php-mt_1
Nginx错误日志
nginx-mt_1 | 2023/03/21 06:37:13 [error] 30#30: *6 connect() failed (111: Connection refused) while connecting to upstream, client: 172.18.0.1, server: , request: "GET /perl.cgi HTTP/1.1", upstream: "fastcgi://172.18.0.3:9001", host: "localhost" nginx-mt_1 | 172.18.0.1 - - [21/Mar/2023:06:37:13 +0000] "GET /perl.cgi HTTP/1.1" 502 559 "-" "Mozilla/5.0 (Macintosh; Intel Mac OS X 10_15_7) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/110.0.0.0 Safari/537.36" "-"
已尝试的排查步骤
- 修正Perl容器的暴露端口
- 确认Perl容器内.pl文件可正常运行
- 修改.pl和.cgi文件的权限
解决方案
核心问题
从docker ps的COMMAND列可见,Perl容器当前运行的是perl5.36.0 -de0,这是Perl的交互调试模式,未监听9001端口提供FastCGI服务,导致Nginx无法建立连接,返回502错误。
解决步骤
修改Perl Dockerfile,安装并启动FastCGI服务
需要安装FastCGI依赖和服务端工具,确保容器启动后监听9001端口。修改后的Dockerfile如下:FROM perl:5.36 # 安装系统依赖和spawn-fcgi工具 RUN apt-get update && apt-get install -y spawn-fcgi && rm -rf /var/lib/apt/lists/* # 安装Perl的FCGI模块 RUN cpanm FCGI # 复制代码文件 COPY perl/src /usr/share/nginx/html # 设置脚本可执行权限 RUN chmod +x /usr/share/nginx/html/*.pl /usr/share/nginx/html/*.cgi # 启动FastCGI服务,监听9001端口,指定处理脚本(替换为你的实际脚本路径) CMD ["spawn-fcgi", "-p", "9001", "-n", "--", "/usr/bin/perl", "/usr/share/nginx/html/your_script.pl"]确保Perl脚本支持FastCGI模式
如果原有脚本是普通CGI模式,需要调整为FastCGI兼容格式,示例脚本如下:#!/usr/bin/perl use FCGI; use CGI; my $request = FCGI::Request(); while ($request->Accept() >= 0) { my $q = CGI->new; print $q->header('text/plain'); print "Hello from Perl FastCGI!"; }重启容器验证
重新构建并启动Perl容器:docker-compose down docker-compose build perl-mt docker-compose up -d进入Perl容器执行
netstat -tulpn | grep 9001,确认端口处于监听状态。
额外注意事项
- 确保Nginx配置中的
SCRIPT_FILENAME参数路径与Perl容器内的脚本路径一致(当前配置已匹配)。 - 若使用自定义脚本,需在CMD命令中替换为实际脚本的绝对路径。
内容的提问来源于stack exchange,提问作者Kotapon
相关产品推荐
相关产品推荐

