Trying to set up flask with nginx and gunicorn - python

I have followed a simple guide, and trying to show my flask application, but it wont show. I am running everything through ssh on a ubuntu server.
Have my flask app and wsgi.py in /var/www/application/
My nginx config is:
server {
listen 80;
server_name application;
access_log /var/log/nginx/application.access.log;
error_log /var/log/nginx/appliation.error.log;
location / {
include proxy_params;
proxy_pass http://unix:/var/www/application/application.sock;
}
}
I have symlinked the file to /etc/nginx/sites-enabled/
Then here is my gunicorn application config
located in: /etc/systemd/system/application.service
[Unit]
Description=application.service - A Flask application run with Gunicorn.
After=network.target
[Service]
User=www-data
Group=www-data
WorkingDirectory=/var/www/application/
ExecStart=/usr/bin/gunicorn --workers 3 --bind unix:/var/www/application.sock wsgi:app
[Install]
WantedBy=multi-user.target
Have checked all processes are running, and systemd status ok, but when i try to curl
http://application
I get nothing?
My app.py
from flask import Flask
app = Flask(__name__)
#app.route("/")
def home():
return "<h1>Nginx & Gunicorn</h1>"
wsgi.py
from main import app
if __name__ == "__main__":
app.run(debug=True)
What am I missing here, how to get it working?

ExecStart=/usr/bin/gunicorn --workers 3 --bind unix:/var/www/application.sock wsgi:app
the problem is the path /var/www/application.sock, it should be: /var/www/application/application.sock
You can still view the status of the service with the command:
sudo systemctl status <service_name>
To understand if the command specified in the service file is correct, or if the application has problems starting, try to start it directly from the command line:
cd /var/www/application/ && /usr/bin/gunicorn --workers 3 --bind unix:/var/www/application/application.sock wsgi:app

Related

Flask app with Nginx and Gunicorn in Ubuntu

I have a vps flask application that processes incoming requests and returns a result in the format {result: OK} or {result: BAD}. There is also a bunch of nginx + gunicorn. When only gunicorn works for me, everything works as it should, but as soon as I connect nginx, the server returns me a response in the form of html code, which I will present below.
<html>
<head><title>502 Bad Gateway</title></head>
<body>
<center><h1>502 Bad Gateway</h1></center>
<hr><center>nginx/1.18.0 (Ubuntu)</center>
</body>
</html>
Here is my '/etc/nginx/sites-available/myproject' file:
server {
listen 80;
server_name 0.0.0.0;
location / {
include proxy_params;
proxy_pass http://unix:/home/sammy/myproject/myproject.sock;
}
}
My configurations of myproject.service:
[Unit]
Description=Gunicorn instance to serve myproject
After=network.target
[Service]
User=sammy
Group=www-data
WorkingDirectory=/home/sammy/myproject
Environment="PATH=/home/sammy/myproject/myprojectenv/bin"
ExecStart=/home/sammy/myproject/myprojectenv/bin/gunicorn --workers 3 --bind unix:myproject.sock -m 007 wsgi:app
[Install]
WantedBy=multi-user.target
my nginx and myporject status id "active" and have no errors
I can't figure out what I'm doing wrong, because I've read a lot of guides and documentation, the result is still unsuccessful
Once again, if I work without nginx, then everything works fine, but I need to connect it too

How to configure a Django application in a virtual env served by uswgi and started by a systemd service?

