skip to Main Content

I have two docker containers: nginx_server and django_server (with UWSGI) and a posgres with postgresql. Now the thing is, My nginx setup seems to be a bit off, because if gives me a 502 Bad Gateway any time I curl 0.0.0.0:8000 (both on host and inside container).

django_server is runs on UWSGI and is configured such as:

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

I’am able to connect to it both outside and inside container and get a proper result.

Inside django_server container I can ping and curl nginx_server with positive result and 502 Bad Gateway.

curl django_server in nginx_server container outputs:

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

(I receive above output in django_server container when curl localhost:80 rather than curl 0.0.0.0:80 / curl 127.0.0.1:80)

It seems to me, like nginx_server is not properly requesting data from uwsgi.

nginx_server configuration:

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
    }
}

I’ve researched that connection must be set to 0.0.0.0 for container to be accessible from outside, and it is done.

Another thing, I call django_server in nginx_server by it’s container name, which should allow mi for connection on the docker network since I docker-compose up.

Main problem is:
django_server content (requesting for uwsgi) is not accessible from other containers, but is accessible from a host.

Additionally (with netstat -tlnp those two are availible):

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:

EDIT:

According to David Maze, I’ve changed port mapping to be simplier and easier to track.

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

Respectively:

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

Even tho above changes are applied, issue persist.

2

Answers


  1. Chosen as BEST ANSWER

    Solution: Official UWSGI site https://uwsgi-docs.readthedocs.io/en/latest/Options.html described a uwsgi-socket connection.

    Nginx is capable of connecting to uwsgi based on uwsgi_params, but then socket in uwsgi configuration must match the type of request. My explanation is a bit messy, but it did work.

    My uwsgi.ini file for uwsgi configuration:

    [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
    

    ngxing default.conf file:

    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
        }
    }
    

    My uwsgi version is: uwsgi --version: 2.0.19.1

    Nginx installed with official docker hub image: nginx version: nginx/1.19.7

    Solution: add uwsgi-socket = 0.0.0.0:some_port to uwsgi.ini


  2. You need to make sure all of the port numbers match up.

    If you start the back-end service with a command

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

    then cross-container calls need to connect to port 80; ports: are not considered here at all (and aren’t necessary if you don’t want to connect to the container from outside Docker). Your Nginx configuration needs to say

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

    and in the Compose ports: setting, the second port number needs to match this port

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

    Similarly, since you’ve configure the Nginx container to

    listen      0.0.0.0:8000;
    

    then you need to use that port 8000 for inter-container communication and as the second ports: number

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

    (If you use the Docker Hub nginx image it by default listens on the standard HTTP port 80, and so you’d need to publish ports: ["8000:80"] to match that port number.)

    Login or Signup to reply.
Please signup or login to give your own answer.
Back To Top
Search