У меня есть приложение django, работающее в Docker, которое использует каналы 2 (для приложения чата). При запуске docker -compose на локальном сайте и чат веб-сокета работает как шарм.
Теперь я попытался развернуть проект: я хочу запустить весь проект только на ASGI с daphne (вместо Daphne для Websocket и gunicorn для стандартных запросов). Ну, я пробовал это в течение трех дней, у меня не получается. Я полностью потерян.
Веб-сайт со «стандартными» http-запросами через https работает отлично, чат с веб-сокетами выдает ошибку 500, но сообщение об ошибке чудо для меня. Я действительно понятия не имею, что делать дальше.
(должен сказать, я новичок в django, nginx и websockets)
Моя настройка: Django , Django Каналы, Redis, Nginx, Docker, Дафна
Django Имя проекта - xtools
Это мое производство docker -составить:
version: '3.7'
services:
web:
container_name: 'web'
build:
context: ./app
dockerfile: Dockerfile.prod
command: daphne -b 0.0.0.0 -p 8000 xtools.asgi:application
volumes:
- static_volume:/home/app/web/static
- media_volume:/home/app/web/mediafiles
expose:
- 8000
env_file:
- ./.env.prod
depends_on:
- db
networks:
- docker-network
redis:
image: redis:latest
command: ["redis-server", "--bind", "redis", "--port", "6379"]
db:
image: postgres:12.0-alpine
volumes:
- postgres_data:/var/lib/postgresql/data/
env_file:
- ./.env.prod.db
networks:
- docker-network
nginx:
build: ./nginx
volumes:
- static_volume:/home/app/web/staticfiles
- media_volume:/home/app/web/mediafiles
- ./dhparam/dhparam-2048.pem:/etc/ssl/certs/dhparam-2048.pem
- /docker-volumes/etc/letsencrypt/live/example.com/fullchain.pem:/etc/letsencrypt/live/example.com/fullchain.pem
- /docker-volumes/etc/letsencrypt/live/example.com/privkey.pem:/etc/letsencrypt/live/example.com/privkey.pem
- /docker-volumes/data/letsencrypt:/data/letsencrypt
ports:
- 80:80
- 443:443
depends_on:
- web
networks:
- docker-network
volumes:
postgres_data:
static_volume:
media_volume:
networks:
docker-network:
driver: bridge
Это мой nginx conf:
upstream toolbox {
server web:8000;
}
proxy_cache_path /var/cache/nginx levels=1:2 keys_zone=tool_cache:10m max_size=10g inactive=60m use_temp_path=off;
server {
listen 443 ssl;
listen [::]:443 ssl;
server_name xtools.com;
server_tokens off;
ssl_certificate /etc/letsencrypt/live/example.com/fullchain.pem;
ssl_certificate_key /etc/letsencrypt/live/example.com/privkey.pem;
ssl_buffer_size 8k;
ssl_dhparam /etc/ssl/certs/dhparam-2048.pem;
ssl_protocols TLSv1.2 TLSv1.1 TLSv1;
ssl_prefer_server_ciphers on;
ssl_ciphers ECDH+AESGCM:ECDH+AES256:ECDH+AES128:DH+3DES:!ADH:!AECDH:!MD5;
ssl_ecdh_curve secp384r1;
ssl_session_tickets off;
ssl_stapling on;
ssl_stapling_verify on;
resolver 8.8.8.8;
location /ws/ {
try_files $uri @proxy_to_ws;
}
location @proxy_to_ws {
proxy_http_version 1.1;
proxy_set_header Upgrade $http_upgrade;
proxy_set_header Connection "upgrade";
proxy_redirect off;
proxy_pass http://toolbox;
}
location / {
proxy_pass http://toolbox;
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
proxy_set_header Host $host;
proxy_redirect off;
proxy_cache tool_cache;
proxy_cache_valid any 48h;
add_header X-Cached $upstream_cache_status;
# Simple requests
if ($request_method ~* "(GET|POST)") {
add_header "Access-Control-Allow-Origin" *;
}
}
location /static/ {
alias /home/app/web/staticfiles/;
}
location /mediafiles/ {
alias /home/app/web/mediafiles/;
}
}
И это сообщение об ошибке:
2020-04-08 14:40:11,802 ERROR Exception inside application: [Errno -2] Name does not resolve
File "/usr/local/lib/python3.8/site-packages/channels/sessions.py", line 183, in __call__
return await self.inner(receive, self.send)
File "/usr/local/lib/python3.8/site-packages/channels/middleware.py", line 41, in coroutine_call
await inner_instance(receive, send)
File "/usr/local/lib/python3.8/site-packages/channels/consumer.py", line 58, in __call__
await await_many_dispatch(
File "/usr/local/lib/python3.8/site-packages/channels/utils.py", line 58, in await_many_dispatch
await task
File "/usr/local/lib/python3.8/site-packages/channels_redis/core.py", line 434, in receive
message_channel, message = await self.receive_single(
File "/usr/local/lib/python3.8/site-packages/channels_redis/core.py", line 489, in receive_single
content = await self._brpop_with_clean(
File "/usr/local/lib/python3.8/site-packages/channels_redis/core.py", line 330, in _brpop_with_clean
async with self.connection(index) as connection:
File "/usr/local/lib/python3.8/site-packages/channels_redis/core.py", line 835, in __aenter__
self.conn = await self.pool.pop()
File "/usr/local/lib/python3.8/site-packages/channels_redis/core.py", line 73, in pop
conns.append(await aioredis.create_redis(**self.host, loop=loop))
File "/usr/local/lib/python3.8/site-packages/aioredis/commands/__init__.py", line 168, in create_redis
conn = await create_connection(address, db=db,
File "/usr/local/lib/python3.8/site-packages/aioredis/connection.py", line 111, in create_connection
reader, writer = await asyncio.wait_for(open_connection(
File "/usr/local/lib/python3.8/asyncio/tasks.py", line 455, in wait_for
return await fut
File "/usr/local/lib/python3.8/site-packages/aioredis/stream.py", line 23, in open_connection
transport, _ = await get_event_loop().create_connection(
File "/usr/local/lib/python3.8/asyncio/base_events.py", line 978, in create_connection
infos = await self._ensure_resolved(
File "/usr/local/lib/python3.8/asyncio/base_events.py", line 1350, in _ensure_resolved
return await loop.getaddrinfo(host, port, family=family, type=type,
File "/usr/local/lib/python3.8/asyncio/base_events.py", line 817, in getaddrinfo
return await self.run_in_executor(
File "/usr/local/lib/python3.8/concurrent/futures/thread.py", line 57, in run
result = self.fn(*self.args, **self.kwargs)
File "/usr/local/lib/python3.8/socket.py", line 914, in getaddrinfo
for res in _socket.getaddrinfo(host, port, family, type, proto, flags):
Redis говорит мне, что работает
redis_1 | 1:M 08 Apr 2020 14:37:56.433 * Ready to accept connections
Дафна принимает подключения, веб-сайт работает, как упоминалось ранее:
web | 2020-04-08 14:38:01,587 INFO Starting server at tcp:port=8000:interface=0.0.0.0
web | 2020-04-08 14:38:01,588 INFO HTTP/2 support not enabled (install the http2 and tls Twisted extras)
web | 2020-04-08 14:38:01,589 INFO Configuring endpoint tcp:port=8000:interface=0.0.0.0
web | 2020-04-08 14:38:01,590 INFO Listening on TCP address 0.0.0.0:8000
web | 2020-04-08 14:38:05,597 ERROR Exception inside application: [Errno -2] Name does not resolve
Я понятия не имею, к чему относится это «Имя не разрешается». Мой потребительский код отлично работает в моей местной среде. В производстве потребитель даже не вызывается (я поместил в него много операторов print, просто чтобы посмотреть, есть ли где-то ошибка).
Nginx В журналах ошибок повторяется эта ошибка при открытии страница чата с веб-сокетами:
2020/04/08 17:36:12 [emerg] 18725#18725: bind() to 0.0.0.0:80 failed (98: Address already in use)
25 2020/04/08 17:36:12 [emerg] 18725#18725: still could not bind()
26 2020/04/08 17:36:17 [notice] 18736#18736: signal process started
27 2020/04/08 17:36:20 [notice] 18741#18741: signal process started
Мой клиент Websocket Call
var ws_scheme = window.location.protocol == "https:" ? "wss://" : "ws://";
var chatSocket = new ReconnectingWebSocket(
ws_scheme + window.location.host +
'/ws/chat/' + roomName + '/'
);
что еще я могу сделать? Я проверил сервер Redis, который работает. Дафна работает и обслуживает страницы, как и должно быть.
Любая помощь приветствуется! Спасибо, Бомби