Это старый вопрос, но я решил, что все равно отвечу на него, потому что недавно столкнулся с той же проблемой и подумал, что могу пролить свет на это.
Как работают каналы Django
Каналы Django — это еще один уровень поверх Django, который имеет два типа процессов:
- Тот, который принимает HTTP/веб-сокеты
- Тот, который запускает представления Django, обработчики веб-сокетов, фоновые задачи и т. д.
По сути, когда приходит запрос, он сначала попадает на интерфейсный сервер (Daphne), который принимает соединение HTTP/Websocket и помещает его в очередь Redis. Затем рабочий (потребитель) видит его, убирает из очереди и запускает логику представления (например, представления Django, обработчики WS и т. д.).
Почему это не сработало для вас
Потому что вы запускаете только рабочего (потребителя), и он блокирует выполнение интерфейса сервера (производителя). Это означает, что никакие соединения не будут приниматься, а рабочий просто смотрит на пустую очередь Redis.
Как я заставил это работать
Я запускаю Daphne, Redis и Workers как отдельные контейнеры для легкого масштабирования. Миграции БД, сбор статических файлов и т. д. выполняются только в контейнере Daphne. В этом контейнере будет работать только один экземпляр, чтобы гарантировать отсутствие параллельных миграций БД.
Рабочие, с другой стороны, могут масштабироваться вверх и вниз для обработки входящего трафика.
Как заставить это работать
Разделите установку на как минимум два контейнера. Я бы не рекомендовал запускать все в одном контейнере (например, используя Supervisor). Почему? Потому что, когда приходит время масштабировать установку, нет простого способа сделать это. Вы можете масштабировать свой контейнер до двух экземпляров, но это просто создаст еще один супервизор с daphne, redis, django в нем... если вы отделите рабочего от daphne, вы можете легко масштабировать рабочий контейнер для обработки растущих входящих запросов.
Один контейнер может работать:
#!/usr/bin/env bash
python wait_for_postgres.py
python manage.py migrate
python manage.py collectstatic --no-input
daphne team_up.asgi:channel_layer --port 8000 -b 0.0.0.0
в то время как другой:
#!/usr/bin/env bash
python wait_for_postgres.py
python manage.py runworker --only-channels=http.* --only-channels=websocket.* -v2
Команда makemigrations
Нет необходимости запускать команду в предоставленном вами сценарии, если что-то может заблокировать все это из-за какого-то вопроса, для которого он ожидает ввода (например, «Вы переименовали столбец X в Y?»).
Вместо этого вы можете выполнить его в работающем контейнере следующим образом:
docker exec -it <container_name> python manage.py makemigrations
person
roman
schedule
14.02.2017