I have an application running in Docker which is using django 2.2 (Django DRF) + channels 3, daphne, nginx.Now I'm trying to deploy the application. DRF APIs are working fine, but supervisord shows that asgi is repeating spawned and exited, and when the frontend app(react) tries to connect to the websocket it shows 500 error. This doesn't occur in my local. I've been looking for the error messages on Google but couldn't find answers. Looks like it comes from my misconfiguration, but I have no idea.
This is my docker-compose.
version: '2'services: db: build: ../containers/mysql ports: - "3306:3306" env_file: staging.env volumes: - ./mysql:/var/lib/mysql - ../containers/mysql/conf:/etc/mysql/conf.d - ../containers/mysql/init:/docker-entrypoint-initdb.d redis: image: redis ports: - "6379:6379" django: build: ../containers/django command: daphne -b 0.0.0.0 -p 8001 myapp.asgi:application volumes: - ../../myapp:/code - ../../logs/django:/var/log/django - ../../logs/uwsgi:/var/log/uwsgi - ../../logs/supervisor:/var/log/supervisor ports: - "8002:8001" links: - db - redis depends_on: - db - redis entrypoint: ./scripts/wait-for-it.sh db:3306 --strict -- supervisor: build: ../containers/django command: /usr/bin/supervisord -n -c /etc/supervisor/supervisord.conf volumes_from: - django volumes: - ../containers/django/supervisord.conf:/etc/supervisor/supervisord.conf - ../../daphne:/run/daphne ports: - "9999" links: - db - redis depends_on: - django entrypoint: ./scripts/wait-for-it.sh django:8001 -- nginx: image: nginx ports: - "80:80" - "443:443" links: - django depends_on: - django volumes: - ../../myapp:/code - ../containers/nginx/nginx_staging.conf:/etc/nginx/nginx.conf:ro - ../containers/nginx/uwsgi_params:/etc/nginx/uwsgi_params:ro - ../containers/nginx/sslkey_staging:/etc/nginx/sslkey - ../../logs/nginx:/var/log/nginx - /etc/localtime:/etc/localtime:ro - ../../react-app/build:/var/www
Dockerfile:
FROM python:3.6ENV PYTHONUNBUFFERED 1RUN apt-get update -yRUN apt-get install -y supervisorRUN apt-get install -y sudoRUN mkdir /codeWORKDIR /codeRUN pip install --upgrade pipADD requirements.txt /code/RUN pip install -r requirements.txtRUN easy_install dnspythonRUN groupadd djangoRUN useradd -g django -s /sbin/nologin -u 1005 djangoRUN mkdir /var/log/djangoRUN chmod 777 /var/log/djangoRUN chown django:django /var/log/djangoRUN mkdir /run/daphneRUN chmod 777 /run/daphne/RUN chown django:django /run/daphne/RUN test -e /usr/bin/python || ln -s /usr/bin/python2.7.distrib /usr/bin/python
requirements.txt:
Django==2.2.3mysqlclient==1.4.6uwsgi==2.0.15pytzdjangorestframework==3.9.0django-cors-headers==2.5.2django-filterdjango-pure-paginationrequeststornado==4.5.3tornado-redis==2.4.18pycryptodjango-widget-tweakspillowdj-rest-authdjango-allauthchannelschannels_redisdaphne
supervisord.conf (i wrote this referencing https://channels.readthedocs.io/en/latest/deploying.html#nginx-supervisor-ubuntu)
[supervisord]nodaemon=trueuser=djangologfile=/var/log/supervisor/supervisord.logpidfile=/tmp/supervisord.pidchildlogdir=/var/log/supervisor[fcgi-program:asgi]# TCP socket used by Nginx backend upstreamsocket=tcp://0.0.0.0:8001# Directory where your site's project files are locateddirectory=/code# Each process needs to have a separate socket file, so we use process_numcommand=daphne -u /run/daphne/daphne%(process_num)d.sock --fd 0 --access-log - --proxy-headers myapp.asgi:application# Number of processes to startup, roughly the number of CPUs you havenumprocs=4# Give each process a unique name so they can be told apartprocess_name=asgi%(process_num)d# Automatically start and recover processesautostart=trueautorestart=true# Choose where you want your log to gostdout_logfile=/var/log/supervisor/asgi.logredirect_stderr=true
This is nginx config file:
worker_processes 1;user nginx nginx;pid /tmp/nginx.pid;error_log /var/log/nginx/error.log warn;events { worker_connections 1024; accept_mutex_delay 100ms;# multi_accept on;# use epoll;}http { include mime.types; # fallback in case we can't determine a type default_type application/octet-stream; log_format token '$remote_addr - $remote_user [$time_local] ''"$request" $status $body_bytes_sent ''"$http_referer" $http_authorization "$http_user_agent"'; access_log /var/log/nginx/access.log token; sendfile on; ssl_session_cache shared:SSL:10m; ssl_session_timeout 10m; ssl_protocols TLSv1.2 TLSv1.3; ssl_prefer_server_ciphers off; ssl_ciphers "ECDHE-ECDSA-AES128-GCM-SHA256:ECDHE-RSA-AES128-GCM-SHA256:ECDHE-ECDSA-AES256-GCM-SHA384:ECDHE-RSA-AES256-GCM-SHA384:ECDHE-ECDSA-CHACHA20-POLY1305:ECDHE-RSA-CHACHA20-POLY1305:DHE-RSA-AES128-GCM-SHA256:DHE-RSA-AES256-GCM-SHA384:ECDHE-RSA-AES128-SHA"; upstream backend { server django:8001; } server { listen 80; server_name myapp.com; return 301 https://$host$request_uri; } server { listen 443 ssl; ssl_certificate /etc/nginx/sslkey/fullchain.pem; ssl_certificate_key /etc/nginx/sslkey/privkey.pem; ssl_dhparam /etc/nginx/sslkey/ssl-dhparams.pem; client_max_body_size 4G; # set the correct host(s) for your site server_name myapp.com; keepalive_timeout 5; location / { root /var/www; index index.html index.htm; try_files $uri /index.html; } location /media/ { root /code/public; } location /backend/ { try_files $uri @webapp; } location @webapp { proxy_pass http://backend; proxy_http_version 1.1; proxy_set_header Upgrade $http_upgrade; proxy_set_header Connection "upgrade"; proxy_redirect off; proxy_set_header Host $host; proxy_set_header X-Real-IP $remote_addr; proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for; proxy_set_header X-Forwarded-Host $server_name; } }}
And this is the error message:
2021-01-08 09:48:17,782 INFO Starting server at tcp:port=8001:interface=0.0.0.02021-01-08 09:48:17,784 INFO HTTP/2 support not enabled (install the http2 and tls Twisted extras)2021-01-08 09:48:17,785 INFO Configuring endpoint tcp:port=8001:interface=0.0.0.02021-01-08 09:48:17,787 INFO Listening on TCP address 0.0.0.0:8001wait-for-it.sh: django:8001 is available after 2 seconds2021-01-08 09:48:18,416 INFO Set uid to user 1005 succeeded2021-01-08 09:48:18,422 INFO Creating socket tcp://0.0.0.0:80012021-01-08 09:48:18,423 INFO Closing socket tcp://0.0.0.0:80012021-01-08 09:48:18,423 INFO supervisord started with pid 12021-01-08 09:48:19,425 INFO Creating socket tcp://0.0.0.0:80012021-01-08 09:48:19,428 INFO spawned: 'asgi1' with pid 192021-01-08 09:48:19,432 INFO spawned: 'asgi0' with pid 202021-01-08 09:48:19,439 INFO spawned: 'asgi3' with pid 212021-01-08 09:48:19,451 INFO spawned: 'asgi2' with pid 222021-01-08 09:48:20,463 INFO success: asgi1 entered RUNNING state, process has stayed up for > than 1 seconds (startsecs)2021-01-08 09:48:20,464 INFO success: asgi0 entered RUNNING state, process has stayed up for > than 1 seconds (startsecs)2021-01-08 09:48:20,465 INFO success: asgi3 entered RUNNING state, process has stayed up for > than 1 seconds (startsecs)2021-01-08 09:48:20,465 INFO success: asgi2 entered RUNNING state, process has stayed up for > than 1 seconds (startsecs)2021-01-08 09:48:25,337 INFO exited: asgi3 (exit status 0; expected)2021-01-08 09:48:25,341 INFO spawned: 'asgi3' with pid 272021-01-08 09:48:25,346 INFO exited: asgi2 (exit status 0; expected)2021-01-08 09:48:25,349 INFO spawned: 'asgi2' with pid 282021-01-08 09:48:25,354 INFO exited: asgi0 (exit status 0; expected)2021-01-08 09:48:25,360 INFO spawned: 'asgi0' with pid 292021-01-08 09:48:25,362 INFO exited: asgi1 (exit status 0; expected)2021-01-08 09:48:26,371 INFO spawned: 'asgi1' with pid 33[08/Jan/2021:09:49:00] "WSCONNECTING /backend/ws/chat/12/" - -ERROR Exception inside application: [Errno -2] Name or service not knownTraceback (most recent call last):File "/usr/local/lib/python3.6/site-packages/channels/utils.py", line 51, in await_many_dispatch await dispatch(result)File "/usr/local/lib/python3.6/site-packages/asgiref/sync.py", line 304, in __call__ ret = await asyncio.wait_for(future, timeout=None)File "/usr/local/lib/python3.6/asyncio/tasks.py", line 339, in wait_for return (yield from fut)File "/usr/local/lib/python3.6/concurrent/futures/thread.py", line 56, in run result = self.fn(*self.args, **self.kwargs)File "/usr/local/lib/python3.6/site-packages/channels/db.py", line 13, in thread_handler return super().thread_handler(loop, *args, **kwargs)File "/usr/local/lib/python3.6/site-packages/asgiref/sync.py", line 343, in thread_handler return func(*args, **kwargs)File "/usr/local/lib/python3.6/site-packages/channels/consumer.py", line 125, in dispatch handler(message)File "/usr/local/lib/python3.6/site-packages/channels/generic/websocket.py", line 39, in websocket_connect self.connect()File "./chat/consumers.py", line 92, in connect self.channel_nameFile "/usr/local/lib/python3.6/site-packages/asgiref/sync.py", line 147, in __call__ return call_result.result()File "/usr/local/lib/python3.6/concurrent/futures/_base.py", line 425, in result return self.__get_result()File "/usr/local/lib/python3.6/concurrent/futures/_base.py", line 384, in __get_result raise self._exceptionFile "/usr/local/lib/python3.6/site-packages/asgiref/sync.py", line 212, in main_wrap result = await self.awaitable(*args, **kwargs)File "/usr/local/lib/python3.6/site-packages/channels_redis/core.py", line 622, in group_add async with self.connection(self.consistent_hash(group)) as connection:File "/usr/local/lib/python3.6/site-packages/channels_redis/core.py", line 884, in __aenter__ self.conn = await self.pool.pop()File "/usr/local/lib/python3.6/site-packages/channels_redis/core.py", line 80, in pop conn = await aioredis.create_redis(**self.host, loop=loop)File "/usr/local/lib/python3.6/site-packages/aioredis/commands/__init__.py", line 175, in create_redis loop=loop)File "/usr/local/lib/python3.6/site-packages/aioredis/connection.py", line 113, in create_connection timeout)File "/usr/local/lib/python3.6/asyncio/tasks.py", line 339, in wait_for return (yield from fut)File "/usr/local/lib/python3.6/site-packages/aioredis/stream.py", line 24, in open_connection lambda: protocol, host, port, **kwds)File "/usr/local/lib/python3.6/asyncio/base_events.py", line 754, in create_connection infos = f1.result()File "/usr/local/lib/python3.6/concurrent/futures/thread.py", line 56, in run result = self.fn(*self.args, **self.kwargs)File "/usr/local/lib/python3.6/socket.py", line 745, in getaddrinfo for res in _socket.getaddrinfo(host, port, family, type, proto, flags):socket.gaierror: [Errno -2] Name or service not knownDuring handling of the above exception, another exception occurred:Traceback (most recent call last):File "/usr/local/lib/python3.6/site-packages/channels/routing.py", line 71, in __call__ return await application(scope, receive, send)File "/usr/local/lib/python3.6/site-packages/asgiref/compatibility.py", line 34, in new_application return await instance(receive, send)File "./chat/token_auth.py", line 44, in __call__ return await self.inner(self.scope, receive, send)File "/usr/local/lib/python3.6/site-packages/channels/sessions.py", line 47, in __call__ return await self.inner(dict(scope, cookies=cookies), receive, send)File "/usr/local/lib/python3.6/site-packages/channels/sessions.py", line 254, in __call__ return await self.inner(wrapper.scope, receive, wrapper.send)File "/usr/local/lib/python3.6/site-packages/channels/auth.py", line 181, in __call__ return await super().__call__(scope, receive, send)File "/usr/local/lib/python3.6/site-packages/channels/middleware.py", line 26, in __call__ return await self.inner(scope, receive, send)File "/usr/local/lib/python3.6/site-packages/channels/routing.py", line 160, in __call__ send,File "/usr/local/lib/python3.6/site-packages/channels/consumer.py", line 94, in app return await consumer(scope, receive, send)File "/usr/local/lib/python3.6/site-packages/channels/consumer.py", line 59, in __call__ [receive, self.channel_receive], self.dispatchFile "/usr/local/lib/python3.6/site-packages/channels/utils.py", line 58, in await_many_dispatch await taskFile "/usr/local/lib/python3.6/site-packages/channels_redis/core.py", line 469, in receive real_channelFile "/usr/local/lib/python3.6/site-packages/channels_redis/core.py", line 524, in receive_single index, channel_key, timeout=self.brpop_timeoutFile "/usr/local/lib/python3.6/site-packages/channels_redis/core.py", line 356, in _brpop_with_clean async with self.connection(index) as connection:File "/usr/local/lib/python3.6/site-packages/channels_redis/core.py", line 884, in __aenter__ self.conn = await self.pool.pop()File "/usr/local/lib/python3.6/site-packages/channels_redis/core.py", line 80, in pop conn = await aioredis.create_redis(**self.host, loop=loop)File "/usr/local/lib/python3.6/site-packages/aioredis/commands/__init__.py", line 175, in create_redis loop=loop)File "/usr/local/lib/python3.6/site-packages/aioredis/connection.py", line 113, in create_connection timeout)File "/usr/local/lib/python3.6/asyncio/tasks.py", line 339, in wait_for return (yield from fut)File "/usr/local/lib/python3.6/site-packages/aioredis/stream.py", line 24, in open_connection lambda: protocol, host, port, **kwds)File "/usr/local/lib/python3.6/asyncio/base_events.py", line 754, in create_connection infos = f1.result()File "/usr/local/lib/python3.6/concurrent/futures/thread.py", line 56, in run result = self.fn(*self.args, **self.kwargs)File "/usr/local/lib/python3.6/socket.py", line 745, in getaddrinfo for res in _socket.getaddrinfo(host, port, family, type, proto, flags):socket.gaierror: [Errno -2] Name or service not known
this is a part of my settings.py in django:
ASGI_APPLICATION = "myapp.asgi.application"CHANNEL_LAYERS = {'default': {'BACKEND': 'channels_redis.core.RedisChannelLayer','CONFIG': {"hosts": [('redis', 6379)], }, },}ALLOWED_HOSTS = ['*']
Updated: frontend app tries to connect to websocket with this url:wss://myapp.com/backend/ws/chat/12
I really don't know what to do next. Could you please help me?