Запуск daphne в Docker без супервизора
В настоящее время я запускаю daphne с помощью супервизора. Вот мой конфиг супервизора:
[supervisord]
user = root
nodaemon = true
[fcgi-program:daphne]
socket=tcp://api:9000
directory=/home/docker/api
ommand=./.docker/services/api/files/startup-operations.sh && daphne -u /run/daphne/daphne%(process_num)d.sock --fd 0 --proxy-headers main.asgi:application
numprocs=2
process_name=asgi%(process_num)d
autostart=true
autorestart=false
stdout_logfile=/dev/stdout
stdout_logfile_maxbytes=0
redirect_stderr=true
killasgroup=true
startsecs=0
exitcodes=0
Вот, в документации по каналам приводится ровно один пример, и он использует супервизор: https://channels.readthedocs.io/en/latest/deploying.html
Однако я прочитал вот это: https://advancedweb.hu/supervisor-with-docker-lessons-learned/
...который выступает за отказ от использования супервизора в докере, и я согласен с этой статьей.
Одна из проблем использования supervisor, о которой не говорится в статье, заключается в том, что у меня есть база данных in-memory, которая должна быть доступна для основного приложения.
Приведенный выше файл конфигурации - это всего лишь одна программа, которая запускает скрипт startup-operations.sh
, но раньше это были две программы: Одна программа загружала данные в память, а другая запускала основное приложение.
Конечно, я могу загрузить эти данные в память в startup-operations.sh
и покончить с ними, но это не удалит супервизор из моего образа. Кажется, что если я выполняю только одну серию команд, я должен быть в состоянии не использовать супервизор в своем образе.
У меня также были ошибки, вызванные нехваткой места в моем ограниченном экземпляре EC2, который одновременно создает и запускает этот образ (я знаю, что идеально было бы создать образ локально и загрузить его в ECR, а затем запустить на сервере, но это тестовый сервер, и у нас сейчас нет таких возможностей), и я хотел уменьшить объем памяти, требуемый как для создания образа, так и для запуска контейнера. Удаление супервизора из сборки и контейнера помогло бы в этом.
Учитывая статью по ссылке, проблему с разделением памяти между программами супервизора и ограничения по объему памяти, я решил попробовать удалить супервизор как из процесса сборки, так и из финального образа моего докеризованного приложения.
Раньше у меня была такая директива CMD
в моем Dockerfile:
CMD ["supervisord", "--nodaemon", "-c", "/etc/supervisor/conf.d/supervisor.conf"]
Теперь у меня есть эта директива CMD
в моем Dockerfile:
CMD ["/bin/bash", "-c", "mkdir -p /run/daphne && /home/docker/api/.docker/services/api/files/startup-operations.sh && daphne -u /run/daphne/daphne.sock --fd 0 --proxy-headers main.asgi:application"]
Все собирается и работает нормально, но когда я пытаюсь получить доступ к конечной точке (например, https://host/admin/
), я получаю ошибку 502 Bad Gateway от nginx, и эта ошибка отображается в логах для основного контейнера приложения:
daphne.server CRITICAL Listen failure: [Errno 88] Socket operation on non-socket
В результате сервер отключается.
Я полагаю, что это связано с этой строкой в оригинальной конфигурации супервизора:
socket=tcp://api:9000
Есть ли строка, которую я могу добавить в директиву CMD
, чтобы создать этот сокет и избежать этой ошибки?
Кстати, вот содержимое startup-operations.sh
:
#!/usr/bin/env bash
echo Waiting for the database to be ready...
./wait-for-db.sh
echo Collecting static files...
python manage.py collectstatic --no-input
echo Done.
echo Running migrations...
python manage.py migrate
echo Done.
echo Creating admin user...
python manage.py create_admin_user
echo Done.
# NOTE: This is the in-memory database.
# We are using local memory to store vectors in development/testing
# and a separate server in staging/production.
echo Initializing vector store...
python manage.py initialize_vector_store
echo Done.
echo Startup operations completed successfully!
exit 0