Nginx

connect() 在使用靜態網站連接到上游時失敗(111:連接被拒絕)

  • May 20, 2022

我的目標是擁有 2 個 docker 容器:

  • nginx 容器(基於 nginx:latest)用作反向代理
  • 帶有靜態網站的容器(基於 nginx:alpine)

稍後我將添加 1+ .net 核心後端服務(暫時不重要)。目前,當我嘗試使用公共 IP 地址訪問我的網路伺服器時,我得到 502 Bad gateway。這是我目前的配置:

docker-compose.yaml

version: '3'
services:
 reverse-proxy:
   image: nginx:latest
   container_name: reverse_proxy
   depends_on:
     - static-website
   volumes:
     - ./reverse_proxy/nginx.conf:/etc/nginx/nginx.conf
   ports:
     - 80:80
 static-website:
   image: sm-static-website
   build:
     context: ./website
   container_name: sm_static_website
   ports:
     - "8080:80"

用於反向代理的 nginx.conf:

worker_processes auto;
include /etc/nginx/modules-enabled/*.conf;

events {
   worker_connections 1024;
}

http {
   server {
           listen 80 default_server;
           listen [::]:80 default_server;

           server_name x.x.x.x; # my_public_ip

           location / {
                   proxy_pass              http://sm_static_website:8080;
                   proxy_set_header        X-Forwarded-For $remote_addr;
           }
   }
}

靜態網站的 Dockerfile:

FROM nginx:alpine
WORKDIR /html
COPY . /var/www/html
EXPOSE 8080

從我的網站容器中,我可以看到 nginx 正在執行/監聽 80:

netstat -tulpn | grep LISTEN
tcp        0      0 127.0.0.11:41389        0.0.0.0:*               LISTEN      -
tcp        0      0 0.0.0.0:80              0.0.0.0:*               LISTEN      1/nginx: master pro
tcp        0      0 :::80                   :::*                    LISTE       1/nginx: master pro

從我的伺服器上,我可以看到 remote_proxy 和 website 容器分別監聽 80/8080:

netstat -tulpn | grep LISTEN
tcp        0      0 0.0.0.0:80              0.0.0.0:*               LISTEN      13936/docker-proxy
tcp        0      0 0.0.0.0:8080            0.0.0.0:*               LISTEN      13797/docker-proxy
tcp6       0      0 :::80                   :::*                    LISTEN      13942/docker-proxy
tcp6       0      0 :::8080                 :::*                    LISTEN      13804/docker-proxy

伺服器上的 ps -aux 返回:

root       13936  0.0  0.0 1075140 3580 ?        Sl   00:24   0:00 /usr/bin/docker-proxy -proto tcp -host-ip 0.0.0.0 -host-port 80 -container-ip 172.18.0.3 -container-port 80
root       13797  0.0  0.0 1148872 3624 ?        Sl   00:24   0:00 /usr/bin/docker-proxy -proto tcp -host-ip 0.0.0.0 -host-port 8080 -container-ip 172.18.0.2 -container-port 80

網站容器的日誌顯示沒有錯誤,工作程序正在執行。但是,反向代理日誌顯示:

2022/05/20 01:20:29 [error] 31#31: *1 connect() failed (111: Connection refused) while connecting to upstream, client: x.x.x.x, server: x.x.x.x, request: "GET / HTTP/1.1", upstream: "http://172.19.0.2:8080/", host: "x.x.x.x"

任何想法我做錯了什麼?如果我從 docker-compose.yml 中刪除 volumes: 行,那麼我會從反向代理容器中獲取預設的 nginx 頁面。這表明它正在正確偵聽,接受請求,但不會將其重定向到網站容器。

portdocker-compose 中的指令定義了哪個埠暴露給外部。當它們連結在一起時,您的反向代理容器可以static-website直接訪問內部的服務,因此您不要在這裡使用暴露的埠。

由於容器內的網站static-website正在偵聽埠 80,因此您需要使用它而不是暴露的埠。

首先,您需要將容器連結在一起,然後添加到reverse-proxy塊中:

links:
 - static-website

你的proxy_pass指令應該是:

proxy_pass              http://sm_static_website;

如果您不想將static-website容器實際暴露在外部,您可以刪除ports那裡的指令。

所以docker-compose.yml應該是這樣的:

version: '3'
services:
 reverse-proxy:
   image: nginx:latest
   container_name: reverse_proxy
   depends_on:
     - static-website
   volumes:
     - ./reverse_proxy/nginx.conf:/etc/nginx/nginx.conf
   ports:
     - 80:80
   links:
     - sm_static_website
 static-website:
   image: sm-static-website
   build:
     context: ./website
   container_name: sm_static_website

TBH:我從來沒有發現使用指令很有用container_name,我不確定你是否必須使用定義的 container_namesm_static_website或者只是在指令static-website中的linksand 中。proxy_pass如果你把它排除在外,那將只是static-website.

引用自:https://serverfault.com/questions/1101369