Hi everyone,
I am developing a website using Django, and I have successfully embedded bokeh to visualise data. I am now trying to move the website to production, using nginx, gunicorn and daphne to run the wsgi and asgi application. The website works, however the web-sockets are not reachable.
Here the nginx configuration file:
upstream M2i2 {
server unix:/run/gunicorn/gunicorn.sock fail_timeout=0;
}
upstream channels-backend {
server Ip_addres:port;
}
server {
listen 443 ssl;
server_name domain_name;
location /favicon.ico { access_log off;
log_not_found off;
}
ssl_certificate ####.cer;
ssl_certificate_key ####.key;
location /static/ {
root path_to_static_folder;
}
location / {
proxy_pass http://M2i2;
proxy_headers_hash_max_size 512;
proxy_headers_hash_bucket_size 128;
proxy_connect_timeout 3600;
proxy_send_timeout 3600;
proxy_read_timeout 3600;
proxy_buffering off;
client_body_temp_path path_to_temporary_folder;
}
client_max_body_size 200G;
client_body_timeout 3600;
location /ws/ {
proxy_pass http://channels-backend;
proxy_send_timeout 3600;
proxy_read_timeout 3600;
proxy_http_version 1.1;
proxy_set_header Upgrade $http_upgrade;
proxy_set_header Connection "upgrade";
proxy_buffering off;
proxy_set_header Host $http_host;
#proxy_redirect off;
proxy_set_header X-Urls-Scheme $scheme;
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;
proxy_set_header X-Forwarded-Proto $scheme;
proxy_set_header SSL_PROTOCOL $ssl_protocol;
}
location /media/ {
root path_to_media/;
}
}
I am using a unix:socket to run gunicorn, but I have read that I cannot using that for the websocket so daphne run on a port.
I have added this line
<meta http-equiv="Content-Security-Policy" content="upgrade-insecure-requests">
in my html to avoid Mixed contents
I have setup the routing as follow:
from channels.auth import AuthMiddlewareStack
from channels.routing import ProtocolTypeRouter, URLRouter
from django.apps import apps
from .settings import bokeh_app_module
bokeh_app_config = apps.get_app_config(bokeh_app_module)
#django_asgi_app = get_asgi_application()
application = ProtocolTypeRouter({
'websocket': AuthMiddlewareStack(URLRouter(bokeh_app_config.routes.get_websocket_urlpatterns())),
'http': AuthMiddlewareStack(URLRouter(bokeh_app_config.routes.get_http_urlpatterns())),
})
and add the bokeh app in urls.py file
bokeh_apps = [
autoload('history/', history_app.app),
]
I am using server_document() function to return the URL of Bokeh server application. for example:
def dashboard(request:HttpRequest)-> HttpResponse:
user = request.user
userID=user.id
absolute=request.build_absolute_uri('/')+'history/'
script2 = server_document(absolute,arguments={"userID":str(user.id) })
return render(request, 'home/dashboard.html',{'script':script2})
and the script2 result
<script id="1002">
(function() {
const xhr = new XMLHttpRequest()
xhr.responseType = 'blob';
xhr.open('GET', "http://domain_name/history/autoload.js?bokeh-autoload-element=1002&bokeh-app-path=/history&bokeh-absolute-url=http://domain_name/history&userID=1", true);
xhr.onload = function (event) {
const script = document.createElement('script');
const src = URL.createObjectURL(event.target.response);
script.src = src;
document.body.appendChild(script);
};
xhr.send();
})();
</script>
The page upload but not the websocket and I get this error
` GET https://domain_name/history/autoload.js?bokeh-autoload-element=1002&bokeh-app-path=/history&bokeh-absolute-url=http://domain_name/history&userID=1 404 (Not Found)`
I have try to use a different urls in server_document() as follow
absolute=http://Ip_addres:port/+'history/'
script2 = server_document(absolute,arguments={"userID":str(user.id) })
then the error is
GET https://Ip_address:port/history/autoload.js?bokeh-autoload-element=1002&bokeh-app-path=/history&bokeh-absolute-url=http://Ip_address:port/history&userID=1 net::ERR_CONNECTION_TIMED_OUT
I am bit stuck now, I am not sure what to do
Lucia