I'm trying to configure a basic a Django application served by uwsgi so that it can be started from systemd on a CentoS 7.X server.
So far my SystemD service is started (active and in running state) but application is not reachable on the configured port. Note that application is running inside a Python virtual environment.
Systemd service is active and running
uwsgi worker processes are
active
socket bind to TCP 8003 is in LISTEN state
SystemD unit file
# /etc/systemd/system/django_03.service
[Unit]
Description=My Django app
Requires=network.target
After=network.target
After=syslog.target
[Service]
TimeoutStartSec=0
RestartSec=10
Restart=always
User=myuser
KillSignal=SIGQUIT
Type=notify
NotifyAccess=all
StandardError=syslog
RuntimeDirectory=uwsgi
ExecStart=/bin/bash -c 'cd /opt/scripts/django/django_03; source django_03_env/bin/activate; uwsgi --ini /opt/scripts/django/django_03/django_03.ini'
[Install]
WantedBy=multi-user.target
uwsgi configuration file
# /opt/scripts/django/django_03/django_03.ini
[uwsgi]
module = wsgi:application
master = true
processes = 5
socket = 127.0.0.1:8003
chmod-socket = 664
vacuum = true
die-on-term = true
Django application
# wsgi.py
def application(environ, response):
response('200 OK', [('Content-Type', 'text/html')])
return [b"Test OK (Django 03) !!"]
Thanks for your help
In this example, systemd service is called "django_03", Python virtual env name is "django_03_env", Python application is "wsgi" with a callable named "application".
1 ] Prerequisites
Create a root directory for Python code, configuration files and virtual env:
mkdir /opt/scripts/django/django_03
Create a virtualenv
cd /opt/scripts/django/django_03
python3 -m venv django_03_env
Start virtualenv
source django_03_env/bin/activate
Install Django and uwsgi
pip install django
pip install uwsgi
2 ] Files
There are three files to create
uwsgi configuration file (INI format): django_03.ini
SystemD service unit: django_03.service
Python application: wsgi.py
2.1 SystemD unit file
# /etc/systemd/system/django_03.service
[Unit]
Description=My Django app
Requires=network.target
After=network.target
After=syslog.target
[Service]
TimeoutStartSec=0
RestartSec=10
Restart=always
User=myuser
KillSignal=SIGQUIT
Type=notify
NotifyAccess=all
StandardError=syslog
RuntimeDirectory=uwsgi
# Main call: Virtual env is activated and uwsgi is started with INI file as argument
ExecStart=/bin/bash -c 'cd /opt/scripts/django/django_03; source django_03_env/bin/activate; uwsgi --ini /opt/scripts/django/django_03/django_03.ini'
[Install]
WantedBy=multi-user.target
2.2 uwsgi configuration file
# /opt/scripts/django/django_03/django_03.ini
[uwsgi]
# "callable": Application entry point, <Python filename without extension: application method name>
module = wsgi:application
# Master process for uwsgi
master = true
# Worker processes for uwsgi
processes = 5
# uwsgi protocol modification
protocol = http
# Socket format X.X.X.X:<port number>
socket = 127.0.0.1:8003
chmod-socket = 664
vacuum = true
die-on-term = true
2.3 Django application file
# /opt/scripts/django/django_03/wsgi.py
# Application callable (main entry point)
def application(environ, response):
response('200 OK', [('Content-Type', 'text/html')])
return [b"Test OK (Django 03) !!"]
III ] Managing application
Django application can now be started by a regular systemd command:
sudo systemctl start django_03
Verify systemd service status
sudo systemctl -l status django_03
journalctl -u django_03
Verify that HTTP socket is listening
netstat -ntap | grep 8003
Verify HTTP response:
curl http://127.0.0.1:8003
Note that by default uwsgi operates with its default transfert protocol which is NOT HTTP. It is not recommended to use uwsgi HTTP socket, the best setup being the use of uswgi default protocol and a reverse proxy in front of it (NGINX, Apache HTTPd). Of course code presented here is far from perfect and might be optimized and tailored to your needs.

Serving flask application with Nginx and gunicorn: permission denied when connecting to webpage.sock

I am trying to setup a simple flask application served by Nginx and Gunicorn and have mostly followed this tutorial. When trying to access the webpage, I get a 502 Bad Gateway error.
The nginx log (/var/log/nginx/error.log) says :
[crit] 23472#0: *1 connect() to unix:/home/crawforc3/webpage/webpage.sock failed (13: Permission denied)
I checked and there is a webpage.sock file in my project directory that looks like this:
srwxrwxrwx 1 crawforc3 www-data 0 May 31 17:59 webpage.sock
Here is my /etc/systemd/system/gunicorn.service
[Unit]
Description=gunicorn daemon
After=network.target
[Service]
User=crawforc3
Group=www-data
WorkingDirectory=/home/crawforc3/webpage
Environment="PATH=home/crawforc3/miniconda3/envs/HALSWEBPAGE/bin"
ExecStart=/home/crawforc3/miniconda3/envs/HALSWEBPAGE/bin/gunicorn --workers 3 --bind unix:/home/crawforc3/webpage/webpage.sock -m 007 wsgi:app
[Install]
WantedBy=multi-user.target
I discovered that there was a discrepancy with /etc/nginx/nginx.conf
I had the user set as www-data and I should have set it as crawforc3. Making this change and restarting nginx and gunicorn resolved the issue.

