Продвинутый Django 5 для продолжающих

Прогресс по курсу:  0/193

11.7 Подготовка к деплою, Gunicorn и NGINX в Docker Compose
3 из 3 шагов пройдено

Gunicorn

Вместо встроенного веб-сервера в Django, который подходит только для разработки, мы будем использовать веб-сервер Gunicorn. Он будет работать только как сервер приложений. Выдача статического контента будет возложена на веб-сервер Nginx, он же будет выступать в качестве обратного прокси для сервера приложений Gunicorn, что позволит снизить нагрузку на него.

Gunicorn, так же как и библиотеку для PostgreSQL, нужно добавить в файл зависимостей requerements.txt:

gunicorn==21.2.0


Что-бы было удобно использовать образ для локальной разработки и для продакшена, создадим второй файл с названием docker-compose.prod.yml. Он будет аналогичен предыдущему образу за исключением нескольких моментов: 

version: '3.8'

services:
  web:
    # Берем Dockerfile из каталога app
    build: app
    # Запускаем сервер gunicorn
    command: gunicorn core.wsgi:application --bind 0.0.0.0:8000
    # Открываем порт 8000 внутри и снаружи
    ports:
      - 8000:8000
    # Файл содержащий переменные для контейнера
    env_file:
      - .env.prod
    # Дожидаемся запуска контейнера db и memcached
    depends_on:
      - db
      - memcached
  db:
      image: postgres:15
      volumes:
        - postgres_data:/var/lib/postgresql/data/
      environment:
        - POSTGRES_USER=book_django
        - POSTGRES_PASSWORD=pass_book_django
        - POSTGRES_DB=book_django
  memcached:
      image: memcached:1.6.21
      ports:
        - 11211:11211
volumes:
  postgres_data:

В этом файле мы убрали строку, где пробрасывали содержимое папки app в контейнер так как это не понадобится.


Создадим файл .env.prod, в который поместим те-же переменные, как и в файле env.dev.
Подразумевается, что для локальной разработки и что для деплоя, вы используете разные значения этих переменных:

DEBUG = True
SECRET_KEY = 'django-insecure-xxxxxxxxxxxx'
DJANGO_ALLOWED_HOSTS = '127.0.0.1'
CSRF_TRUSTED_ORIGINS = 'http://127.0.0.1'
CACHES_BACKEND = 'django.core.cache.backends.memcached.PyMemcacheCache'
CACHES_LOCATION = 'memcached:11211'
INTERNAL_IPS = '127.0.0.1'

SQL_ENGINE=django.db.backends.postgresql
SQL_DATABASE=book_django
SQL_USER=book_django
SQL_PASSWORD=pass_book_django
SQL_HOST=db
SQL_PORT=5432
DATABASE=postgres


На данный момент структура созданных файлов и папок следующая:


Выполним остановку предыдущих контейнеров, удалим их:

docker-compose down -v


Выполним билд нового контейнера для деплоя:

docker-compose -f docker-compose.prod.yml up -d --build


Выполним миграции, при которых будет создана структура нашей базы данных book_django:

docker-compose exec web python manage.py migrate --noinput


Теперь проверим работу, откроем в браузере http://127.0.0.1:8000, мы видим что наш проект работает нормально и с сервером приложений Gunicorn:


  • Комментария
Будьте вежливы и соблюдайте наши принципы сообщества. Пожалуйста, не оставляйте решения и подсказки в комментариях, для этого есть отдельный форум.
Оставить комментарий

ModuleNotFoundError: No module named 'core'
[2023-11-09 14:28:22 +0300] [51982] [INFO] Worker exiting (pid: 51982)
[2023-11-09 14:28:22 +0300] [51981] [ERROR] Worker (pid:51982) exited with code 3
[2023-11-09 14:28:22 +0300] [51981] [ERROR] Shutting down: Master
[2023-11-09 14:28:22 +0300] [51981] [ERROR] Reason: Worker failed to boot.

Подскажите, в чем ошибка и как исправить?

@Мочалов_Антон, замените core.wsgi на имя_проекта.wsgi, в команде:

command: gunicorn core.wsgi:application --bind 0.0.0.0:8000

да все заработало но вы ничего не исправили!

 

@Мочалов_Антон, замените core.wsgi на имя_проекта.wsgi, в команде:

command: gunicorn core.wsgi:application --bind 0.0.0.0:8000

в этом коде вот эта команда:

command: gunicorn django_htmx.wsgi:application --bind 0.0.0.0:8000

вот тут должно быть имя джанго проекта такое как проходящий человек указал в своем проекте!

command: gunicorn ВАШЕ_ИМЯ_ПРОЕКТА.wsgi:application --bind 0.0.0.0:8000

version: '3.8'

