使用静态网站连接到上游时 connect() 失败(111:连接被拒绝)

使用静态网站连接到上游时 connect() 失败(111:连接被拒绝)

我的目标是拥有两个docker容器:

  • nginx 容器(基于 nginx:latest)用作反向代理
  • 带有静态网站的容器(基于 nginx:alpine)

稍后我将添加 1+ .net core 后端服务(目前不重要)。目前,当我尝试使用公共 IP 地址访问我的 Web 服务器时,会出现 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 页面。这表明它正在正确监听,接受请求,但不会将其重定向到网站容器。

答案1

docker-compose 中的指令port定义了哪个端口暴露给外部。当它们链接在一起时,您的反向代理容器可以直接访问内部的服务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

老实说:我从未发现使用container_name指令有什么用,我不确定是否必须使用定义的容器名称sm_static_website,还是只在指令中static-website使用。如果你省略它,它就只是。linksproxy_passstatic-website

相关内容