首页 > 解决方案 > 同一网络上的 docker 容器(来自 compose)看不到对方

问题描述

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

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 和 curlnginx_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>

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

在我看来,好像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为容器才能从外部访问,并且已经完成。

另一件事,我通过它的容器名称调用django_servernginx_server,这应该允许 mi 连接到docker networki 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

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

标签: pythondjangodockernetworkingdocker-compose

解决方案


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

如果使用命令启动后端服务

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

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

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

并且在 Composeports:设置中,第二个端口号需要和这个端口匹配

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 Hubnginx映像,它默认侦听标准 HTTP 端口 80,因此您需要发布ports: ["8000:80"]以匹配该端口号。)


推荐阅读