uwsgi works from console but not ini - python

I am trying to setup graphite with nginx. Because of this I need to run it using a configuration or ini file in /etc/uwsgi, but I am unable to get the application to start correctly.
Using, the command,
uwsgi --http :9090 --wsgi-file /opt/graphite/conf/graphite.py
Graphite starts and runs fine, I can navigate it and look at stats.
I proceeded to create an ini file, with the contents:
[uwsgi]
processes = 2
socket = localhost:8081
gid = nginx
uid = nginx
chdir = /opt/graphite/conf
uswsgi-file = graphite.py
running the ini file I see:
mapped 145536 bytes (142 KB) for 2 cores
*** Operational MODE: preforking ***
*** no app loaded. going in full dynamic mode ***
*** uWSGI is running in multiple interpreter mode ***
I can only guess it something is misconfigured here in the ini file but I am not seeing what it is.
Any help is appreciated!

There are some differences between your command line and ini file:
you're using socket instead of http inside ini. That means, uWSGI server will talk using uwsgi protocol instead of http. If you're using uwsgi_pass in nginx and trying to access your website from browser through that nginx, it's fine. But if you're trying to access uwsgi directly from browser, bypassing nginx, you won't succeed because browsers doesn't talk uwsgi.
You've put uswgi-file instead of wsgi-file into your config. That won't work at all and uwsgi won't be able to find your wsgi file.
And if you're chdiring into directory with your wsgi file, it is better to use:
module = wsgi
instead of wsgi-file.

Related

uWSGI startup logs formatted as json

