Question

502 Gateway Error Docker-compose Nginx-Proxy Django

Posted May 17, 2021 234 views
NginxDockerDjangoUbuntu 20.04

I am trying to docker up my django application using this tutorial.
https://testdriven.io/blog/dockerizing-django-with-postgres-gunicorn-and-nginx/

Technically, I have 2 problems:
1) Cannot connect to the database
2) 502 gateway error

Everything seems to work until i get this error:

nginx-proxy    | nginx.1  *1 connect() failed (111: Connection refused) while connecting to upstream, client: 111.222.333.444, server: www.hello.com, request: "GET /favicon.ico HTTP/2.0", upstream: "http://172.25.0.2:8000/favicon.ico", host: "www.hello.com", referrer: "https://www.hello.com/"

Also, it seems that my web server is unable to detect my postgresql database as it prompts a “waiting for postgres” due to the entrypoint.sh i have provided. I have configured my database using this tutorial:
https://www.digitalocean.com/community/tutorials/how-to-set-up-django-with-postgres-nginx-and-gunicorn-on-ubuntu-20-04

Been stuck with this for a few days! I will attach my code here:

When I run netstat plant:

Proto Recv-Q Send-Q Local Address           Foreign Address         State       PID/Program name    
tcp        0      0 127.0.0.53:53           0.0.0.0:*               LISTEN      637/systemd-resolve 
tcp        0      0 0.0.0.0:22              0.0.0.0:*               LISTEN      840/sshd            
tcp        0      0 127.0.0.1:5432          0.0.0.0:*               LISTEN      27204/postgres      
tcp        0      0 127.0.0.1:35449         0.0.0.0:*               LISTEN      19618/containerd    
tcp        0      0 111.222.333.444:22       555.666.777.888:52289    ESTABLISHED 740/sshd: root@nott 
tcp        0   1080 111.222.333.444:22       999.111.222.333:13146    ESTABLISHED 16139/sshd: [accept 
tcp        0    356 111.222.333.444:22       555.666.777.888:52288    ESTABLISHED 32641/sshd: root@pt 
tcp6       0      0 :::22                   :::*                    LISTEN      840/sshd   

docker-compose file:

version: '3.8'

services:
  web:
    container_name: container_name
    build:
      context: ./hello_main
      dockerfile: Dockerfile.prod
    image: hello
    command: gunicorn --timeout 180 hello.wsgi:application --bind 0.0.0.0:8000
    volumes:
      - static_volume:/home/app/web/staticfiles
      - media_volume:/home/app/web/mediafiles
    expose:
      - 8000
    env_file:
      - ./.env
  nginx-proxy:
    container_name: nginx-proxy
    build: ./nginx
    image: nginx-proxy
    restart: always
    ports:
      - 80:80
    volumes:
      - static_volume:/home/app/web/staticfiles
      - media_volume:/home/app/web/mediafiles
      - certs:/etc/nginx/certs
      - html:/usr/share/nginx/html
      - vhost:/etc/nginx/vhost.d
      - /var/run/docker.sock:/tmp/docker.sock:ro
    depends_on:
      - web

volumes:
  static_volume:
  media_volume:
  certs:
  html:
  vhost:

DockerFile stuff works fine.

I also configured settings on nginx based on this tutorial: https://testdriven.io/blog/dockerizing-django-with-postgres-gunicorn-and-nginx/
I did not use the nginx.conf provided by the digitalocean server.

vhost.d/default

server {

    listen 80;

    location / {
        proxy_pass http://www.hello.com;
        proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
        proxy_set_header Host $host;
        proxy_redirect off;
    }


location = /favicon.ico { access_log off; log_not_found off; }


location /staticfiles/ {
  alias /home/app/web/staticfiles/;
  add_header Access-Control-Allow-Origin *;
}

location /mediafiles/ {
  alias /home/app/web/mediafiles/;
  add_header Access-Control-Allow-Origin *;
  proxy_read_timeout 300;
  proxy_connect_timeout 300;
  proxy_send_timeout 300; 
}


DockerFile for NGINX:

FROM jwilder/nginx-proxy
COPY vhost.d/default /etc/nginx/vhost.d/default
COPY custom.conf /etc/nginx/conf.d/custom.conf

CUSTOM.CONF FOR NGINX

client_max_body_size 25M;
proxy_connect_timeout       600;
proxy_send_timeout          600;
proxy_read_timeout          600;
send_timeout                600;

edited by MattIPv4

These answers are provided by our Community. If you find them useful, show some love by clicking the heart. If you run into issues leave a comment, or add your own answer to help others.

×
Submit an Answer
1 answer

Hi there @Bleung026,

As far as I can see you are running your database directly on the server itself. What you could do in order to connect to the database from a Docker container, you could use the following hostname:

host.docker.internal:5432

Regarding the 502 error, it is most likely caused by the database connection, if your backend service is unable to obtain a database connection it is most likely crashing and the docker container is not starting.

You can verify that with the docker ps -a command.

Here is a quick video that explains why Nginx returns a 502 error:

Let me know how it goes.
Regards,
Bobby

  • Hey Bobby! Thanks for the reply but unfortunately it didn’t work
    :( I am not even sure if the database is connected. Sometimes i also get an error: nginx: [emerg] “server” directive is not allowed here. Not sure why this is happening, basically i know it should be within the http {} but because im using the jwilder nginx-proxy I’m not sure how to continue.

    Only good news is that after 1 day of work, the 502 error is gone. But instead of showing my website, it shows the welcome page to nginx saying that more configuration should be required.

    for the database, I have added into my docker-compose web file instead of what you have suggested.

        extra_hosts:
          - "host.docker.internal:host-gateway"
    
    • Hey Bobby, just want to update that I have solved this problem:

      [emerg] “server” directive is not allowed here. Not sure why this is happening, basically i know it should be within the http {}
      
      

      However, the 502 gateway problem is back. And this is because it still cannot connect to the local database from inside the docker container. I have tried the following combinations in my docker-compose file

          extra_hosts:
            - "host.docker.internal:host-gateway"
          environment:
            - DB_UPSTREAM:http://${DOCKER_GATEWAY_HOST:-host.docker.internal}:5432
         # extra_hosts:
           # - "host.docker.internal:host-gateway"
           # - "database:172.17.0.1"
           # - "host.docker.internal" 
         # network_mode: "host.docker.internal:5432"
      

      and in my django settings file:
      db host I have set to:

      host.docker.internal
      172.17.0.1
      database
      127.0.0.1
      ${DOCKER_GATEWAY_HOST:-host.docker.internal}
      <my_server_ip_address>
      
      

      All these combinations did not work. I tried to do an exec web bash and then ran the command: pg_ctlcluster 11 main start which didn’t work as well. Any advice why this is so?

      @bobbyiliev

      • Hi there @Bleung026,

        It sounds like that the backend service is still failing to start. Do you have any specific errors that could point you to the correct direction?

        I could suggest starting with the following:

        • Test if you have the network connectivity from the container to the host on port 5432, you could use the telnet command to test that for example when within your container
        • Verify that your PostgreSQL username and password that you are using in your connection string are correct

        Regards,
        Bobby