Раскрытие порта websockets через одно и то же место dokku

У меня есть проект django, где я запускаю свои web и django каналы как отдельные procs в Procfile:

web: gunicorn django_project.wsgi:application
socket: daphne django_project.asgi:application

И выставил ws/wss, используя dokku proxy:ports-add web ws:80:8000 wss:443:8000 (web - это название моего приложения dokku):

=====> web proxy information
       Proxy enabled:                 true
       Proxy port map:                http:80:5000 https:443:5000 ws:80:8000 wss:443:8000
       Proxy type:                    nginx

Я выставил контейнерный порт 8000, потому что по умолчанию daphne работает на порту 8000:

app[socket.1]: Starting server at tcp:port=8000:interface=127.0.0.1
app[socket.1]: Configuring endpoint tcp:port=8000:interface=127.0.0.1
app[socket.1]: Listening on TCP address 127.0.0.1:8000

Но я не могу подключиться к своему websocket в браузере. Я получаю ошибку Not Found: /ws/mywebsocket для конечной точки моего websocket, а функция socket.onclose немедленно вызывается с ошибкой code: 1006.

Я думаю, что мне нужно создать пользовательский nginx.sigil для dokku для перенаправления на websocket, если url содержит /ws/, но многие ответы кажутся устаревшими и не работают.

Система отображения портов в Dokku передает отображение портов отдельным реализациям прокси, которые должны обрабатывать схему. Встроенный прокси-плагин nginx поддерживает только сопоставления портов http и http. Кроме того, он не имеет функциональности для отправки соединений с заданного отображения портов на заданный тип процесса.

Плагин nginx proxy открывает пользовательскую переменную .DOKKU_APP_${PROCESS_TYPE}_LISTENERS для каждого PROCESS_TYPE в вашем Procfile, которую можно использовать в сочетании с пользовательской переменной nginx.conf.sigil для:

  • создайте пользовательский блок восходящего потока
  • добавьте блок местоположения, указывающий на этот блок восходящего потока

Вы можете создать блок восходящего потока для вашего конкретного случая использования следующим образом:

# the variable maps to the Procfile entry. Replace `SOCKET` as appropriate for your process type name.
{{ if $.DOKKU_APP_SOCKET_LISTENERS }}
# this assumes the socket listening port is 8000
upstream {{ $.APP }}-socket-8000 {
{{ range $listeners := $.DOKKU_APP_SOCKET_LISTENERS | split " " }}
{{ $listener_list := $listeners | split ":" }}
{{ $listener_ip := index $listener_list 0 }}
  server {{ $listener_ip }}:8000;{{ end }}
}
{{ end }}

Блок расположения будет выглядеть следующим образом:

location /ws/ {
  proxy_pass http://{{ .APP }}-socket-8000;
  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;
}
Вернуться на верх