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

Cloud Run部署单容器全栈应用Nginx proxy_pass连接失败求助

单容器全栈应用Cloud Run部署:Nginx proxy_pass连接拒绝问题解决

问题场景

通过单容器部署全栈应用,使用Nginx反向代理前端静态文件和后端API,本地运行正常,但部署到Cloud Run后,访问/api路径时出现Nginx连接拒绝错误:

[error] 10#10: *9 connect() failed (111: Connection refused) while connecting to upstream, client: #certain_IP, server: _, request: "GET /api/here/we/are HTTP/1.1", upstream: "http://127.0.0.1:3000/api/here/we/are", host: "my_domain.bla"

容器日志确认后端应用已正常启动并监听3000端口,Nginx监听8080端口。

现有配置

Dockerfile

FROM ubuntu:22.10

# Create my_user ...

# Copy Nginx configuration files
COPY ./nginx.conf /etc/nginx/nginx.conf
COPY ./proxy.conf /etc/nginx/conf.d/proxy.conf

WORKDIR /app
RUN npm install \
    && npm run build

WORKDIR /app/frontend
RUN npm install \
    && npm run build

RUN sudo cp -a ./dist/. /var/www/html

WORKDIR /app

CMD ["sh", "-c", "nginx -g 'daemon off;' & npm run start:prod"]

proxy.conf

upstream backend {
    server localhost:3000;
}

server {
    listen 8080;
    server_name _;

    root /var/www/html;
    index index.html;

    location / {
        try_files $uri $uri/ /index.html;
    }

    location ~ \.(css|js)$ {
        add_header Content-Type text/plain;
        try_files $uri =404;
    }

    location /api {
        proxy_pass http://backend/api;
        proxy_set_header Host $host;
        proxy_set_header X-Real-IP $remote_addr;
        proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
    }
}

nginx.conf

user my_user;
worker_processes auto;
pid /run/nginx.pid;
include /etc/nginx/modules-enabled/*.conf;

events {
    worker_connections 768;
    # Other event configurations if needed
}

http {
    include /etc/nginx/mime.types;
    default_type application/octet-stream;

    access_log /var/log/nginx/access.log;
    error_log /var/log/nginx/error.log;

    sendfile on;

    include /etc/nginx/conf.d/*.conf;
}

本地与Cloud Run的核心差异

  1. 进程启动可靠性:本地环境可手动确保后端就绪后再访问;但Cloud Run用&并行启动Nginx和后端时,可能出现Nginx先启动完成,而后端仍在初始化,导致初始请求连接拒绝。
  2. 网络监听范围:部分Node.js应用默认仅监听127.0.0.1,本地环回访问正常,但Cloud Run容器网络环境中,这种绑定可能引发跨进程访问异常(尽管同一容器内理论互通,但实际部署存在兼容性问题)。

解决方法

1. 修改后端应用监听地址为0.0.0.0

确保后端服务绑定到容器所有网络接口,而非仅本地环回。例如Node.js应用代码中:

// 替换原有的 app.listen(3000)
app.listen(3000, '0.0.0.0', () => {
  console.log('Backend running on port 3000');
});

或在启动命令中添加参数(以Express框架为例):

# 修改package.json中的start:prod命令
"start:prod": "node server.js --host 0.0.0.0"

2. 使用进程管理器替代&并行启动

用supervisord统一管理Nginx和后端进程,实现进程监控与启动顺序控制:

安装supervisord到Dockerfile

# 在Dockerfile中添加supervisord安装步骤
RUN apt-get update && apt-get install -y supervisor \
    && rm -rf /var/lib/apt/lists/*

# 创建supervisord配置文件目录
RUN mkdir -p /var/log/supervisor

# 复制supervisord配置文件
COPY supervisord.conf /etc/supervisor/conf.d/supervisord.conf

# 替换原CMD命令
CMD ["/usr/bin/supervisord"]

创建supervisord.conf配置文件

[supervisord]
nodaemon=true
logfile=/var/log/supervisor/supervisord.log
pidfile=/var/run/supervisord.pid

[program:backend]
directory=/app
command=npm run start:prod
autostart=true
autorestart=true
stdout_logfile=/var/log/supervisor/backend.log
stderr_logfile=/var/log/supervisor/backend.err.log
user=my_user

[program:nginx]
command=nginx -g 'daemon off;'
autostart=true
autorestart=true
stdout_logfile=/var/log/supervisor/nginx.log
stderr_logfile=/var/log/supervisor/nginx.err.log
user=my_user

3. 优化Nginx代理配置(可选)

将upstream中的localhost替换为127.0.0.1,避免DNS解析可能的延迟或异常:

upstream backend {
    server 127.0.0.1:3000;
}

验证步骤

  1. 构建修改后的镜像并本地测试,确保后端和Nginx正常启动,API代理功能正常。
  2. 部署到Cloud Run后,查看容器日志确认两个进程均正常运行,无启动报错。
  3. 访问API路径验证代理功能是否恢复正常。

内容的提问来源于stack exchange,提问作者Yelk0

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.15 08:08:10