How to correctly load Flask app module in uWSGI? - python

[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.

Related

What is the command for starting a WSGI server for Django?

I've developed an application in Django that I usually run in development mode:
python manage.py runserver
I do the same for my deployed instances - obviously a security issue that I now want to resolve.
From the Django docs, its not clear to me how to:
For simplicity sake, I picked wsgi (over asgi): https://docs.djangoproject.com/en/4.0/howto/deployment/wsgi/ . From this page, its not clear to me how my 'runserver' command changes to run the wsgi server over the development server. Should I run the wsgi.py file? That doesn't seem to do anything.
From the page above, its not clear whether wsgi is actually a server, or more a platform/type of servers. Do I need to use uwsgi/uvicorn/etc. instead?
I'm testing on windows - uvicorn is unix only, so I tried uwsgi, but thats giving me this error message: AttributeError: module 'os' has no attribute 'uname' - I guess its Unix only as well
So I'm using the docker image I was already building for deployment - uwsgi is giving me issues again because my docker image has no compiler, so I try now with gunicorn.
that should be easy: gunicorn project.wsgi, which gives me:
ModuleNotFoundError: No module named 'project/wsgi'
my folder structure looks like:
root-folder
project
wsgi.py
settings.py
django_app_1
django_app_2
manage.py
As the manual says, the gunicorn command should work as long as you run the gunicorn command from the same location as manage.py - which is what I'm doing.
I guess I'm missing something very obvious - who knows what?
The wsgi.py file just gives you a WSGI compatible application that a WSGI HTTP server (such as Gunicorn) can run.
I guess you have to run gunicorn project.wsgi from the root folder (that one containing the project module).
Typically, the directory containing manage.py and the module in which wsgi.py resides are one and the same. But not in your case.

NGINX + Gunicorn + Flask - 502 Bad Gateway - Permission Denied on Socket File

We are trying to set up NGINX as a reverse proxy to our Gunicorn Python application. We have been following this Guide from Digital Ocean (https://www.digitalocean.com/community/tutorials/how-to-serve-flask-applications-with-gunicorn-and-nginx-on-ubuntu-16-04#create-a-systemd-unit-file). Both Gunicorn and NGINX are running on the same Ubuntu 16.04 32-bit virtual machine.
All of the posts we've seen online dealing with this type of permissions issue seem to point to the wrong "Group" setting in the service file, or to wrong permissions on the socket file. But as you can see below, we have the group set to "www-data". The socket file appears to have the necessary permissions and www-data is the owner.
What we currently have set (I've replaced our app name with "app"):
run.py
from flask import current_app
import os
from os import path
from application import app
from instance.config import Config
if __name__ == '__main__':
conf = Config()
app.run(host='0.0.0.0', debug=False, threaded=True)
/etc/systemd/system/app.service
[Unit]
Description=Application
After=network.target
[Service]
User=<root>
Group=www-data
WorkingDirectory=/home/<root>/app
Environment="PATH=/home/<root>/venv/bin"
ExecStart=/home/<root>/venv/bin/gunicorn --workers 3 --bind unix:app.sock -m 007 run:app
[Install]
WantedBy=multi-user.target
/etc/nginx/sites-available/app
server {
listen 80;
server_name app.com;
location / {
include proxy_params;
proxy_pass http://unix:/home/<root>/app/app.sock;
}
}
/var/log/nginx/error.log
2020/06/05 16:49:22 [crit] 2176#2176: *1 connect() to unix:/home/<root>/app/app.sock failed (13: Permission denied) while connecting to upstream, client: 10.0.2.2, server: app.com, request: "GET / HTTP/1.1", upstream: "http://unix:/home/<root>/app/app.sock:/", host: "app.com"
Here are the permissions on the socket file:
gsi#ubuntu:~/app$ ls -l app.sock
srwxrwx--- 1 <root> www-data 0 Jun 5 16:10 app.sock
We're new to NGINX so we're not quite sure what the issue is or how to troubleshoot this. Can anyone see where we're going wrong here? Please let us know if there's additional info we can provide.
I just ran into this problem. I was able to create the gunicorn socket file, but nginx complained about permission denied. The issue was that my socket file was in a sub-folder and the root folder did not have read or execute permissions. So even though the sub-folder had the correct permissions, the root folder prevented nginx from entering the sub-folder.
The solution was to add read and execute permissions to the root folder:
chmod o+rx /example_root_folder
We were able to resolve this by giving the www-data group access to the full application folder: sudo chgrp www-data ~/app. It already had access to the socket file specifically, but not the application folder.
I didn't think this was necessary since we specified the root user as the owner of the service. The root user already had access to the app folder and the instructions we were following didn't have steps for setting up the group access.
I don't have a lot of experience with Linux permissions/ownership though so this might be obvious to most experienced users.
Instead of entering app.com in the server name, try entering the IP address of the host machine and see if that works on the machine itself by running:
$curl <IP address of the host machine>
If still it doesn't work, I have written an article on the same, try to implement it using that and let me know if it works!
Hope it helps! :)

Target WSGI script not found or unable to stat for Flask Apache

I am trying to load a Flask app in a subdirectory on my domain. Below is my virtual host configuration. the Flask app is kept at /var/www/FlaskApps/Recommender/
Apache's error log keeps saying "Target WSGI script not found or unable to stat: /var/www/FlaskApps/FlaskApp.wsgi" when i try to reach the endpoint /recommender
From online other people said it might be a permission issue, but I'm not sure if it's the case per snapshot below.
Thanks for your help
You have FlaskApps.wsgi in directory, but FlaskApp.wsgi in WSGIScriptAlias directive. So they don't match.

uwsgi works from console but not ini

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.

Heroku looking for the wrong wsgi file. Django

I'm on Django, but I'm not sure if it matters. Anyway, I get an Application Error, and when I check the logs I see the error:
ImportError: No module named redlibros.wsgi
And it is fine cause the wsgi file is not name "redlibros.wsgi", I don't even know where it gets that name. The module is named
WSGI_APPLICATION = 'letrasclub.wsgi.application' # on my settings
web: gunicorn letrasclub.wsgi --log-file - # on my procfile
and on my folders it looks like this:
LetrasClub
letrasclub
wsgi.py
templates
static
...
Any idea where to find the error?
EDIT
Ok, some extra info: I have a different repo, with a different Heroku remote. I copied that repo, changed the app, created a new Heroku remote and then pushed to the new one.
So, if I write
git remote -v
heroku https://git.heroku.com/letrasclub2.git (fetch)
heroku https://git.heroku.com/letrasclub2.git (push)
origin https://github.com/Alejoss/LetrasClub2.0.git (fetch)
origin https://github.com/Alejoss/LetrasClub2.0.git (push)
Looks fine, if I go to the old app location and write the same command I get the old remote, the one that is related to the "redlibros.wsgi" app, perfect.
Now, why when I try to push the new app to the new heroku remote, I get the error that means Heroku is looking for the Old wsgi file, I changed the wsgi name, I changed the Procfile, I changed the wsgi file declaration on the settings, what am I missing?
You look at wrong project.
You look at https://github.com/Alejoss/redlibros (I guess it's Your project), not at https://github.com/Alejoss/LetrasClub2.0

Categories