services:
  web:
    # Берем Dockerfile из каталога app
    build: app
    # Запускаем сервер gunicorn
    command: gunicorn django_htmx.wsgi:application --bind 0.0.0.0:8000
    # Открываем порт 8000 внутри и снаружи
    ports:
      - 8000:8000
    # Файл содержащий переменные для контейнера
    env_file:
      - .env.prod
    # Дожидаемся запуска контейнера db и memcached
    depends_on:
      - db
      - memcached
  db:
      image: postgres:15
      volumes:
        - postgres_data:/var/lib/postgresql/data/
      environment:
        - POSTGRES_USER=book_django
        - POSTGRES_PASSWORD=pass_book_django
        - POSTGRES_DB=book_django
  memcached:
      image: memcached:1.6.21
      ports:
        - 11211:11211
volumes:
  postgres_data:


 

@No_Name, А что надо было исправить? У нас по курсу проект называется core.

У меня пишет что попытка соединения не удалась. Почему то контейнер web_01 переходит в статус Exited(3).

Логи:

2023-11-26 00:21:50 [2023-11-25 20:21:50 +0000] [1] [INFO] Starting gunicorn 21.2.0
2023-11-26 00:21:50 [2023-11-25 20:21:50 +0000] [1] [INFO] Listening at: http://0.0.0.0:8000 (1)
2023-11-26 00:21:50 [2023-11-25 20:21:50 +0000] [1] [INFO] Using worker: sync
2023-11-26 00:21:50 [2023-11-25 20:21:50 +0000] [7] [INFO] Booting worker with pid: 7
2023-11-26 00:21:50 [2023-11-25 20:21:50 +0000] [7] [ERROR] Exception in worker process
2023-11-26 00:21:50 Traceback (most recent call last):
2023-11-26 00:21:50   File "/usr/local/lib/python3.12/site-packages/gunicorn/arbiter.py", line 609, in spawn_worker
2023-11-26 00:21:50     worker.init_process()
2023-11-26 00:21:50   File "/usr/local/lib/python3.12/site-packages/gunicorn/workers/base.py", line 134, in init_process
2023-11-26 00:21:50     self.load_wsgi()
2023-11-26 00:21:50   File "/usr/local/lib/python3.12/site-packages/gunicorn/workers/base.py", line 146, in load_wsgi
2023-11-26 00:21:50     self.wsgi = self.app.wsgi()
2023-11-26 00:21:50                 ^^^^^^^^^^^^^^^
2023-11-26 00:21:50   File "/usr/local/lib/python3.12/site-packages/gunicorn/app/base.py", line 67, in wsgi
2023-11-26 00:21:50     self.callable = self.load()
2023-11-26 00:21:50                     ^^^^^^^^^^^
2023-11-26 00:21:50   File "/usr/local/lib/python3.12/site-packages/gunicorn/app/wsgiapp.py", line 58, in load
2023-11-26 00:21:50     return self.load_wsgiapp()
2023-11-26 00:21:50            ^^^^^^^^^^^^^^^^^^^
2023-11-26 00:21:50   File "/usr/local/lib/python3.12/site-packages/gunicorn/app/wsgiapp.py", line 48, in load_wsgiapp
2023-11-26 00:21:50     return util.import_app(self.app_uri)
2023-11-26 00:21:50            ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
2023-11-26 00:21:50   File "/usr/local/lib/python3.12/site-packages/gunicorn/util.py", line 371, in import_app
2023-11-26 00:21:50     mod = importlib.import_module(module)
2023-11-26 00:21:50           ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
2023-11-26 00:21:50   File "/usr/local/lib/python3.12/importlib/__init__.py", line 90, in import_module
2023-11-26 00:21:50     return _bootstrap._gcd_import(name[level:], package, level)
2023-11-26 00:21:50            ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
2023-11-26 00:21:50   File "<frozen importlib._bootstrap>", line 1381, in _gcd_import
2023-11-26 00:21:50   File "<frozen importlib._bootstrap>", line 1354, in _find_and_load
2023-11-26 00:21:50   File "<frozen importlib._bootstrap>", line 1304, in _find_and_load_unlocked
2023-11-26 00:21:50   File "<frozen importlib._bootstrap>", line 488, in _call_with_frames_removed
2023-11-26 00:21:50   File "<frozen importlib._bootstrap>", line 1381, in _gcd_import
2023-11-26 00:21:50   File "<frozen importlib._bootstrap>", line 1354, in _find_and_load
2023-11-26 00:21:50   File "<frozen importlib._bootstrap>", line 1318, in _find_and_load_unlocked
2023-11-26 00:21:50 ModuleNotFoundError: No module named 'core'
2023-11-26 00:21:50 [2023-11-25 20:21:50 +0000] [7] [INFO] Worker exiting (pid: 7)
2023-11-26 00:21:50 [2023-11-25 20:21:50 +0000] [1] [ERROR] Worker (pid:7) exited with code 3
2023-11-26 00:21:50 [2023-11-25 20:21:50 +0000] [1] [ERROR] Shutting down: Master
2023-11-26 00:21:50 [2023-11-25 20:21:50 +0000] [1] [ERROR] Reason: Worker failed to boot.
2023-11-26 00:22:35 [2023-11-25 20:22:35 +0000] [1] [INFO] Starting gunicorn 21.2.0
2023-11-26 00:22:35 [2023-11-25 20:22:35 +0000] [1] [INFO] Listening at: http://0.0.0.0:8000 (1)
2023-11-26 00:22:35 [2023-11-25 20:22:35 +0000] [1] [INFO] Using worker: sync
2023-11-26 00:22:35 [2023-11-25 20:22:35 +0000] [7] [INFO] Booting worker with pid: 7
2023-11-26 00:22:35 [2023-11-25 20:22:35 +0000] [7] [ERROR] Exception in worker process
2023-11-26 00:22:35 Traceback (most recent call last):
2023-11-26 00:22:35   File "/usr/local/lib/python3.12/site-packages/gunicorn/arbiter.py", line 609, in spawn_worker
2023-11-26 00:22:35     worker.init_process()
2023-11-26 00:22:35   File "/usr/local/lib/python3.12/site-packages/gunicorn/workers/base.py", line 134, in init_process
2023-11-26 00:22:35     self.load_wsgi()
2023-11-26 00:22:35   File "/usr/local/lib/python3.12/site-packages/gunicorn/workers/base.py", line 146, in load_wsgi
2023-11-26 00:22:35     self.wsgi = self.app.wsgi()
2023-11-26 00:22:35                 ^^^^^^^^^^^^^^^
2023-11-26 00:22:35   File "/usr/local/lib/python3.12/site-packages/gunicorn/app/base.py", line 67, in wsgi
2023-11-26 00:22:35     self.callable = self.load()
2023-11-26 00:22:35                     ^^^^^^^^^^^
2023-11-26 00:22:35   File "/usr/local/lib/python3.12/site-packages/gunicorn/app/wsgiapp.py", line 58, in load
2023-11-26 00:22:35     return self.load_wsgiapp()
2023-11-26 00:22:35            ^^^^^^^^^^^^^^^^^^^
2023-11-26 00:22:35   File "/usr/local/lib/python3.12/site-packages/gunicorn/app/wsgiapp.py", line 48, in load_wsgiapp
2023-11-26 00:22:35     return util.import_app(self.app_uri)
2023-11-26 00:22:35            ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
2023-11-26 00:22:35   File "/usr/local/lib/python3.12/site-packages/gunicorn/util.py", line 371, in import_app
2023-11-26 00:22:35     mod = importlib.import_module(module)
2023-11-26 00:22:35           ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
2023-11-26 00:22:35   File "/usr/local/lib/python3.12/importlib/__init__.py", line 90, in import_module
2023-11-26 00:22:35     return _bootstrap._gcd_import(name[level:], package, level)
2023-11-26 00:22:35            ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
2023-11-26 00:22:35   File "<frozen importlib._bootstrap>", line 1381, in _gcd_import
2023-11-26 00:22:35   File "<frozen importlib._bootstrap>", line 1354, in _find_and_load
2023-11-26 00:22:35   File "<frozen importlib._bootstrap>", line 1304, in _find_and_load_unlocked
2023-11-26 00:22:35   File "<frozen importlib._bootstrap>", line 488, in _call_with_frames_removed
2023-11-26 00:22:35   File "<frozen importlib._bootstrap>", line 1381, in _gcd_import
2023-11-26 00:22:35   File "<frozen importlib._bootstrap>", line 1354, in _find_and_load
2023-11-26 00:22:35   File "<frozen importlib._bootstrap>", line 1318, in _find_and_load_unlocked
2023-11-26 00:22:35 ModuleNotFoundError: No module named 'core'
2023-11-26 00:22:35 [2023-11-25 20:22:35 +0000] [7] [INFO] Worker exiting (pid: 7)
2023-11-26 00:22:35 [2023-11-25 20:22:35 +0000] [1] [ERROR] Worker (pid:7) exited with code 3
2023-11-26 00:22:35 [2023-11-25 20:22:35 +0000] [1] [ERROR] Shutting down: Master
2023-11-26 00:22:35 [2023-11-25 20:22:35 +0000] [1] [ERROR] Reason: Worker failed to boot.

Если меняю в команде core.wsgi на имя_проекта.wsgi то выходит ошибка при миграции

django.core.cache.backends.base.InvalidCacheBackendError: Could not find backend 'None': None doesn't look like a module path

а в браузере Internal Server Error.

@Григорий_Кожанов, Судя по тому проекту, у вас должно быть django_htmx.wsqi

А далее у нас ошибка по файлу .env.prod, а именно не хватает переменных по кешу, добавьте их:

CACHES_BACKEND = 'django.core.cache.backends.memcached.PyMemcacheCache'
CACHES_LOCATION = 'memcached:11211'

@Илья_Перминов, Да, спасибо за помощь, всё заработало.