Hi Auden,
Thanks for posting your detailed instructions. I was trying to understand your uwsgi and nginx configuration recently and I think there may be some confusion in how your setup is working.
It looks like you are using uwsgi to start up py4web as a normal bottle http server rather than as a wsgi application. To correctly use nginx + uwsgi your nginx configuration should have a uwsgi_pass configuration rather than the proxy_pass entry you have. From my recent research I understand that using uwsgi_pass avoids the overhead of processing the http protocol twice (once within nginx and also within bottle) and is therefore more efficient.
I think the correct code for your app.py should be:
import os
from py4web.core import wsgi
password_file = os.path.abspath(os.path.join(os.path.dirname(__file__),"password.txt"))
application = wsgi(password_file = password_file, dashboard_mode = "full",apps_folder=os.path.abspath(os.path.dirname(__file__)))
the last line in your instructions actually starts up the bottle server I think, which shouldn't be needed.
In your nginx server configuration you should have the following (where you currently have proxy_pass):
uwsgi_pass unix://home/www-data/py4web/py4web.sock;
include uwsgi_params;
This would correctly connect to the uwsgi socket you create in your pyweb.ini uwsgi configuration file. As a side note I saw a comment that the correct place to put a socket file is in the /run/ folder on a modern linux system, so /run/uwsgi/py4web.sock might be a sensible path.
I chose to use a port rather than a socket so my configuration files are as follows if anyone wants to do it the same way. This is simpler as it avoids any potential permissions issues on the socket file.
uwsgi config (py4web.ini):
[uwsgi]
socket = :8081
chdir = /path/to/py4web/apps
pythonpath = /path/to/py4web/apps
file = app.py
plugins = python
uid = http
gid = http
Note: http is the same user account used to run nginx on my system.
This app.py goes into the chdir folder specified above:
import os
from py4web.core import wsgi
password_file = os.path.abspath(os.path.join(os.path.dirname(__file__),"password.txt"))
application = wsgi(password_file = password_file, dashboard_mode = "full", apps_folder=os.path.abspath(os.path.dirname(__file__)))
location entry for specific application in nginx configuration file, sits within a server config block:
location /app_name {
uwsgi_pass 127.0.0.1:8081;
include uwsgi_params;
}
On my system I can now go to
http://localhost/app_name to use that specific py4web application. I believe this is now correctly getting nginx to handle all the http protcol and using the more efficient wsgi protocol between nginx and the py4web application.
If you run uwsgi in the command line using the changes suggested above you will not see any reference to bottle starting up and running on port 8080 (or whatever port you specify in your app.py), which proves you are no longer using bottle's http server to handle requests and are in fact using the more efficient wsgi protocol.
I hope this clears up some confusion and is helpful to anyone else trying a similar set up. My system is actually ArchLinux so while I'm happy to share any other steps needed, these may vary from the ubuntu system described in your document.
Richard.