Search code examples
djangonginxdocker-composetraefikproduction-environment

Traefik2 as reverse_proxy for Nginx in django production docker-compose


I have managed to build a small Django app some basic things. Localy works all fine and I'd like to start this WebApp on a production server I already have running.

On this server are already some docker-compose configurations running were a traefik2 works as a revers_proxy with letsencrypt certifikates. So far so good.

As I designed my django project with nginx as static file delivery I'd like to use it and let traefik2 work as revers_proxy in front of nginx.

docer-compose.pro.yml

version: "3.9"

# docker-compose for production
# It is important that the .env.prod is used.
# For this, docker-compose must always be executed
# with the command docker-compose -f docker-compose.pro.yml --env-file .env.prod.

services:
  web:
    build:
      context: .
      dockerfile: ./compose/Dockerfile
    restart: always
    command: gunicorn project.wsgi:application --bind 0.0.0.0:8000
    env_file:
      - ./.env.prod
    expose:
      - 8000
    volumes:
      - static_volume:/code/staticfiles
      - media_volume:/code/mediafiles
    depends_on:
      - redis
      - db
    networks:
      - pjnet

  db:
    image: postgres:15
    restart: always
    volumes:
      - postgres_data:/var/lib/postgresql/data/
    environment:
      - POSTGRES_USER=${DB_USERNAME}
      - POSTGRES_PASSWORD=${DB_PASSWORD}
      - POSTGRES_DB=${DB_NAME}
    networks:
      - pjnet

  redis:
    image: redis:7
    networks:
      - pjnet

  celery:
    build:
      context: .
      dockerfile: ./compose/Dockerfile
    restart: always
    command: celery -A project worker -l info
    volumes:
      - .:/code
    env_file:
      - ./.env.prod
    depends_on:
      - db
      - redis
      - web
    networks:
      - pjnet

  nginx:
    build: ./compose/nginx
    restart: always
    ports:
      - ${NGINX_PORT}:80
    volumes:
      - static_volume:/code/staticfiles
      - media_volume:/code/mediafiles
    labels:
      - traefik.enable=true
      - traefik.http.routers.blogng.rule=Host(`blog.project.com`)
      - traefik.http.routers.blogng.entrypoints=http
      - traefik.http.routers.blogng.middlewares=https-redirect

      - traefik.http.routers.blogngsec.rule=Host(`blog.project.com`)
      - traefik.http.routers.blogngsec.entrypoints=https
      - traefik.http.routers.blogngsec.tls.certresolver=le
      - traefik.http.routers.blogngsec.service=blogngsec
      - traefik.http.services.blogngsec.loadbalancer.server.port=${NGINX_PORT}
    depends_on:
      - web
    networks:
      - pjnet
      - traefik-net

volumes:
  postgres_data:
  static_volume:
  media_volume:

networks:
  traefik-net:
    external: true
  pjnet:

and the nginx.conf

upstream web_app {
    server web:8000;
}

server {

    listen 80;

    location /static/ {
        alias /code/staticfiles/;
    }

    location /media/ {
        alias /code/mediafiles/;
    }

    location / {
        proxy_pass http://web_app;
        proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
        proxy_set_header Host $host;
        proxy_redirect off;
    }

}

Question

With this config I get a "Bad Gateway" Error from my Browser. Did somebody know what I'm doing wrong?

Additional

If I use the "labels" part at the web service, django works but I can't get static files. This confirms to me that Traefik and django are working. When I use the configuration form above it looks from docker-compose like no request to nginx is getting through.


Solution

  • Well, it's actually much too embarrassing to ask such a question.

    The solution is to set the port Nginx listens to correctly and remove it from docker-compose.

    So the following lines need to be corrected.

    docker-compose.pro.yml

    nginx:
        build: ./compose/nginx
        restart: always
        #ports:               <--- can also be deleted
          #- ${NGINX_PORT}:80  <--- can also be deleted
        volumes:
          - static_volume:/code/staticfiles
          - media_volume:/code/mediafiles
        labels:
    

    nginx.conf

    server {
    
        listen 8080;   <-- in my example port I use
    
        location /static/ {