Назад | Перейти на главную страницу

Докер, как Django + uwsgi / gunicorn + nginx?

Я не могу понять, какой «правильный» способ развернуть проект Django, который использует uwsgi / gunicorn (я еще не решил, что использовать, вероятно, uwsgi, поскольку он имеет лучшую производительность, предложения?) И nginx с использованием докер.

Я видел, что некоторые люди складывают все в один контейнер. Я не эксперт в докере, но контейнер должен делать только одну (1) вещь. Итак, наличие Django + nginx похоже на 2, а не на 1.

Теперь моя идея развертывания такова:

Есть ли другой способ сделать это? Есть ли руководство, в котором этот случай рассматривается немного глубже. Мне нужна надежная продукция, а не просто проверка кода на моем компьютере.

Я нашел этот ответ от Майкл Хэмптон:

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

Вам необходимо изменить конфигурацию 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;
   }
}

И для docker-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

В настоящее время я создаю приложение django так, как вы хотите.

Для этого я использую docker-compose. Это мой docker-compose.yml

version: '2'
services:
  nginx:
    container_name: nginx-container
    links:
      - uwsgi
    build: ./nginx
    ports:
      - "8888:80"
    volumes_from:
      - uwsgi
  uwsgi:
    container_name: uwsgi-container
    build: ./uwsgi
    expose:
      - "8001"
    volumes:
      - ./code/conf:/opt/conf
      - ./code/app:/opt/app

Dockerfile для uWSGI:

FROM python:3.5
RUN ["pip", "install", "uwsgi"]
CMD ["uwsgi", "--master", "--ini", "/opt/conf/uwsgi.ini"]

Dockerfile для nginx:

FROM nginx
RUN ["rm", "/etc/nginx/conf.d/default.conf"]
RUN ["ln", "-s", "/opt/conf/nginx.conf", "/etc/nginx/conf.d/"]
CMD ["nginx", "-g", "daemon off;"]

А это мое дерево каталогов:

├── README.md
├── code
│   ├── app
│   └── conf
├── collectstatic.sh
├── docker-compose.yml
├── install.sh
├── migrate.sh
├── nginx
│   └── Dockerfile
├── restart.sh
├── upgrade.sh
├── uwsgi
│   └── Dockerfile

Поэтому я создаю свои изображения с помощью docker-compose build затем запустите новые контейнеры в фоновом режиме с помощью docker-compose up -d Затем я могу выполнить некоторые задачи по настройке, такие как установка django, создание секретного ключа или все, что вы хотите, чтобы ваш контейнер был готов.

Контейнеры nginx и uwsgi используют общие тома для чтения файлов конфигурации И для связи с файловым сокетом.

Не уверен, что это лучший способ, но работа над ним продолжается.

Наконец-то мне удалось создать свою докер-композицию для Django, Gunicorn, Nginx и Postgres благодаря (в основном) этот учебник.

По сути, у вас есть один контейнер для Nginx, один контейнер для Django + Gunicorn и один контейнер (или несколько, если вам нужно несколько баз данных) для Postgres.

Вы также можете разделить Django + Gunicorn на два контейнера, но я думаю, что имеет смысл иметь их оба в одном контейнере, потому что один процесс Gunicorn всегда запускает одно приложение Django wsgi. Я не думаю, что у вас может быть N Gunicorn с 1 Django, 1 Gunicorn с N Django или N Gunicorn с N Django, поэтому здесь нет возможностей масштабирования, кроме масштабирования N контейнеров Gunicorn + Django.

Тома используются для постоянного хранения данных баз данных (и, возможно, статических / мультимедийных файлов Django).

Вы просили учебник или другие способы сделать это, поэтому я не буду публиковать здесь свое содержимое docker-compose.yml (потому что для этого также потребуется файл Dockerfile, файл conf Nginx, файл conf Gunicorn, файлы env баз данных, и многие фрагменты кода Python, такие как настройки DATABASES), но я постараюсь сделать учебник, когда у меня будет время, и опубликую ссылку в редактировании / комментарии.

Между тем ссылка, которую я предоставил выше, является очень хорошей отправной точкой.

РЕДАКТИРОВАТЬ: теперь вы можете взглянуть на это пример настройки докера и связанные Сообщение блога.