I'm deploying my django app with nginx-uwsgi
I wanna add Varnish to this stack.
As I know Varnish can cache only ip and port.
But my stack configured this way:
location / {
uwsgi_pass unix://home/mechanism/SERVER/run/MechanisM.sock;
include uwsgi_params;
}
so my nginx works with uwsgi's socket. not ip and port.
but Varnish needs ip and port. like this:
backend default {
.host = "127.0.0.1";
.port = "8080";
}
should I change uwsgi to run with ip and port? or there's some way to configure Varnish to work with uwsgi's sock? or how to know ip and port of this socket?
btw, I'm starting uwsgi with this command:
exec /usr/sbin/uwsgi --socket /home/mechanism/SERVER/run/MechanisM.sock --chmod-socket --module wsgi_app --pythonpath /home/mechanism/SERVER/django-projects/MechanisM/uwsgi -p 12 -t 15
should I use -s 127.0.0.1:3031 instead of --socket /home/mechanism/SERVER/run/MechanisM.sock ??
Varnish will cache date coming from nginx, not from uWSGI.
Put the nginx address in varnish not the uWSGI one
Related
I'm trying to deploy a Django app in a Ubuntu Server 18.04 using Nginx and Gunicorn. Every tool seems to work properly, at least, from logs and status points of view.
The point is that if I log into my server using SSH and try to use curl, gunicorn is able to see the request and handle it. However, if I write directly my IP, I get simply the typical Welcome to nginx home page and the request is completely invisible to gunicorn, so it seems nginx is unable to locate and pass the request to the gunicorn socket.
I'm using nginx 1.14.0, Django 2.2.1, Python 3.6.7, gunicorn 19.9.0 and PostgreSQL 10.8.
This is my nginx config
server {
listen 80;
server_name localhost;
location /favicon.ico { access_log off; log_not_found off; }
location /static/ {
alias /home/django/myproject/myproject;
}
location / {
include proxy_params;
proxy_pass http://unix:/run/gunicorn.sock;
}
}
And these are my gunicorn.sock
[Unit]
Description=gunicorn socket
[Socket]
ListenStream=/run/gunicorn.sock
[Install]
WantedBy=sockets.target
and gunicorn.service
[Unit]
Description=gunicorn daemon
Requires=gunicorn.socket
After=network.target
[Service]
User=django
Group=www-data
WorkingDirectory=/home/django/myproject/myproject
ExecStart=/home/django/myproject/myproject/myproject/bin/gunicorn \
--access-logfile - \
--workers 3 \
--bind unix:/run/gunicorn.sock \
MyProject.wsgi:application
[Install]
WantedBy=multi-user.target
I've been following this guide (https://www.digitalocean.com/community/tutorials/how-to-set-up-django-with-postgres-nginx-and-gunicorn-on-ubuntu-18-04), where most of all has worked as expected, but with the difference that my project is not a completely new one as in the tutorial, but cloned from my git repo (however, it's tested and the code works properly)
I was expecting the Django admin to be accessible from my browser already with this config, but it's not. I try to access my IP from my browser and I get Welcome to nginx but also 404 if I visit /admin. In addition, the gunicorn logs shows no requests.
In the other hand, if I log through SSH into my server and I execute curl --unix-socket /run/gunicorn.sock localhost, I can see in the gunicorn logs the request done by curl.
Any help is welcome.. I've been here for hours and I'm not able to get even 1 request from outside the server.
PD: it's also not something related to the ports in the server, since when I access the root of my IP, I receive the nginx answer. It just seems like Nginx has no config at all.
in your nginx config, you should use your proper server_name instead of localhost
server_name mydomain.com;
If not, you will fall back to the default nginx server, which returns the "welcome to nginx" message. You can change which virtual server is default by changing the order of servers, removing the nginx default, or using the default_server parameter. You can also listen to multiple server names.
listen 80 default_server;
server_name mydomain.com localhost;
If the Host header field does not match a server name, NGINX Plus routes the request to the default server for the port on which the request arrived. The default server is the first one listed in the nginx.conf file, unless you include the default_server parameter to the listen directive to explicitly designate a server as the default.
https://docs.nginx.com/nginx/admin-guide/web-server/web-server/#setting-up-virtual-servers
Remember that you have to reload the nginx config after making changes. sudo nginx -s reload for example.
Finally, I've got it working properly. You were right about the config of nginx, although my real problem was not to delete/modify default config file for nginx in sites_enabled folder. Thus, when I was setting listen 80 default_server I got the following error
[emerg] 10619#0: a duplicate default server for 0.0.0.0:80 in
/etc/nginx/sites-enabled/mysite.com:4
Anyway, I had a problem with the static files which I still not knowing why it works like that. I needed to set DEBUG = True to be able to see static files of the admin module.
I'll keep on investigating the proper way of serving static files in production for the admin panel.
Thank you so much for the help!
I'm trying to deploy my Django Project through different application server : Apache2, Nginx/gunicorn, ...
It works fine with Apache2 or Nginx, but I would like to dissociate these application server with my Django Projet. I would like to get an environment like this :
Server 1 (172.30.10.92) : Django Project & wsgi
Server 2 (172.30.10.93) : Nginx/gunicorn
Why ? Because later I will have some Django applications, but I would like to use just one application server.
I think I'm making a mistake with my configuration files syntax.
I have in /etc/nginx/sites-available/DatasystemsCORE.conf :
server {
listen 8000;
server_name 172.30.10.92;
location = /favicon.ico { access_log off; log_not_found off; }
location /static/ {
root http://172.30.10.92:/var/www/html/;
}
location / {
include proxy_params;
proxy_pass http://172.30.10.92/unix:/var/www/html/DatasystemsCORE/dscore.sock;
}
}
server_name : Is it IP adress from Django server or nginx server ? I think it's the first one but I'm not sure.
proxy_pass : I think there is an issue in my path
Then, I'm executing this command :
gunicorn --daemon --workers 3 --bind 172.30.10.92/unix:/var/www/html/DatasystemsCORE/dscore.sock 172.30.10.92:/var/www/html/DatasystemsCORE/DatasystemsCORE.wsgi
One more time, I thing there is a syntax problem because I'm getting 502 Bad Request
How I can add IP address from a distant Django server there ?
Thank you !
I found How to solve my issue and I made a tutorial (based on my case) in order to help everyone who would like to make the same thing.
My file is there : Download tutorial file
But this is the same tutorial written in English.
My Django IP server : 172.30.10.92
My Nginx IP server : 172.30.10.93
1- Install and Configure wsgi (located on Django server)
WSGI is a file created with your Django project.
The file is located in /path/to/your/project/Myproject/wsgi.py
We have to edit this file like this :
import os
from django.core.wsgi import get_wsgi_application
import sys sys.path.append('/var/www/html/Myproject')
os.environ.setdefault("DJANGO_SETTINGS_MODULE", "Myproject.settings")
application = get_wsgi_application()
2- Install and Configure gunicorn/supervisor (located on Django server)
In order to install gunicorn/supervisor, you have to execute in your shell :
pip install gunicorn
pip install supervisor
Then, you have to create a new file in /etc/supervisor/conf.d/Myproject.conf which looks like this :
[program:Myproject]
command = /home/valentin/.virtualenvs/MyprojectEnv/bin/gunicorn Myproject.wsgi:application --name "Myproject" --workers=4 --bind=0.0.0.0:8080 -- user="valentin" --group="valentin" ; Command to start app
user = username #You have to replace by your username
stdout_logfile = /var/log/supervisor/supervisor.log
redirect_stderr = true
log
environment=LANG=fr_FR.UTF-8,LC_ALL=fr_FR.UTF-8
I specified port 8080 which is the communication port between my application server and my web server.
3- Edit hosts file on nginx server (located on nginx server)
You have to edit your hosts file located to /etc/hosts and add a new entry to your Django server :
127.0.0.1 localhost
127.0.1.1 valentin
172.30.10.92 Myproject
# The following lines are desirable for IPv6 capable hosts ::1 localhost ip6-localhost ip6-loopback
ff02::1 ip6-allnodes
ff02::2 ip6-allrouters
4- New config file in nginx repository (located on nginx server)
This new file should be placed in /etc/nginx/sites-available/Myproject.conf
server {
listen 8080;
server_name Myproject;
root /var/www/html/Myproject/;
location /static/ {
root /var/www/html/;
}
location / {
include proxy_params;
proxy_pass http://172.30.10.92:8080;
}
}
The IP address corresponds to my Django server address. I specified the listen port (8080), the path to my Django project & static directory.
Then, you have to create a symbolic link to sites-enabled.
After ths operation, restart nginx service :
sudo service nginx restart
5- Allow nginx IP address in Django (located on Django server)
You have to edit your settings.py file in order to allow nginx IP address in ALLOWED_HOSTS :
ALLOWED_HOSTS = ['localhost', '172.30.10.93', '127.0.0.1', '[::1]']
6- Finally execute gunicorn (located on Django server)
Finally, you have to start gunicorn. You should be inside your Django root project and execute :
gunicorn Myproject.wsgi:application --bind 172.30.10.92:8080
Now, in your browser, try to connect to your nginx server with the port :
http://172.30.10.93:8080
It works !
PS : This tutorial works for me, if it doesn't work for you, maybe I missed something, or maybe you didn't make exactly like me ;)
What you're trying to do doesn't make any sense. You can certainly use a single nginx on a separate server, but gunicorn is the application server and belongs with the application.
There is no "Django server" so your first question is irrelevant. gunicorn will need to serve on a port, not a socket, and the nginx proxy_pass will point to that port.
trying to run django app "mysite" through uwsgi with nginx on Ubuntu 16.04, but when I start uwsgi and check in my browser, it just hangs.
i set django upstream socket to on port 8002 and nginx to listen on 8003. In the browser i visit 192.168.0.17:8003 prior to running uwsgi and it throws 502 which is expected, so I start uwsgi with
uwsgi --http :8002 --module mysite.wsgi --logto /tmp/uwsgi.log --master
and 8003 now hangs when I reload in the browser. I looked through /var/log/nginx/error.log but it's blank (so is access.log).
Here is nginx config, which is symlinked to /etc/nginx/sites-enabled:
sudo nano /etc/nginx/sites-available/mysite_nginx.conf
# mysite_nginx.conf
# the upstream component nginx needs to connect to
upstream django {
# server unix:///path/to/your/mysite/mysite.sock; # for a file socket
server 127.0.0.1:8002; # for a web port socket (we'll use this first)
}
# configuration of the server
server {
# the port your site will be served on
listen 8003;
# the domain name it will serve for
server_name 192.168.0.17; # substitute your machine's IP address or FQDN
charset utf-8;
# max upload size
client_max_body_size 75M; # adjust to taste
# Django media
location /media {
alias /home/myusername/uwsgi-tutorial/mysite/media; # your Django project's media files - amend as required
}
location /static {
alias /home/myusername/uwsgi-tutorial/mysite/static; # your Django project's static files - amend as required
}
# Finally, send all non-media requests to the Django server.
location / {
uwsgi_pass django;
include /home/myusername/uwsgi-tutorial/mysite/uwsgi_params; # the uwsgi_params file you installed
}
}
I know that Django is running because in my app's settings.py I have ALLOWED_HOSTS = ['192.168.0.17','localhost','127.0.0.1'] and when I visit port 8002 in the browser I get the django "Congratulations!" page. And when I remove 192.168.0.17 from ALLOWED_HOSTS, django still runs on that machine from localhost or 127.0.0.1, so this seems that it must be something to do with how ngnix and uwsgi are talking to each other.
Any ideas??
It turns out systemd does not like lines in config files to be too long. I removed a couple long comments in /etc/systemd/system/uwsgi.service, restarted uwgsi service and all is well.
I found this out by running sudo journalctl -u uwsgi and finding the following error:
[/etc/systemd/system/uwsgi.service:5] Unbalanced quoting, ignoring: "/bin/bash -c 'mkdir -p /run/uwsgi; chown myusername:myusern
In researching Unbalanced quoting, found this git issue regarding maximum file line length.
I encounterd an error when bound gunicorn listen address to my nginx server,here is the thing:
1.gunicorn_wsgi.py
import multiprocessing
bind="192.168.239.145:8080"(my nginx server ip address)
workers = multiprocessing.cpu_count() 2 + 1
2.nginx.conf
http{
upstream realservers{
server 192.168.239.146:8080;(my django and gunicorn address)
}
servr{
listen 80;
server_name example.com
location / {
proxy_pass http://realservers
}
}
}
when i ran gunicorn -c gunicorn-wsgi.py myproject.wsgi,error occur:
[2015-03-30 04:56:05 -0700] [38656] [INFO] Starting gunicorn 19.3.0
[2015-03-30 04:56:05 -0700] [38656] [ERROR] Invalid address: ('192.168.239.145', 8080)
I noticed that gunicorn has mentioned that if you are running nginx on a different host than gunicorn you need to tell gunicorn to trust the the x-forward-* headers sent by nginx.
If you are running Nginx on a different host than Gunicorn you need to
tell Gunicorn to trust the X-Forwarded-* headers sent by Nginx. By
default, Gunicorn will only trust these headers if the connection
comes from localhost. This is to prevent a malicious client from
forging these headers:
gunicorn -w 3 --forwarded-allow-ips="10.170.3.217,10.170.3.220" test:app
I followed what it said ,but still same error. And I change the address to 127.0.0.1 and 0.0.0.0 ,they work fine,but is not secure,How to configure it ,please help me !
It's obviously not your problem, but it is confusing that you're calling your configuration file "gunicon_wsgi.py". It's not your WSGI file. Call it "gunicorn_conf.py" or something similar.
Your problem is however that you have misunderstood what it means to bind to an IP address. You can't bind your gunicorn server to an IP address on a different machine; that makes no sense at all. And it's not "insecure" to bind to 0.0.0.0.
I'm a very beginner in python and django. However I'm trying to create a server to deploy my application. But when I want to access my app, I always get the default nginx page "Welcome to nginx".
This server is on Ubuntu 12.04 (precise)
I've installed nginx, python, django and uwsgi packages with apt.
Next I've created a django project to /var/www/djangoApps and a django app to /var/www/djangoApps/testApp
This is my /etc/nginx/sites-available/djangoApps :
server {
listen 80
server_name django.pommesky.com;
rewrite ^(.*) http://www.django.pommesky.com/$1 permanent;
}
server {
listen 80;
server_name www.django.pommesky.com;
access_log /var/log/nginx/djangoApps_access.log;
error_log /var/log/nginx/djangoApps_error.log;
location /media {
alias /var/www/djangoApps/media/;
}
location /static {
alias /var/www/djangoApps/static/;
}
location / {
uwsgi_pass unix:///run/uwsgi/app/djangoApps/socket;
include uwsgi_params;
}
}
And this is my /etc/uwsgi/apps-available/djangoApps.ini :
env = DJANGO_SETTINGS_MODULE=djangoApps.settings
module = django.core.handlers.wsgi:WSGIHandler()
chdir = /var/www/djangoApps
socket = /run/uwsgi/djangoApps/socket
logto = /var/log/uwsgi/djangoApps.log
The uwsgi log doesn't show anything, everything seems to run well, it finishes by spawned uWSGI worker ...
But /var/log/nginx/djangoApps_access.log; and /var/log/nginx/djangoApps_error.log; don't exist, which is very strange.
I can't figure out what's wrong with my configuration.
Please help me ...
The domain django.pommesky.com doesn't look like it's alive, so it's possible that Nginx is receiving requests with wrong Host: field in the HTTP request header. (sect. 14.23) So Nginx serves a default catch-all page.
You can disable the default Nginx site by removing the /etc/nginx/sites-enabled/default link, and then restarting the daemon.
sudo rm -v /etc/nginx/sites-enabled/default
sudo service nginx restart
You can reenable by recreating the link:
sudo ln -sf /etc/nginx/sites-available/default /etc/nginx/sites-enabled/default
sudo service nginx restart
The other thing you can try is to setup Bind or another DNS daemon to serve a fake pommesky.com zone with all the subdomains you want and use that DNS while you're developing your site.
Of course you can also register that domain with a hosting provider, and then use the DNS zone editor in its control panel to setup your subdomains and all the PTRs you want to whatever public IP addresses you need.