如何使用 proxy_pass 创建一个使用 nginx 的 dockefile,以便在一个容器中为全栈应用程序提供服务?我的目标是使用云运行

How can I create a dockefile that uses nginx using proxy_pass in order to serve a fullstack application in one container? I aim to use cloud run

提问人:Yelk0 提问时间:7/25/2023 最后编辑:Yelk0 更新时间:7/25/2023 访问量:37

问:

我的 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;
}

在本地,这就像一个魅力,但是一旦部署在云中运行并尝试访问 /api 下的路径,例如 my_domain.bla/api/here/we/are,我从 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""

Nginx 正在侦听端口 8080,我的后端应用程序在端口 3000 上运行(我看到来自容器的清晰日志确认应用程序运行良好并侦听正确的端口)

我希望proxy_pass能像在本地一样在云上运行。有人了解云运行和本地运行之间的区别吗? 我的第一个想法是 nginx 可能尝试将请求路由到主机而不是内部容器。后端端口没有公开,所以它会解释连接被拒绝,但我该如何解决?

docker nginx google-cloud-run proxypass

评论

0赞 David Maze 7/25/2023
通常,每个容器只应运行一个进程。在您的设置中,如果 Nginx 因任何原因退出,Docker 生态系统不会注意到;如果主应用程序退出,它将带走 Nginx。你能在两个单独的容器中运行它们吗?
0赞 Yelk0 7/25/2023
感谢您的回答!完全有效的观点。我对 dockerfile 进行了健康检查,以验证容器是否按预期运行。我可能在云上运行 2 个服务,将我的应用程序拆分为前端/nginx 和后端,并确保一个服务可以与另一个服务通信。但是,此设置更为复杂。这就是为什么我想有一种快速的方法在一个容器中测试我的应用程序。您知道为什么这在本地而不是在云上运行以及如何解决它吗?
0赞 Geilmaker 7/25/2023
如果将两者放在一个容器中的唯一原因是“此设置更复杂”,那么您应该将这 2 个服务拆分。这并不复杂,如果需要,我们可以指导您完成,而且这绝对是更好的做法,并且拆分这 2 项服务要容易得多。
0赞 Yelk0 7/25/2023
你绝对是对的,成为一个更好的实践。感谢您的输入!我很想知道为什么这在云运行上没有醒来,但它确实在本地工作。如果我们还没有弄清楚问题,为什么拆分服务会更容易?
0赞 John Hanley 7/25/2023
我建议您研究一下 Cloud Run 应用程序的生命周期。应用在处理 HTTP 请求时接收 CPU 周期。在后台运行进程通常意味着 CPU 匮乏和网络连接故障。为 Cloud Run 设计应用,而不是尝试将您的应用融入 Cloud Run 以获得最佳效果。

答:

0赞 John Hanley 7/25/2023 #1

您的 Nginx 应用程序需要的 CPU 时间比您当前的 Cloud Run 配置提供的要多。本关于容器生命周期的指南将展示如何分配 CPU 时间。

为您的 Cloud Run 实例启用。CPU always allocated

当始终分配 CPU 时,会产生额外的成本。有关详细信息,请查看此文档