【问题标题】:docker containers on the same net (from compose) don't see each other同一网络上的 docker 容器(来自 compose)看不到对方
【发布时间】:2021-02-22 18:29:39
【问题描述】:

我有两个 docker 容器:nginx_serverdjango_server(带有 UWSGI)和一个 posgres 带有 postgresql。现在问题是,我的nginx 设置似乎有点不对劲,因为如果我在curl 0.0.0.0:8000 (在主机上和容器内)任何时候都会给我一个502 Bad Gateway

django_server 在 UWSGI 上运行,配置如下:

uwsgi --http-socket 0.0.0.0:80 \
        --master \
        --module label_it.wsgi \
        --static-map /static=/app/label_it/front/static \

我能够在容器内外连接到它并获得正确的结果。

django_server 容器内,我可以 ping 和 curl nginx_server 得到肯定结果和 502 Bad Gateway

curl django_servernginx_server 容器输出中:

<html lang="en">
<head>
  <title>Bad Request (400)</title>
</head>
<body>
  <h1>Bad Request (400)</h1><p></p>
</body>
</html>

(当curl localhost:80 而不是curl 0.0.0.0:80 / curl 127.0.0.1:80 时,我在django_server 容器中收到上述输出)

在我看来,nginx_server 没有正确地从 uwsgi 请求数据。

nginx_server配置:

upstream django {
    server django_server:8000;
}

# configuration of the server
server {
    # the port your site will be served on
    listen      0.0.0.0:8000;

    # the domain name it will serve for
    server_name label_it.com; # substitute your machine's IP address or FQDN
    charset     utf-8;

    # max upload size
    client_max_body_size 75M;   # adjust to taste

    location /static {
        alias /vol/static; # your Django project's static files - amend as required
    }

    # Finally, send all non-media requests to the Django server.
    location / {
        uwsgi_pass  django;
        include     /etc/nginx/uwsgi_params; # the uwsgi_params file you installed
    }
}

我研究了连接必须设置为0.0.0.0 才能从外部访问容器,并且已经完成。

另一件事,我在nginx_server 中调用django_server 通过它的容器名称,这应该允许mi 连接到docker network,因为我是docker-compose up

主要问题是: django_server 内容(请求uwsgi)无法从其他容器访问,但可以从主机访问。

另外(netstat -tlnp 这两个可用):

tcp        0      0 0.0.0.0:8000            0.0.0.0:*               LISTEN      -                   
tcp        0      0 0.0.0.0:8001            0.0.0.0:*               LISTEN      -                   

docker-compose.prod.yaml:

version: "3.8"

services:
  db:
    image: postgres
    container_name: postgres
    environment:
      - POSTGRES_DB=postgres
      - POSTGRES_USER=postgres
      - POSTGRES_PASSWORD=postgres
    volumes:
      - ./private/posgtesql/data/data:/var/lib/postgresql/data
  app:
    build: .
    container_name: django_server
    environment:
      - DJANGO_SECRET_KEY=***
      - DJANGO_DEBUG=False
      - PATH=/app/scripts:${PATH}
      - DJANGO_SETTINGS_MODULE=label_it.settings
    volumes:
      - .:/app
      - static_data:/vol/static
    ports:
      - "8001:80"
    depends_on:
      - db
  nginx:
    container_name: nginx_server
    build:
      context: ./nginx
    volumes:
      - static_data:/vol/static
      - ./nginx/conf.d:/etc/nginx/conf.d
      - ./nginx/uwsgi_params:/etc/nginx/uwsgi_params
    ports:
      - "8000:80"
    depends_on:
      - app

volumes:
  static_data:

编辑:

根据 David Maze 的说法,我已将端口映射更改为更简单且更易于跟踪。

django_server` is now `port 8001:8001
nginx_server` is now `port 8000:8000

分别:

django_server uwsgi: --http-socket 0.0.0.0:8001
nginx_server: listen 0.0.0.0:8000 and server django_server:8001

即使应用了上述更改,问题仍然存在。

【问题讨论】:

    标签: python django docker networking docker-compose


    【解决方案1】:

    您需要确保所有端口号都匹配。

    如果用命令启动后端服务

    uwsgi --http-socket 0.0.0.0:80 ...
    

    那么跨容器调用需要连接到80端口; ports: 在这里根本不考虑(如果您不想从 Docker 外部连接到容器,则没有必要)。你的 Nginx 配置需要说明

    upstream django {
        server django_server:80; # same port as process in container
    }
    

    并且在 Compose ports: 设置中,第二个端口号需要与此端口匹配

    services:
      app:
        ports:
          - "8001:80" # second port must match process in container
    

    同样,由于您已将 Nginx 容器配置为

    listen      0.0.0.0:8000;
    

    那么您需要使用该端口 8000 进行容器间通信,并作为第二个 ports: 编号

    services:
      nginx:
        ports:
          - "8000:8000" # second port must match "listen" statement
    

    (如果您使用Docker Hub nginx image,它默认侦听标准 HTTP 端口 80,因此您需要发布 ports: ["8000:80"] 以匹配该端口号。)

    【讨论】:

    • 感谢您的简短而出色的解释!我学到了一些新东西。根据您的回答应用更改。可悲的是,问题没有解决(见编辑)。此外,在调试时,我尝试完全删除 django_server 中的 ports: -8001:8001,因为我认为它可能会阻塞 uwsgi 套接字,但仍然没有任何改变。
    【解决方案2】:

    解决方案: UWSGI 官方网站https://uwsgi-docs.readthedocs.io/en/latest/Options.html 描述了一个uwsgi-socket 连接。

    Nginx 能够基于uwsgi_params 连接到uwsgi,但是uwsgi 配置中的socket 必须匹配请求的类型。我的解释有点乱,但确实有效。

    我的uwsgi.ini 文件uwsgi 配置:

    [uwsgi]
    uwsgi-socket = 0.0.0.0:8001 <- this line solved the issue
    master = true
    module = label_it.wsgi:application
    chdir = /app/label_it <- important
    static-map = /static=/app/label_it/front/static <- might not be neccessery
    chmod-socket = 666 <- might not be neccessery
    

    ngxingdefault.conf 文件:

    upstream django {
        server django_server:8001;
    }
    
    # configuration of the server
    server {
        # the port your site will be served on
        listen      0.0.0.0:8000;
    
        server_name label_it.com;
        charset     utf-8;
    
    
        client_max_body_size 75M;
    
        location /static {
            alias /vol/static; # your Django project's static files - amend as required
        }
    
        
        location / {
            uwsgi_pass  django;
            include     /etc/nginx/uwsgi_params; # the uwsgi_params file you installed
        }
    }
    

    我的uwsgi版本是:uwsgi --version: 2.0.19.1

    Nginx安装官方docker hub图片:nginx version: nginx/1.19.7

    解决方法:将uwsgi-socket = 0.0.0.0:some_port添加到uwsgi.ini

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2020-05-10
      • 2015-12-07
      • 1970-01-01
      • 2021-12-20
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2020-04-04
      相关资源
      最近更新 更多