docker, nginx, django и как обслуживать статические файлы

цель: набор контейнеров docker для развертывания производственного сайта django.

мое зависание в этом процессе заключается в том, что обычно nginx напрямую обслуживает статические файлы... Основываясь на моем понимании хорошей архитектуры с помощью docker, у вас будет контейнер для вашего сервера wsgi (возможно, gunicorn), отдельный контейнер nginx с конфигурацией восходящего сервера, указывающей на ваш контейнер gunicorn. Контейнер nginx может балансировать нагрузку между несколькими gunicorn стеклотара.

но это означает, что я должен установить статические файлы моего приложения django в контейнер nginx, что кажется плохой практикой, так как это основная цель-действительно балансировка нагрузки

лучше ли иметь три контейнера: nginx, gunicorn и выделенный статический сервер (возможно, nginx или lighthttpd) для статических файлов?

2 ответов


что касается обслуживания статических файлов, ваши параметры зависят от функциональности вашего приложения. Есть очень изящный инструмент под названием dj-static который поможет вам обслуживать статические файлы, добавив очень минимальный код.

документация довольно проста и все, что вам нужно сделать, это следовать эти шаги.


Я нашел этот ответ от Майкл Хэмптон: "Это работает только в том случае, если процессы находятся в одном хосте, виртуальной машине или контейнере, потому что он пытается подключиться к одной машине. Когда они находятся в разных контейнерах, это не работает.

вам нужно изменить конфигурацию nginx, чтобы она использовала внутренний IP-адрес контейнера uwsgi."ссылка с поста

и наверняка то, что вы должны иметь в виду, если вы будет иметь Nginx в другом контейнере, также вы должны установить nginx.conf, указывая каталог статических файлов как псевдоним, предотвращающий проблему безопасности.

Я надеюсь, что этот код работает для всех, мне потребовалось несколько наших, чтобы понять, как составить Gunicorn, docker и Nginx:

# nginx.conf
  upstream djangoA {
       server $DOCKER_CONTAINER_SERVICE:9000 max_fails=3 fail_timeout=0;
       # In my case looks like: web:9000
  }
Server {
    include mime.types;
    # The port your site will be served on      
    listen 80;
    # the domain name it will serve for
    server_name $YOUR_SERVER_NAME;# substitute your machine's IP address or FQDN
    charset utf-8;
    #Max upload size
    client_max_body_size 512M;   # adjust to taste
    location /site_media {
       alias $DIRECTORY_STATIC_FILES/site_media;#your Django project's media   files have to be inside of the container have nginxs, you can copy them with volumes.
    expires 30d;
    }

    location / {
      try_files $uri @proxy_to_app;
    }

   # Finally, send all non-media requests to the Django server.
   location @proxy_to_app {
     proxy_set_header X-Real-IP $remote_addr;
     proxy_redirect off;
     proxy_set_header Host $host;
     proxy_pass http://djangoA;
   }
}

и для докера-compose:

#production.yml
version: '2'

services:
  db:
    extends:
      file: base.yml
      service: db

  nginx:
    image: nginx:latest
  volumes:
      - ./nginx:/etc/nginx/conf.d/
      - ./$STATIC_FILE_ROOT/site_media:/$STATIC_FILE_ROOT/site_media
  ports:
      - "80:80"
    depends_on:
      - web


  web:
    extends:
      file: base.yml
      service: web
    build:
      args:
        - DJANGO_ENV=production
    command: bash -c "python manage.py collectstatic --noinput && chmod 775 -R project/site_media/static && gunicorn project.wsgi:application"
    volumes:
      - ./$DIRECTORY_APP:/$DIRECTORY_APP
    ports:
      - "9000:9000"
    depends_on:
      - db

volumes:
  db_data:
    external: true