Docker como Django + uwsgi / gunicorn + nginx?

3

Eu não consigo entender qual é a maneira "correta" de implantar um projeto do Django que usa uwsgi / gunicorn (eu ainda não decidi o que usar, provavelmente o uwsgi, pois tem melhores performances, sugestões?) e nginx usando o docker.

Vi que algumas pessoas colocam tudo no mesmo contêiner. Não sou especialista em docker, mas o contêiner deve fazer apenas uma (1) coisa. Então, ter o Django + nginx parece ser 2 em vez de 1.

Agora, minha ideia da implantação é:

  • um contêiner com Django e uwsgi. No final do Dockerfile eu executo o script uwsgi. Este contêiner expõe a porta 8000
  • um contêiner com nginx que está vinculado ao django one. Isso expõe a porta 80 e faz proxy das solicitações para o django.

Existe alguma outra maneira de fazer isso? Existe um tutorial que cobre este caso um pouco mais profundo. Eu preciso de uma produção sólida, não apenas para testar algum código no meu pc.

    
por EsseTi 14.06.2016 / 11:12

3 respostas

2

Atualmente estou construindo um aplicativo django do jeito que você quer.

Eu uso o docker-compose para fazer isso. Este é o meu 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 for uWSGI:

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

Dockerfile for 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;"]

E esta é a minha árvore de diretórios:

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

Portanto, eu construo minhas imagens com docker-compose build e, em seguida, inicio novos contêineres em segundo plano com docker-compose up -d , então posso executar algumas tarefas de configuração, como instalar o django, gerar chave secreta ou o que você quiser que seu contêiner esteja pronto.

Os contêineres nginx e uwsgi usam volumes compartilhados para ler arquivos de configuração E para se comunicar com um soquete de arquivo.

Bem, não tenho certeza se é o melhor caminho, mas é um trabalho em andamento.

    
por 01.07.2016 / 15:28
2

Eu encontrei esta resposta de Michael Hampton :

"This only works if the processes are in the same host, VM or container, because it tries to make a connection to the same machine. When they are in different containers, it does not work.

You need to alter your nginx configuration so that it uses the internal IP address of the uwsgi container."

E, definitivamente, é algo que você deve ter em mente se você tiver o Nginx em um contêiner diferente e também definir o nginx.conf, apontando seu diretório de arquivos estáticos como um alias que impede um problema de segurança.

Espero que esse código funcione para todos. Demorei algumas horas para descobrir como compor o Gunicorn, o docker e o 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;
   }
}

E para o 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
    
por 16.04.2017 / 20:32
2

Eu finalmente consegui construir meu docker-compose para Django, Gunicorn, Nginx e Postgres graças (principalmente) a este tutorial .

Basicamente, você tem um container para Nginx, um container para Django + Gunicorn, e um container (ou mais se você quiser múltiplos bancos de dados) para Postgres.

Você também pode dividir o Django + Gunicorn em dois containers, mas acho que faz mais sentido tê-los em um container, porque um processo do Gunicorn sempre executa um aplicativo wsgi do Django. Eu não acho que você pode ter NGunicorn rodando 1 Django, 1 Gunicorn rodando N Django, ou N Gunicorn rodando N Django, então não há possibilidades de escalar aqui, exceto escalar N recipientes Gunicorn + Django.

Os volumes são usados para manter os dados dos bancos de dados (e opcionalmente os arquivos static / media do Django) permanentemente.

Você estava solicitando um tutorial ou outras maneiras de fazer isso, por isso não postarei meu conteúdo docker-compose.yml aqui (porque também exigiria o Dockerfile, o arquivo conf Nginx, o arquivo conf Gunicorn, os bancos de dados arquivos env, e muitos trechos de código Python como configurações de bancos de dados), mas vou tentar fazer um tutorial quando eu tiver tempo e postar o link em uma edição / comentário.

Enquanto isso, o link que eu forneci acima é um bom ponto de partida.

EDIT: agora você pode dar uma olhada neste exemplo de configuração da janela de encaixe e os relacionados < href="http://pawamoy.github.io/2018/02/01/docker-compose-django-postgres-nginx.html"> postagem no blog .

    
por 18.01.2018 / 17:40