uWSGI has an option for disabling logging from the application it is running. This way, I can control my application logging from Python. However, disabling these still leaves the uWSGI startup messages in the usual format, e.g.
[uWSGI] getting INI configuration from /app/uwsgi.ini
*** Starting uWSGI 2.0.18 (64bit) on [Tue Nov 12 08:36:47 2019] ***
compiled with version: 8.3.0 on 12 November 2019 08:35:14
...
The problem with these is that they are not formatted as json, which means that all log messages are shown as errors in my logging viewer, Google Stackdriver.
uWSGI has an option for encoding/formatting logs, see here, specifically the log-encoder = json { ... option.
The problem is that if I encode the logs as json, using the option above, specifically the following,
log-encoder = json {"unix":${unix}, "msg":"${msg}"}
the startup logs simply disappear.
How can I format startup logs as json?
uWSGI has three sources of log messages:
Application logs (python logs)
uWSGI server logs (information about server startup, errors, warnings)
Request logs
If I'm getting it right, you have problems with logs under point 2 (uWSGI server logs).
A configuration like this one works for me:
logger = default stdio
log-route = default ^((?!\{).)*$
log-encoder = json:default {"time":"${micros}", "source":"uwsgi", "message":"${msg}"}
log-encoder = nl
You can separately format the request logs using the logger-req and log-req-encoder options.
More on JSON logging in uWSGI and full configuration of all log types can be found here

How to switch different config file running flask with uwsgi

I am deploying my flask app with uwsgi to multiple servers.
Different server should run the same app but read different config file. There are two config file used in my app.
one is 'config.py' read by flask:
app.config.from_object('config')
another is the 'uwsgi_config.ini' which is used when starting uwsgi:
uwsgi uwsgi_config.ini
Since I have several server, I must write several config files like:
config.dev.py config.test.py config.prod.py
uwsgi_config.dev.py uwsgi_config.dev.py uwsgi_config.prod.py
So my question is how can I switch different tiers when starting uwsgi without hacking the source code every time ?
I think the key thing is I should run uwsgi like this:
uwsgi uwsgi_config.dev.ini
and then flask can read the 'dev' tier from uwsgi_config.dev.ini.
Is there a simple way to do this ?

How to correctly load Flask app module in uWSGI?

[EDIT]
I managed to load the flask app module by starting uwsgi from within the project folder. I now have a problem with nginx not having permission to the socket file though (scroll down to the end of the question). If anybody can help with that..?
[/EDIT]
Following this tutorial I'm trying to run my Flask website with uWSGI and nginx. When doing exactly as the tutorial says it works fine. I now want to run my own website though. And the structure of my own website project looks as follows:
myownproject
|-app
| -__init__.py
|-run.py
|-myownproject_nginx.conf
|-myownproject_uwsgi.ini
in which app is loaded in __init__.py like this:
app = Flask(__name__)
and myownproject_uwsgi.ini looks like this:
[uwsgi]
#application's base folder
base = /home/kramer65/myownproject
#python module to import
app = app
module = %(app)
# I disabled these lines below because I don't use a venv (please don't ask)
# home = %(base)/venv
# pythonpath = %(base)
#socket file's location
socket = /home/kramer65/myownproject/%n.sock
#permissions for the socket file
chmod-socket = 666
#the variable that holds the flask application inside the imported module
callable = app
#location of log files
logto = /var/log/uwsgi/%n.log
But when I run this:
$ uwsgi --ini /home/kramer65/myownproject/myownproject_uwsgi.ini
[uWSGI] getting INI configuration from /home/kramer65/myownproject/myownproject_uwsgi.ini
I get the following logs in /var/log/uwsgi/myownproject_uwsgi.log:
*** Operational MODE: single process ***
ImportError: No module named app
unable to load app 0 (mountpoint='') (callable not found or import error)
*** no app loaded. going in full dynamic mode ***
*** uWSGI is running in multiple interpreter mode ***
Why doesn't uwsgi find my callable? And why is the mountpoint empty (='')? What am I doing wrong here?
Does anybody know how I can get this to work properly?
[EDIT]
Okay, I tried running uwsgi --ini /home/kramer65/myownproject/myownproject_uwsgi.ini from within the myownproject project folder, which solves this problem; it now finds the callable and that seems to work fine.
I still get a 502 though, the next problem seems to be a permission problem with nginx not having permission to the socket file. /var/log/nginx/error.log says:
2015/10/27 11:40:36 [crit] 14276#0: *1 connect() to
unix:/home/kramer65/myownproject/myownproject_uwsgi.sock failed (13:
Permission denied) while connecting to upstream, client:
80.xxx.xxx.xxx, server: localhost, request: "GET / HTTP/1.1", upstream:
"uwsgi://unix:/home/kramer65/myownproject/myownproject_uwsgi.sock:",
host: "52.xx.xx.xxx"
So I changed the chmod-socket = 666 to chmod-socket = 777. When doing an ls -l I actually see the socket file having full permissions, but I still get the error I pasted above.
Any ideas to get this working?
The base config is just a internal variable. The part you commented out caused your problem.
If you don't want to use virtualenv and set your pythonpath, change the base config to chdir.
chdir = /home/kramer65/myownproject
Internally, uWSGI will run from chdir instead of from the current directory.
About the socket permission problem, the nginx user (probably www-data) does not have access to your personal folder (/home/kramer65/). You must set the socket to another folder, where nginx and uwsgi have access.

nginx+uwsgi+django, there seems to be some strange cache in uwsgi, help me

This is uwsgi config:
[uwsgi]
uid = 500
listen=200
master = true
profiler = true
processes = 8
logdate = true
socket = 127.0.0.1:8000
module = www.wsgi
pythonpath = /root/www/
pythonpath = /root/www/www
pidfile = /root/www/www.pid
daemonize = /root/www/www.log
enable-threads = true
memory-report = true
limit-as = 6048
This is Nginx config:
server{
listen 80;
server_name 119.254.35.221;
location / {
uwsgi_pass 127.0.0.1:8000;
include uwsgi_params;
}
}
The django works ok, but modifed pages can't be seen unless i restart uwsgi.(what's more, as i config 8 worker process, i can see the modified page when i press on ctrl+f5 for a while, seems that only certain worker can read and response the modified page, but others just shows the old one, who caches the old page? i didn't config anything about cache)
I didn't config the django, and it works well with "python manager runserver ...", but havfe this problem when working with nginx+uwsgi.
(the nginx and uwsgi are both new installation, i'm sure nothing else is configed here..)
uwsgi does not reload your code automatically, only development server does
runserver is for debug purposes, uwsgi and nginx for production
in production you can restart uwsgi by service uwsgi restart or via init.d script
there is even better way to reload uwsg by using touch-reload
usually there is no need to cleanup .pyc files, it happens only when timestamps on files are wrong (I've seen it only couple times at my entire carieer)
This is normal behavior. uwsgi will not re-read your code unless you restart it (it does not work like runserver when you have DEBUG=True).
If after you have updated your code, restarted uwsgi, cleared your browser cache and it still doesn't reflect your changes, then you should delete *.pyc files from your source directory.
I typically use this:
find . -name "*.pyc" -exec rm {} \;
Roughly speaking, .pyc is the "compiled" version of your code. Python will load this optimized version if it doesn't detect a change in the source. If you delete these files; then it will re-read your source files.

Deploying a Pyramid application using uWSGI and Cherokee

I'm attempting to setup a generic Pyramid project to work with uWSGI through Cherokee, but constantly get a "no app loaded" error. All the research I've done doesn't really give me much to go on. Anyone have any ideas? Please note that I 'am' using a virtualenv via virtualenvwrapper.
This is from my development.ini
[uwsgi]
socket = 127.0.0.1:2626
master = true
processes = 1
virtualenv = /home/user/.virtualenvs/pyramid/
pythonpath = /home/user/Projects/ConventionMeStatic
And this is the command I've been trying to use to launch it: /usr/bin/uwsgi --ini development.ini --plugin python.
I can post any further details but there have been no other changes made to the project itself.
You have specified a virtualenv and a pytonpath, but you have not specified which app to load.
If you have a single-file app you can load that file with the --wsgi-file option, if you have a deployment.ini file you can use the --paste option as described here
http://projects.unbit.it/uwsgi/wiki/UsePaste
or the --ini-paste shortcuts described in examples section of the uwsgi wiki

Categories