configuring web.py in nginx.. confusion - python

Hi I am new with nginx server, and I have uploaded my index.py file at /var/www/pyth/index.py ...
I am a little bit confused because in my local I can run freely
python index.py and access http://127.0.0.1:8080
I was wondering how can I do that in nginx, I have run python index.py but I can't access to mysite.com:8080
this is my config in /etc/nginx/sites-available/default
server {
listen 80 default_server;
listen [::]:80 default_server ipv6only=on;`
#root /usr/share/nginx/html;
#index index.php index.py index.html index.htm;
root /var/www/mysite.com;
index index.php index.py index.html index.htm;
# Make site accessible from http://localhost/
server_name mysite.com;
location / {
# First attempt to serve request as file, then
# as directory, then fall back to displaying a 404.
try_files $uri $uri/ =404;
# Uncomment to enable naxsi on this location
# include /etc/nginx/naxsi.rules
}
# Only for nginx-naxsi used with nginx-naxsi-ui : process denied reques$
#location /RequestDenied {
# proxy_pass http://127.0.0.1:8080;
#}
#error_page 404 /404.html;
...
does anyone has an idea about my case? any help will be appreciated.. thanks in advance

You should set up either a uwsgi (or similar), or a proxy_pass in nginx.
The option with UWSGI is better because it'll use the protocol designed for working with web-servers; though it's a bit harder to set up than just proxying everything via nginx.
proxy_pass
web.py has a web-server just for the development purposes, it shouldn't be used in production environment because it's really slow and inefficient in that case, and using proxy_pass wouldn't be a great idea if you are planning to release it.
With proxy_pass, you leave the 127.0.0.1:8080 server online, and then in nginx (on the same server), set up like that:
location / {
proxy_pass http://127.0.0.1:8080;
proxy_set_header X-Real-IP $remote_addr;
proxy_set_header Host $host;
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
}
The proxy_pass option redirects everything to the web.py server at 127.0.0.1:8080, the other ones - redirect the data about the connection (IP of the connected client and the host that was used for the connection on the nginx's side)
UWSGI
Using UWSGI, in short, is like that:
1) install uwsgi using your distro's package manager, or a pip, or using setup.py install.
2) in nginx, set up a server that will pass everything to the UWSGI server:
server {
listen 80;
location / {
include uwsgi_params;
uwsgi_pass 127.0.0.1:9000;
}
}
3) Then, in your web.py application (let's suppose it's called yourappfile.py), instead of app.run(), use:
app = web.application(urls, globals())
application = app.wsgifunc()
You can still have app.run(), just make sure to put it inside the if __name__ == '__main__' block; and make sure the application = app.wsgifunc() is outside so UWSGI could see it.
Then start a UWSGI server:
uwsgi --http :9090 --wsgi-file yourappfile.py
Take a look at these manuals, it may help you:
UWSGI Quickstart
Web.py running on the nginx uwsgi
Deployment of Web.py Applications Using uWSGI and
Nginx
UWSGI Wiki - Examples

Related

Django + nginx + gunicorn not being able to serve static files

I'm trying to deploy a django app in a EC2 instance but I'm currently having issues serving the static files of the app.
Currently, my nginx's conf file looks like this:
# Default server configuration
#
server {
listen 80 default_server;
listen [::]:80 default_server;
root /var/www/html;
# Add index.php to the list if you are using PHP
index index.html index.htm index.nginx-debian.html;
server_name _;
location / {
proxy_set_header Host $host;
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
proxy_pass http://0.0.0.0:8000;
}
location /static/ {
#autoindex on;
root /home/ubuntu/some/folder/static/;
}
}
Also in my settings.py file in my django project I have the following config related to my static files:
STATIC_URL = '/static/'
STATIC_ROOT = '/home/ubuntu/some/folder/static/'
and Gunicorn, I'm launching it as the following:
gunicorn3 --bind 0.0.0.0:8000 myproject.wsgi:application
And with that, if I access http://ec2-my-instanceI see the html content, but all my js and css files get error 404.
I'm kinda lost and I don't know what I'm missing to make it works, I already migrated the static content and I checked the folder which nginx is looking for the static files have them, but if I check the browser's console I see this kind of errors:
GET http://ec2-my-instance/static/somefile.js net::ERR_ABORTED 404 (Not Found)
You want 'alias' not 'root':
location /static/ {
alias /home/ubuntu/some/folder/static/;
}

Multiple Django app using nginx and gunicorn on Ubuntu 14.04 trusty server

I am new to server configuration. I do some google and config django app using gunicorn and nginx on ubuntu 14.04 trusty server. For the first django app I use port number 80 and my configfiles are :
/etc/init/gunicorn.conf :-
description "Gunicorn application server handling myproject"
start on runlevel [2345]
stop on runlevel [!2345]
respawn
setuid
setgid www-data
chdir /home/myserver/my_virtualenv_path/myproject
exec /home/myserver/my_virtualenv_path/myproject/gunicorn --workers 2 --bind unix:/home/myserver/my_virtualenv_path/myproject/myproject.sock myproject.wsgi:application
My nginx configuration file for first django app:
/etc/nginx/site-available :-
server {
listen 80;
server_name myapp.com;
location = /favicon.ico { access_log off; log_not_found off; }
location /static/ {
root /home/myserver/my_virtualenv_path/myproject;
}
location / {
include proxy_params;
proxy_pass http://unix:/home/myserver/my_virtualenv_path/myproject/myproject.sock;
}
}
After that, i link site to site-enabled .
Next, i create a new django app inside the first django app virtualenv like:
FirstApp_Virtual_Env\first_djangoapp\app files
FirstApp_Virtual_Env\Second_djangoapp\app files
Now i configure gunicorn for second app like :
/etc/init/gunicorn_t :-
description "Gunicorn application server handling myproject2"
start on runlevel [2345]
stop on runlevel [!2345]
respawn
setuid
setgid www-data
chdir /home/myserver/my_virtualenv_path/myproject2
exec /home/myserver/my_virtualenv_path/myproject/gunicorn --workers 2 --bind unix:/home/myserver/my_virtualenv_path/myproject2/myproject2.sock myproject2.wsgi:application
My nginx configuration file for second django app:
/etc/nginx/site-available :-
server {
listen 8000;
server_name myapp2.com;
location = /favicon.ico { access_log off; log_not_found off; }
location /static/ {
root /home/myserver/my_virtualenv_path/myproject2;
}
location / {
include proxy_params;
proxy_pass http://unix:/home/myserver/my_virtualenv_path/myproject2/myproject2.sock;
}
}
After that i link site to site-enabled .
Now here is my problem: when i type myapp.com then my first django app is working fine but for second app when i type myapp2.com its showing nginx page and when i type myapp2.com:8000 it's working fine . I do some google for that but i am unable to find solution. I am newbie to this so please give me a hint for that how to correct my problem. Thanks for your time.
You configured nginx to serve myapp2.com on port 8000:
server {
listen 8000;
server_name myapp2.com;
# ...
}
so why would you expect nginx to serve it on port 80 ?
[edit] I thought the above was enough to make the problem clear but obviously not, so let's start again:
You configured nginx to serve myapp2.com on port 8000 (the listen 8000; line in your conf, so nginx do what you asked for: it serves myapp2.com on port 8000.
If you want nginx to serve myapp2.com on port 80 (which is the implied default port for http so you don't have to specify it explicitely in your url - IOW 'http://myapp2.com/' is a shortcut for 'http://myapp2.com:80/'), all you have to do is to configure nginx to serve it on port 80 just like you did for 'myapp.com': replace listen 8000; by listen 80;.
If you don't type in a port, your client will automatically use port 80.
Typing myapp2.com is the same as typing myapp2.com:80
But myapp2.com is not running on port 80, it's running on port 8000.
When you go into production it is possible to redirect myapp2.com to port 8000 without explicitly typing it. You register myapp2.com with a DNS name server and point it towards myapp2.com:8000

Running 2 Gunicorn Apps and Nginx with Supervisord

This problem has admittedly stumped me for months. I've just procrastinated fixing other bugs and putting this aside until now where it HAS to be fixed --
I am trying to run 2 separate gunicorn apps and start nginx within the same supervisord.conf file. When I start supervisor, I am able to successfully run the handlecalls app but when I go to the website that commentbox is responsible for loading, I get an internal service error (500).
When I run the handlecalls and commentbox apps separately with the commands following the command field, the apps run fine. Why is the commentbox program giving me a 500 error when I try to run both with supervisord?
my supervisord script:
[program:nginx]
directory = /var/www/vmail
command = service nginx start -g "daemon off;"
autostart = True
[program:commentbox]
directory = /var/www/vmail
command = gunicorn app:app -bind 0.0.0.0:8000
autostart = True
[program:handlecalls]
directory = /var/www/vmail
command = gunicorn handle_calls:app --bind 0.0.0.0:8000
autostart = True
[supervisord]
directory = /var/www/vmail
logfile = /var/www/vmail/supervisorerrs.log
loglevel = trace
This has nothing to do with supervisord. Supervisord is just a way for you to start/stop/restart your server. This has more to do with your server's configuration.
The basic: To serve two gunicorn apps with nginx, you have to run them on two different ports, then config nginx to proxy_pass the request to their respective ports. The reson is: once a process is running on a port, that port cannot be used by another process.
So change the configuration in your supervisord script to:
[program:commentbox]
directory = /var/www/vmail
command = gunicorn app:app --bind 0.0.0.0:8000
autostart = True
[program:handlecalls]
directory = /var/www/vmail
command = gunicorn handle_calls:app --bind 0.0.0.0:8001
autostart = True
Then in your nginx server's configuration for handlecalls
proxy_pass 127.0.0.1:8081
Update: Here is the basics of deploying a web application
As mentioned above, one port can only be listened by a process.
You can use nginx as a http server, listening to port 80 (or 443 for https), then passing the request to other applications listening to other ports (for example, commentbox on port 8000 and handlecalls on port 8001)
You can add rules to nginx as how to serve your application by adding certain server configuration files in /etc/nginx/sites-available/ (by default. It is different in some cases). The rules should specify a way for nginx to know which application it should send the request to, for example:
To reuse the same http port (80), each application should be assigned to a different domain. i.e: commentbox.yourdomain.com for commentbox and handlecalls.yourdomain.com for handlecalls
A way to serve two different apps on the same domain, is for them to serve on different ports. For example: yourdomain.com would serve commentbox and yourdomain.com:8080 would serve handlecalls
A way to serve two different apps on the same domain and the same ports, is for them to serve on two different endpoints. For example yourdomain.com/commentbox would serve commentbox and yourdomain.com/handlecalls would serve handlecalls
After adding configuration files to /etc/nginx/sites-available/, you must symlink those files to /etc/nginx/sites-enabled/, well, to tell nginx that you want to enable them. You can add the files directly to /etc/nginx/sites-enabled/, but I don't recommend it, since it doesn't give you a convenient way to enable/disable your application.
Update: Here is how to config nginx to serve gunicorn applications using two different subdomains:
Add two subdomains commentbox.yourdomain.com and handlecalls.yourdomain.com, and point them both to your server's IP.
Create a a configuration file for commentbox at /etc/nginx/sites-available/commentbox with the following content (edit as fit):
server {
listen 80;
server_name commentbox.yourdomain.com;
root /path/to/your/application/static/folder;
location / {
try_files $uri #app;
}
location #app {
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_redirect off;
proxy_pass http://127.0.0.1:8000;
}
}
Create a configuration file for handlecalls at /etc/nginx/sites-available/handlecalls with the following content (edit as fit):
server {
listen 80;
server_name handlecalls.yourdomain.com;
root /path/to/your/application/static/folder;
location / {
try_files $uri #app;
}
location #app {
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_redirect off;
proxy_pass http://127.0.0.1:8001;
}
}
Create symlinks to enable those servers:
sudo ln -s /etc/nginx/sites-available/commentbox /etc/nginx/sites-enabled/
sudo ln -s /etc/nginx/sites-available/handlecalls /etc/nginx/sites-enabled/
Restart nginx to take effect
sudo service nginx restart

Nginx and Gunicorn 502

I am deploying an application to a server, but I seem to be misunderstanding some basic concepts here. The problem is that I am using gunicorn with port 8001
gunicorn myproj.wsgi:application --bind XXX.XXX.XXX.XXX:8001
Nginx, however, is listening to port 8000, as you can see in the file /etc/nginx/sites-available/myproj:
server {
listen 8000;
server_name XXX.XXX.XXX.XXX;
access_log off;
location /static/ {
root /opt/myproj;
}
location / {
proxy_pass http://127.0.0.1:8001;
proxy_set_header X-Forwarded-Host $server_name;
proxy_set_header X-Real-IP $remote_addr;
add_header P3p 'CP="ALL DSP COR PSAa PSDa OUR NOR ONL UNI COM NAV"';
}
}
So, here is what happens:
When I access XXX.XXX.XXX.XXXX:8001, I get my page, but without any of the static files. I can access the static files by XXX.XXX.XXX.XXX:8000/static/css/mycss.css. However, when I access XXX.XXX.XXX.XXX:8000, I get a 502 - Bad Gateway error.
What am I misunderstanding here? How can I access my page with the static files?
Your problem is happening because you are binding gunicorn to your external ip, but nginx is forwarding to the localhost port. The point is that gunicorn should not be accessible to the outside at all; all requests should go through the nginx reverse proxy.
Bind gunicorn to 127.0.0.1:8001.
The basic scheme when using application servers, like gunicorn is:
[User's web browser] <-> [Web server(Nginx)] <-> [Application server(Gunicorn)]
The web server usually listens on public IP address on port 80, and then forwards the connection to application server, serving as reverse proxy. If you run application server and web server on same host it's common to bind both to "localhost"(IP: 127.0.0.1) and same port, i.e. 8001 in your case. So try binding Gunicorn on 127.0.0.1:8001 as specified in your Nginx configuration.
Note: In case when two servers are running on one machine, it's usually worth connecting them via Unix sockets instead of network sockets for performance reasons.

Django deployment https + gunicorn and nginx

I am stuck with setting the https with django on aws with nginx and gunicorn.
my configuration is:
server {
listen 80;
listen 443 ssl;
server_name logitech.enterpriselist.com;
rewrite ^ https://logitech.enterpriselist.com$request_uri? permanent;
root /home/ubuntu/git/elist/static/;
#` ssl on;
ssl_certificate /etc/ssl/elist.crt;
ssl_certificate_key /etc/ssl/elist.key;
location / {
# proxy_pass http://logitech.enterpriselist.com/;
}
location /static/ {
alias /home/ubuntu/git/elist/static/;
}
}
It is working fine with http with port 8001:
gunicorn configs.wsgi:application --bind 172.31.14.102:8001`
and not with domain
http://logitech.enterpriselist.com:8001/.
But I also want to run the things with the default port, but when I run
gunicorn configs.wsgi:application --bind 172.31.14.102:80
it says address already in use!
Also with https when I open http://logitech.enterpriselist.com/, it goes to https://logitech.enterpriselist.com/ but it says website have redirect loop so I need help in sorting this.
You haven't got anything to tell nginx it should be proxying requests to gunicorn. In particular, you need a proxy_pass directive and an upstream section.
Also, you don't want to run gunicorn on port 80, since that is what nginx is already bound to. That's what the proxy is for.
The gunicorn deployment docs have an example nginx configuration which works fine.

Categories

Resources