sock file is missing in running django app with nginx and gunicorn

I was following this tutorial and successfully ran the project manually. However, after setting up nginx and systemd, it says 502 Bad Gateway.
I have looked through other similar threads to no avail.
I see that my gunicorn workers are running by doing ps -ax | grep gunicorn.
my nginx configuration:
server {
listen 8000;
server_name 127.0.0.1;
location = /favicon.ico { access_log off; log_not_found off; }
location /static/ {
root /home/ubuntu/myproject;
}
location / {
include proxy_params;
proxy_pass http://unix:/home/ubuntu/myproject/myproject.sock;
}
}
and the systemd file:
[Unit]
Description=gunicorn daemon
After=network.target
[Service]
User=ubuntu
Group=www-data
WorkingDirectory=/home/ubuntu/myproject
ExecStart=/home/ubuntu/myproject/myprojectenv/bin/gunicorn --workers 3 --bind unix:/home/ubuntu/myproject/myproject.sock myproject.wsgi:application
[Install]
WantedBy=multi-user.target
The contents of /var/log/nginx/error.log:
2017/02/18 17:57:51 [crit] 1977#1977: *6 connect() to unix:/home/ubuntu/myproject/myproject.sock failed (2: No such file or directory) while connecting to upstream, client: 10.0.2.2, server: 172.30.1.5, request: "GET / HTTP/1.1", upstream: "http://unix:/home/ubuntu/myproject/myproject.sock:/", host: "localhost:8000"
Manually running /home/ubuntu/myproject/myprojectenv/bin/gunicorn --workers 3 --bind unix:/home/ubuntu/myproject/myproject.sock myproject.wsgi:application is also working. That is, sock file is created.
I feel like I missing something very simple.
What could I be doing wrong?
There could be an ordering thing here - nginx is probably starting before gunicorn, so the socket is not yet there to connect. You should add gunicorn.service to the After directive in the nginx systemd file.

Gunicorn + Nginx Internal server error while trying to apply code changes

I set up a VPS (django + gunicorn + nginx ) and it was working fine showing default django screen, but after I updated my django code and made all migrations I thought that now I need to restart gunicorn to apply changes.
So I did this:
sudo systemctl restart gunicorn
After this I've got Internal Server Error
Everything is set up like here
gunicorn.service :
[Unit]
Description=gunicorn daemon
After=network.targett
[Service]
User=thekotik
Group=www-data
WorkingDirectory=/home/thekotik/glboy
ExecStart=/home/thekotik/glboy/denv/bin/gunicorn --workers 3 --bind unix:/home/thekotik/glboy/closer.sock closer.wsgi:application
[Install]
WantedBy=multi-user.target
<class 'socket.error'>, [Errno 13] Permission denied: file: /usr/lib/python2.7/socket.py line: 228
unix socket files holds the same case unix file permissions; the file ( /home/thekotik/glboy/closer.sock) is currently being used or not owned by gunicorn process user that causes error 13.
I recommend using the TCP option --bind 127.0.0.1:8000.For tcp based changes,
gunicorn.service
[Unit]
Description=gunicorn daemon
After=network.targett
[Service]
User=thekotik
Group=www-data
WorkingDirectory=/home/thekotik/glboy
ExecStart=/home/thekotik/glboy/denv/bin/gunicorn --workers 3 --bind 127.0.0.1:9090 closer.wsgi:application
[Install]
WantedBy=multi-user.target
use above systemd service file for gunicorn & change the proxy option in nginx to
proxy_pass http://127.0.0.1:9090$request_uri;
that will avoid unix socket file based permission problems.

Categories

Resources