Django Channels + Nginx + Daphne в Docker
уже 2 дня пытаюсь решить проблему, испробовал множество вариантов, перечитал кучу статей и форумов, пока тупик. В своем Django приложении я подключил веб сокеты с помощью библиотеки Django Channels для реализации чата. Фронтенд на Vue js. Локально все работало хорошо, чатик моментально отображал сообщения, но как только я завернул все это дело в Docker, клиенская сторона перестала подключаться к веб сокетам. Мне кажется, либо я с настройками nginx что то сделал не так, либо в Docker. Я не devops и в этом не силен, поэтому прошу помощи!!
Dockerfile
###########
# BUILDER #
###########
# pull official base image
FROM python:3.9.2 as builder
ENV PYTHONDONTWRITEBYCECODE 1
ENV PYTHONUNBUFFERED 1
# set work directory
WORKDIR /usr/src/app
# install psycopg2 dependencies
RUN apt-get update -y && apt-get -y install postgresql gcc python3-dev musl-dev
# lint
RUN pip install --upgrade pip
COPY . .
# install dependencies
COPY ./requirements.txt /usr/src/requirements.txt
RUN pip wheel --no-cache-dir --no-deps --wheel-dir /usr/src/app/wheels -r requirements.txt
#########
# FINAL #
#########
# pull official base image
FROM python:3.9.2
# create directory for the app user
RUN mkdir -p /home/app
# create the app user
RUN groupadd app
RUN useradd -m -g app app -p password
RUN usermod -aG app app
# create the appropriate directories
ENV HOME=/home/app
ENV APP_HOME=/home/app/web
RUN mkdir $APP_HOME
WORKDIR $APP_HOME
# install dependencies
RUN apt-get update \
&& apt-get install netcat -y
COPY --from=builder /usr/src/app/wheels /wheels
COPY --from=builder /usr/src/app/requirements.txt .
RUN /usr/local/bin/python -m pip install --upgrade pip
RUN pip install --no-cache /wheels/*
# copy entrypoint-prod.sh
COPY ./entrypoint.sh $APP_HOME
# copy project
COPY . $APP_HOME
# chown all the files to the app user
RUN chown -R app:app $APP_HOME
# change to the app user
USER app
# run entrypoint.prod.sh
ENTRYPOINT ["/home/app/web/entrypoint.sh"]
entrypoint.sh
#!/bin/sh
if [ "$DATABASE" = "postgres" ]
then
echo "Waiting for postgres..."
while ! nc -z $DB_HOST $DB_PORT; do
sleep 0.1
done
echo "Postgres started"
fi
exec "$@"
Docker-compose.yml
version: '3.7'
services:
web:
build:
context: ./
dockerfile: Dockerfile
command: gunicorn school.wsgi:application --bind 0.0.0.0:8000
volumes:
- static_volume:/home/app/web/static
- media_volume:/home/app/web/media
expose:
- 8000
depends_on:
- db
- redis
env_file:
- ./.env.prod
links:
- redis
db:
image: postgres:10.1-alpine
volumes:
- postgres_data:/var/lib/postgresql/data/
env_file:
- ./.env.db
vue:
build:
context: ./scool-ui
dockerfile: Dockerfile
volumes:
- vue_dist:/app/dist
depends_on:
- web
redis:
image: "redis:alpine"
restart: always
ports:
- "6379:6379"
volumes:
- redis_data:/data
daphne:
image: daphne
build: .
working_dir: /home/app/web
command: bash -c ""
ports:
- "8001:8001"
environment:
- REDIS_HOST=redis
depends_on:
- redis
links:
- redis
nginx:
build: ./nginx
ports:
- 80:80
volumes:
- static_volume:/home/app/web/static
- media_volume:/home/app/web/media
- vue_dist:/app/dist
depends_on:
- web
- vue
- daphne
links:
- daphne
volumes:
postgres_data:
static_volume:
media_volume:
vue_dist:
redis_data:
nginx/Dockerfile
FROM nginx:1.21.3-alpine
RUN rm /etc/nginx/conf.d/default.conf
COPY nginx.conf /etc/nginx/conf.d
nginx.conf
upstream school {
server web:8000;
}
server {
listen 80;
location / {
root /app/dist;
#index index.html index.htm;
try_files $uri $uri/ /index.html;
}
location /api/ {
proxy_pass http://school;
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
proxy_set_header Host $host;
proxy_redirect off;
}
location /ws/ {
proxy_pass http://0.0.0.0:8001;;
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;
}
location /static/ {
root /home/app/web;
}
location /media/ {
root /home/app/web;
}
}
Что пробовал: Пытался запускать daphne из entrypoint.sh и пытался запустить daphne вместо gunicorn в web в docker-compose, в настройках nginx пробовал указывать 8000 порт
Так же на всякий случай скину метод конекта к сокету с клиенской стороны:
connect() {
this.chatSocket = new WebSocket(
'ws://127.0.0.1/ws/chat/' + String(this.id) + '/'
);
this.chatSocket.onopen = () => {
this.status = "connected";
};
this.chatSocket.onmessage = ({data}) => {
this.responseData.push(JSON.parse(data))
}
}