My django app works fine on local machine as well as on Heroku, however I'm having troubles to deploy it do Digital Ocean Ubuntu 16.04 droplet. Followed this tutorial, app has started but websockets didn't work.
By running in terminal virtual environment: daphne -b 0.0.0.0 -p 8000 slist.asgi:channel_layer
and in second terminal window:
./manage.py runworker
The app works but only on port 8000. I can't access it on mydomain.com but only on mydomain.com:8000.
When I close terminal windows the site cannot be accessed.
What and how needs to be set for the site to run without my terminal windows and without the ':8000'?
My gunicorn.service file:
[Unit]
Description=gunicorn daemon
After=network.target
[Service]
User=kuba1
Group=www-data
WorkingDirectory=/home/kuba1/slistproject
ExecStart=/home/kuba1/slistproject/slistvenv/bin/gunicorn --workers 3 --bind unix:/home/kuba1/slistproject/slistvenv/src/slist.sock slist.wsgi:application
[Install]
WantedBy=multi-user.target
my Nginx settings:
server {
listen 80;
server_name server_name fortests.ovh;
client_max_body_size 20M;
location /static/ {
root /home/kuba1/slistproject/slistvenv/src;
}
location / {
proxy_pass http://unix:/home/kuba1/slistproject/slistvenv/src/slist.sock;
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;
}
}
You have to proxy_pass the domain to that port 8000:
location / {
proxy_pass_header Server;
proxy_set_header X-Forwarded-Proto https;
proxy_set_header Host $http_host;
proxy_redirect off;
proxy_set_header X-Real-IP $remote_addr;
proxy_set_header X-Scheme $scheme;
proxy_connect_timeout 10;
proxy_read_timeout 10;
proxy_pass http://localhost:8001/;
}
It should be:
proxy_set_header Connection "Upgrade";
Working config for me:
upstream websocket {
server unix:/path/to/daphne.sock fail_timeout=20;
}
location /url/socket/ {
try_files $uri #proxy_to_channel_app;
}
location #proxy_to_channel_app {
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
proxy_set_header X-Real-IP $remote_addr;
# enable this if and only if you use HTTPS
proxy_set_header X-Forwarded-Proto https;
proxy_set_header Host $http_host;
# web socket setup
proxy_set_header Upgrade $http_upgrade;
proxy_set_header Connection 'Upgrade';
# we don't want nginx trying to do something clever with
# redirects, we set the Host: header above already.
proxy_redirect off;
proxy_pass http://websocket;
}
Daphne command:
daphne -u run/daphne.sock project.asgi:channel_layer
Related
I am currently trying to set up a simple ip website, miip.co with a api with the purpose of just showing your your ip address when you open the site.
When I test https://ready.chair6.net/?url=https://miip.co it shows yes to all but ipv4 literals with only a warning.
My nginx location looks like so
location / {
proxy_pass http://unix:/home/www/miip/app.sock;
proxy_set_header Host $http_host;
proxy_set_header X-Real-IP $remote_addr;
proxy_set_header X-Scheme $scheme;
proxy_set_header REMOTE_ADDR $remote_addr;
proxy_read_timeout 1000; # this
}
my gunicorn command looks like so
command = /home/www/miip/venv/bin/gunicorn --workers 3 --bind unix:/home/www/miip/app.sock app.wsgi:application
And my django ip function looks like so
def get_ip(request):
x_forwarded_for = request.META.get('HTTP_X_FORWARDED_FOR')
if x_forwarded_for:
ip = x_forwarded_for.split(',')[0]
else:
ip = request.META.get('REMOTE_ADDR')
return ip
Yet despite this, it always return a ipv4. My system is also on ipv6. I think it has to do with nginx proxy pass but unsure.
Okay, got it.
In nginx proxy_pass you have to pass the ipv6 and in gunicorn you have to double bind https://djangodeployment.readthedocs.io/en/latest/06-gunicorn.html
in nginx,
location / {
proxy_set_header X-Real-IP $remote_addr;
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
proxy_set_header Host $host;
proxy_set_header X-NginX-Proxy false;
real_ip_header X-Real-IP;
proxy_pass http://[::1]:8000;
proxy_redirect off;
}
and in gunicorn
command = /home/www/miip/venv/bin/gunicorn --workers 3 --bind unix:/home/www/miip/app.sock --bind [::1]:8000 app.wsgi:application
I want to deploy django as backend server with nginx.
I use daphne as asgi server due to django channel
location /api {
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-Proto $scheme;
proxy_pass http://127.0.0.1:10131;
}
as you can see, http://127.0.0.1:10131 is django which should be connected to http://my_domain.com/api
but django can't recognize requested uri.
surely, I set FORCE_SCRIPT_NAME to /api
What should I do further?
please help.
First check whether your daphne service is running on server or not & then try this
server {
listen 80; # can change to 10131
server_name http://my_domain.com;
location /api {
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-Proto $scheme;
proxy_pass http://127.0.0.1:10131;
}
}
You can change listen port if you want your api accessible to specific port eg. 10131
If you're facing any issues then try to check your daphne logs like this
sudo journalctl -u daphne
and to check your api is running or not run this command
curl http://127.0.0.1:10131/api
you may need to install curl run this to install it
sudo apt install curl
I'm trying for the first time to deploy my Django application on a server but so far I wasn't able to get rid of port in my URL. Right now I'm using Gunicorn with Nginx with the following configuration.
Nginx /etc/nginx/sites-enabled/site.conf
server {
listen 8000;
server_name example.com;
location = /favicon.ico {access_log off;log_not_found off;}
location /static/ {
root /home/webapp/um;
}
location /media/ {
root /home/webapp/um;
}
location / {
include proxy_params;
proxy_pass http://unix:/home/webapp/um/um.sock;
}
}
/etc/nginx/proxy_params
proxy_set_header Host $http_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-Proto $scheme;
Gunicorn /etc/systemd/system/gunicorn.service
Description=gunicorn service
After=network.target
[Service]
User=root
Group=www-data
WorkingDirectory=/home/webapp/um/
ExecStart=/root/um/bin/gunicorn --access-logfile - --workers 3 --bind unix:/home/webapp/um/um.sock um.wsgi:application
[Install]
WantedBy=multi-user.target
Gunicorn binding
gunicorn --bind 0.0.0.0:8000 um.wsgi:application
Changing port 8000 with port 80 in /etc/nginx/sites-enabled/site.conf gives me a 404 on nginx. Using port 8000 I'm able to see the site using http://example.com:8000/myapp but I'm aiming at using http://example.com/myapp as my address.
As a side note, the VPS I'm installing the app on came with Plesk already installed with which I'm also not familiar with. I don't know if Plesk might be interferring in catching traffic from port 80.
Thanks in advance
You just need to listen this server on port 80 instead of 8000
save gunicorn as described
server {
listen 80;
server_name 52.14.64.58 example.com www.example.com;
location = /favicon.ico {access_log off;log_not_found off;}
location /static/ {
root /home/webapp/um;
}
location /media/ {
root /home/webapp/um;
}
location / {
include proxy_params;
proxy_pass http://unix:/home/webapp/um/um.sock;
}
}
52.14.64.58 => is ipv4 of your virtual machine, it could be anything in your case.
Now time to make changes in our django settings
ALLOWED_HOSTS = ['IP_ADDRESS', 'example.com', 'www.example.com']
Now check nginx status then restart gunicorn and nginx . I hope it would work for you.
sudo nginx -t
sudo systemctl restart nginx
sudo systemctl restart gunicorn
Now setup your domain by it's dns settings.
After a bit of struggling, I found the solution. Turns out my config was correct, but there was an nginx config file automatically written by plesk that was catching requests on port 80. The content of such file is
server {
listen 111.111.111.111:80;
location ^~ /plesk-site-preview/ {
proxy_pass http://127.0.0.1:8880;
proxy_set_header Host plesk-site-preview.local;
proxy_set_header X-Real-IP $remote_addr;
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
proxy_cookie_domain plesk-site-preview.local $host;
access_log off;
}
location / {
proxy_pass http://111.111.111.111:7080;
proxy_set_header Host $host;
proxy_set_header X-Real-IP $remote_addr;
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
}
}
server {
listen 111.111.111.111:443 ssl;
ssl_certificate /opt/psa/var/certificates/certWpPLaPv;
ssl_certificate_key /opt/psa/var/certificates/certWpPLaPv;
location ^~ /plesk-site-preview/ {
proxy_pass http://127.0.0.1:8880;
proxy_set_header Host plesk-site-preview.local;
proxy_set_header X-Real-IP $remote_addr;
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
proxy_cookie_domain plesk-site-preview.local $host;
access_log off;
}
location / {
proxy_pass https://111.111.111.111:7081;
proxy_set_header Host $host;
proxy_set_header X-Real-IP $remote_addr;
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
}
Once I removed that file from inclusion in nginx.conf everything started working. As a suggestion for whoever is facing a similar situation, I would recommend to check what Nginx is processing using the following command
nginx -T
I am currently deploying a django project using channel 2.x with uwgsi for http requests and daphne for background tasks.
Daphne by itself is running correctly as well as uwgsi.
Configuration for both is the following:
location /stream {
# daphne server running on port 8001 so we set a proxy to that url
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;
}
# These requests are handled by uwsgi
location / {
include uwsgi_params;
uwsgi_pass unix:/run/uwsgi/app/project/socket;
proxy_set_header Host $host;
proxy_set_header X-Real-IP $remote_addr;
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
# Make the following two variables accessible to the application:
uwsgi_param SSL_CLIENT_VERIFY $ssl_client_verify;
uwsgi_param SSL_CLIENT_RAW_CERT $ssl_client_raw_cert;
}
All background workers are preceded by /stream. All endpoints are protected. When login in and accessing endpoints such as /api/v1/resource it correctly returns the data but when triggering tasks via /stream I get permission denied (403). Debugging this behavior I have come to the conclusion that sessions are not persisted among Daphne and Uwsgi.
How can I achieve sessions to be shared between them?
TLDR: How to share cookies between subdomains for a backend application sever that I cannot "configure" using nginx (1.8.x) as a proxy - some magical combination of proxy_*?
A tornado web server is running on "127.0.0.1:9999/ipython" that I cannot configure (it's running as part of an ipython notebook server). I'm using nginx to proxy from "www.mysite.com" to 127.0.0.1:9999 successfully (http traffic at least).
However, part of the backend application requires Websockets. Because I am using CloudFlare, I have to use a separate domain for Websockets ("Websockets are currently only available for Enterprise customers ... All other customers ... should create a subdomain for Websockets in their CloudFlare DNS and disable the CloudFlare proxy"). I'm using "ws.mysite.com".
When a user logs in at "https :// www.mysite.com", a cookie is set by the tornado web server for "www.mysite.com" (I can't seem to configure it, otherwise I would just set it to ".mysite.com"). When the websocket part of the application kicks in, it sends a request to "wss :// ws.mysite.com", but fails to authenticate because the cookie is set for a different domain("www.mysite.com").
Is it possible for nginx to "spoof" the domain so the tornado webserver registers it for ".mysite.com"? proxy_cookie_domain doesn't seem to work as I'd expect... Should I hard code "proxy_set_header Host"?
I was thinking a nginx conf similar to....
upstream ipython_server {
server 127.0.0.1:8888;
}
server {
listen 443;
server_name www.mysite.com;
ssl_certificate cert.crt;
ssl_certificate_key cert.key;
ssl on;
# **** THIS DOESN'T WORK ??? ****
proxy_cookie_domain www.mysite.com .mysite.com;
location /ipython/static {
proxy_pass https://ipython_server$request_uri;
proxy_set_header Host $host;
proxy_set_header X-Real-IP $remote_addr;
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
}
location /ipython/api/sessions {
proxy_pass https://ipython_server$request_uri;
proxy_set_header Host $host;
proxy_set_header Origin "";
proxy_set_header X-Real-IP $remote_addr;
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
}
location /ipython {
proxy_pass https://ipython_server$request_uri;
proxy_set_header Host $host;
proxy_set_header X-Real-IP $remote_addr;
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
}
location / {
try_files $uri $uri/ =404;
}
}
server {
listen 443;
server_name ws.azampagl.com;
ssl_certificate cert.crt;
ssl_certificate_key cert.key;
ssl on;
# **** THIS DOESN'T WORK ??? ****
proxy_cookie_domain ws.mysite.com .mysite.com;
# This is the websocket location
location /ipython/api/kernels/ {
proxy_pass https://ipython_server$request_uri;
proxy_redirect off;
proxy_http_version 1.1;
chunked_transfer_encoding off;
proxy_buffering off;
proxy_read_timeout 86400;
proxy_set_header Host $host;
proxy_set_header Origin "";
proxy_set_header Upgrade websocket;
proxy_set_header Connection "upgrade";
proxy_set_header X-Real-IP $remote_addr;
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
proxy_set_header X-NginX-Proxy true;
proxy_set_header X-Forwarded-Proto $scheme;
}
}
I've been looking in the nginx lua module? It looks like you can set cookie domains, but it looks hackish...
Thanks greatly in advance for your assistance!
(Side note: I do technically have access to the tornado configuration, but there is zero documentation on how to set the "cookie domain" for the server. i.e.
c.NotebookApp.tornado_settings = {'cookie_domain????':'.mysite.com'}
)