Я не могу понять, какой «правильный» способ развернуть проект 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), но я постараюсь сделать учебник, когда у меня будет время, и опубликую ссылку в редактировании / комментарии.
Между тем ссылка, которую я предоставил выше, является очень хорошей отправной точкой.
РЕДАКТИРОВАТЬ: теперь вы можете взглянуть на это пример настройки докера и связанные Сообщение блога.