You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

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错误。

解决步骤

  1. 修改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"]
    
  2. 确保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!";
    }
    
  3. 重启容器验证
    重新构建并启动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

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.07.27 02:57:09