Issues getting nginx to serve my flask app - python

The bounty expires in 4 days. Answers to this question are eligible for a +350 reputation bounty.
dms_quant wants to draw more attention to this question.
I have a flask app that I would like to serve via a DO Droplet.
I have followed How To Serve Flask Applications with Gunicorn and Nginx on Ubuntu 22.04
This is my folder structure
root/
└── baseweb/
├── venv
├── app.py
└── app/
├── routes.py
└── templates/
└── index.html
app.py looks like this
from app import app
if __name__ == "__main__":
app.run(host='0.0.0.0', debug=True)
I have created a baseweb service
[Unit]
Description=Gunicorn instance to serve myproject
After=network.target
[Service]
User=root
Group=www-data
WorkingDirectory=/root/baseweb
Environment="PATH=/root/baseweb/venv/bin"
ExecStart=/root/baseweb/venv/bin/gunicorn --workers 1 --bind unix:baseweb.sock app:app
[Install]
WantedBy=multi-user.target
and my nginx configuration (/etc/nginx/sites-available/baseweb) - edited per arthur simas comment below
server {
listen 80;
server_name baserank.net www.baserank.net;
location / {
proxy_pass http://unix:/root/baseweb/baseweb.sock;
}
}
When i simply run app.py using my venv, i can access my flask app via http://68.183.68.148:5000/
if I run gunicorn --bind 0.0.0.0:5000 app:app i can also access my app via the same IP.
But when i try to access via nginx (via http://68.183.68.148 without running the app in console), i get
502 Bad Gateway
nginx/1.22.0 (Ubuntu)
I have spent hours trying to adjust settings, but i have no idea where this is going wrong - so any help is very much appreciated.
Edit 2023-02-17: Ngnix access.log
185.16.141.5 - - [17/Feb/2023:14:14:17 +0000] "GET / HTTP/1.1" 502 568 "http://baserank.net/" "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/108.0.0.0 Safari/537.36"
185.16.141.5 - - [17/Feb/2023:14:14:17 +0000] "GET / HTTP/1.1" 502 568 "http://baserank.net/" "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/108.0.0.0 Safari/537.36"
185.16.141.5 - - [17/Feb/2023:14:14:20 +0000] "GET / HTTP/1.1" 502 568 "http://baserank.net/" "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/108.0.0.0 Safari/537.36"
185.16.141.5 - - [17/Feb/2023:14:14:20 +0000] "GET / HTTP/1.1" 502 568 "http://baserank.net/" "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/108.0.0.0 Safari/537.36"
143.110.222.166 - - [17/Feb/2023:14:22:21 +0000] "GET / HTTP/1.1" 502 166 "-" "Mozilla/5.0 (iPhone; CPU iPhone OS 16_1 like Mac OS X) AppleWebKit/605.1.15 (KHTML, like Gecko) Version/16.1 Mobile/15E148 Safari/604.1"

your ngnix config is wrong. you don't use root directive for reverse proxying with nginx, but instead proxy_pass. the tutorial you've posted is right. the changes you should do:
server {
listen 80;
server_name your_domain www.your_domain; # place here your website domain (optional directive)
location / {
proxy_pass http://unix:/root/baseweb/baseweb.sock;
}
}
listen tells were the nginx server should listen to requests. it could be only the port (80), ip:port (68.183.68.148:80), an unix socket (unix:/var/run/nginx.sock), etc...
the proxy_pass directive acts as a reverse proxy, forwarding traffic to the provided URL.
root is for serving static files.
read more at:
NGINX Module ngx_http_core_module - listen
NGINX Reverse Proxy
NGINX Module ngx_http_proxy_module - proxy_pass
Serving Static Content
also, be sure to create the service in systemd, at the correct path location and check if its running sudo systemctl status myproject (or nginx would not be able to forward traffic to it)

One potential issue could be with the ownership and permission of the socket file /root/baseweb/baseweb.sock. Make sure the user running the Gunicorn service (in your case, root) has ownership of the file, and the permissions are set correctly. You can try changing the group to root in the baseweb.service file:
[Service]
User=root
Group=root
WorkingDirectory=/root/baseweb
Environment="PATH=/root/baseweb/venv/bin"
ExecStart=/root/baseweb/venv/bin/gunicorn --workers 1 --bind unix:baseweb.sock app:app
After modifying the service file, make sure to reload the daemon and restart the service:
sudo systemctl daemon-reload
sudo systemctl restart baseweb
You can also check the error log of Gunicorn by adding --log-level debug --error-logfile /path/to/error.log to the Gunicorn command in the baseweb.service file. Then, check the content of /path/to/error.log for more details about the error.
Another thing to try is to update the Nginx configuration to proxy pass to http://127.0.0.1:5000 instead of the socket file. You can try modifying the configuration file as follows:
server {
listen 80;
server_name baserank.net www.baserank.net;
location / {
proxy_pass http://127.0.0.1:5000;
proxy_set_header Host $host;
proxy_set_header X-Real-IP $remote_addr;
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
}
}
After modifying the configuration file, restart the Nginx service:
sudo systemctl restart nginx

Related

Static files not loading using nginx and docker

I'm having approximately the same error as in this question, as concerning Django, all my pages are loaded correctly but not my static files. I guess it has something to do with an error in my configuration files, however even though I've been searching for quite some time, I couldn't find anything to solve my problem.
Here is my Django Dockerfile :
FROM python:3.10.5-alpine
RUN pip install --upgrade pip
RUN wget https://upload.wikimedia.org/wikipedia/commons/b/b9/First-google-logo.gif -O media/media.gif
COPY ./requirements.txt .
RUN pip install -r requirements.txt
COPY ./src /app
WORKDIR /app
COPY ./entrypoint.sh /
ENTRYPOINT ["sh", "/entrypoint.sh"]
nginx.conf
upstream django {
server django_gunicorn:8000;
}
server {
listen 80;
server_name 127.0.0.1;
location / {
proxy_pass http://django;
}
location /static/ {
alias /static/;
}
location /media/ {
alias /media/;
}
}
nginx Dockerfile
FROM nginx:1.19.0-alpine
COPY ./nginx.conf /etc/nginx/conf.d/nginx.conf
docker-compose.yml
version: '3.7'
services:
django_gunicorn:
volumes:
- static:/static
- media:/media
env_file:
- env
build:
context: .
ports:
- "8000:8000"
nginx:
build: ./nginx
volumes:
- static:/static
- media:/media
ports:
- "80:80"
depends_on:
- django_gunicorn
volumes:
static:
media:
And I get errors like that :
testapp-django_gunicorn-1 |
testapp-django_gunicorn-1 | 9771 static files copied to '/app/static'.
testapp-django_gunicorn-1 | [2022-07-21 12:27:36 +0000] [9] [INFO] Starting gunicorn 20.1.0
testapp-django_gunicorn-1 | [2022-07-21 12:27:36 +0000] [9] [INFO] Listening at: http://0.0.0.0:8000 (9)
testapp-django_gunicorn-1 | [2022-07-21 12:27:36 +0000] [9] [INFO] Using worker: sync
testapp-django_gunicorn-1 | [2022-07-21 12:27:36 +0000] [10] [INFO] Booting worker with pid: 10
testapp-nginx-1 | 172.20.0.1 - - [21/Jul/2022:12:30:45 +0000] "GET /scripts/ HTTP/1.1" 200 17460 "http://127.0.0.1/scripts/" "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/103.0.0.0 Safari/537.36" "-"
testapp-nginx-1 | 172.20.0.1 - - [21/Jul/2022:12:30:45 +0000] "GET /static/scripts/bootstrap/css/bootstrap.css HTTP/1.1" 404 555 "http://127.0.0.1/scripts/" "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/103.0.0.0 Safari/537.36" "-"
testapp-nginx-1 | 2022/07/21 12:30:45 [error] 30#30: *1 open() "/static/scripts/bootstrap/css/bootstrap.css" failed (2: No such file or directory), client: 172.20.0.1, server: 127.0.0.1, request: "GET /static/scripts/bootstrap/css/bootstrap.css HTTP/1.1", host: "127.0.0.1", referrer: "http://127.0.0.1/scripts/"
EDIT : entrypoint.sh
#!/bin/sh
python manage.py migrate
python manage.py collectstatic
gunicorn main.wsgi:application --bind 0.0.0.0:8000
Your nginx container is looking for static in /static/ but the logs show you're collecting static in /app/static/ in the gunicorn container. In docker-compose, did you try - static:/app/static on the gunicorn side and - static:/static on the nginx side?

Aiohttp and NGINX running in Docker

Long story short
I would like to run aiohttp backend services on a nginx webserver. Both should be running in docker containers. Furthermore my frontend angular application should access my backend services.
Expected behaviour
I expect that the nginx webserver could connect to my backend system aiohttp, running in docker.
Actual behaviour
I am always getting an error in the docker logs while I am trying to call a GET request on my aiohttp backend service.
nginx_1 | 2018/09/29 13:48:03 [error] 6#6: *1 connect() failed (111: Connection refused) while connecting to upstream, client: 172.19.0.1, server: , request: "GET /toolservice/volatility?command=pslist HTTP/1.1", upstream: "http://172.19.0.2:80/toolservice/volatility?command=pslist", host: "localhost"
nginx_1 | 172.19.0.1 - - [29/Sep/2018:13:48:03 +0000] "GET /toolservice/volatility?command=pslist HTTP/1.1" 502 576 "-" "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/69.0.3497.100 Safari/537.36" "-"
Docker-compose.yml
version: '3'
services:
nginx:
build: ./nginx
restart: always
depends_on:
- toolservice
- ifs
ports:
- "80:80"
ifs:
restart: always
build: ../ifsbackend
ports:
- "8002:8000"
toolservice:
restart: always
build: ../ToolService
ports:
- "8001:8000"
Dockerfile nginx webserver
FROM nginx:1.13-alpine
RUN rm /etc/nginx/conf.d/default.conf
COPY conf/server.conf /etc/nginx/conf.d/
Dockerfile aiohttp backend
FROM python:3.6.6-alpine
COPY tool /
COPY requirements.txt /
COPY toolservice_config.yaml /
RUN apk update && apk add \
python3-dev \
musl-dev \
gcc \
&& pip install -r requirements.txt \
&& pip install virtualenv
RUN python3 -m virtualenv --python=python3 virtualenv
EXPOSE 8080
CMD [ "python", "server.py" ]
Nginx webserver config
#upstream toolservice {
# server 0.0.0.0:8001 fail_timeout=0;
#}
server {
listen 80;
#server_name localhost;
proxy_buffers 8 16k;
proxy_buffer_size 32k;
location /toolservice {
proxy_pass http://toolservice;
proxy_redirect default;
proxy_set_header Host $host;
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
}
location /ifs {
proxy_pass http://ifs;
proxy_redirect default;
proxy_set_header Host $host;
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
}
}
Aiohttp toolservice backend
from aiohttp import web
from routes import setup_routes
from settings import config
app = web.Application()
setup_routes(app)
app['config'] = config
web.run_app(app, port=8001)
Aiohttp is running on the port 8001 in the container toolservice, but your proxying to the port 80.
proxy_pass http://toolservice;
Try proxying to 8001:
proxy_pass http://toolservice:8001;
Maybe you will need to fix publishing of the port for toolservice container - I'm not 100% sure:
ports:
- "8001:8001"

Deploying a Flask application using cgi script in Xampp

I am attempting to deploy a simple Hello World script on XAMMP.
In case the link is removed here is application.py:
from flask import Flask
app = Flask(__name__)
#app.route("/")
def hello():
return "Hello World!"
My applciation.cgi script is as follows:
#!C:/Users/Simon/Documents/Python/Scripts/python.exe
from wsgiref.handlers import CGIHandler
from application import hello
CGIHandler().run(app)
C:/Users/Simon/Documents/Python/ is the location of my virtual python environment.
I have configured XAMMP (httpd.conf) in the following way:
AddHandler cgi-script .py
ScriptInterpreterSource Registry-Strict
This configuration I kept in all cases.
I tried the following as suggested in the documentation:
ScriptAlias /Network C:/Users/Simon/Documents/Network/application.cgi
This failed and I tried this as suggested in here:
<Directory "C:/Users/Simon/Documents/Network">
Options Indexes FollowSymLinks MultiViews
AllowOverride All
Require all granted
</Directory>
Alias /Network "C:/Users/Simon/Documents/Network"
In all cases an Error 500 Server error! was returned.
I'm not sure if it's needed but here is the relevant error showing in access.log:
192.168.0.8 - - [17/Feb/2018:13:21:12 +0000] "GET / HTTP/1.1" 500 1100 "-" "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/64.0.3282.167 Safari/537.36"
If anything is missing please tell me and I will add it.
How can I correctly configure my server so that I can run this script?
There was mistake in application.cgi:
#!C:/Users/Simon/Documents/Python/Scripts/python.exe
from wsgiref.handlers import CGIHandler
from application import hello
CGIHandler().run(hello)
It is however still returning an error:
A server error occurred. Please contact the administrator.
You've imported the wrong thing in your CGI script; as a result app is not defined. You should be importing that rather than hello.

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.

flask app won't run on ubuntu 12.04 (digital ocean)

I am having difficulties deploying a basic flask app on a digital ocean server running ubuntu 12.04, apache2, and mod-wsgi. I have tried a number of different modifications of both the myapp.conf file and the myapp.wsgi file. I suspected that these were the culprits, but now I'm not so sure.
At all times, visiting my url just displays the apache 'It works' dialogue. Each attempt made to successfully restart the apache service (after trying to fix the problem), and access the website sees this same activity in the error.log:
[Wed Aug 27 00:49:14 2014] [notice] caught SIGTERM, shutting down
[Wed Aug 27 00:49:15 2014] [notice] Apache/2.2.22 (Ubuntu) mod_wsgi/3.3 Python/2.7.3 configured -- resuming normal operations
And this activity in the access.log:
11.22.33.44 - - [27/Aug/2014:00:49:19 -0400] "GET / HTTP/1.1" 304 209 "-" "Mozilla/5.0 (Windows NT 6.1; WOW64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/36.0.1985.143 Safari/537.36"
11.22.33.44 - - [27/Aug/2014:00:49:21 -0400] "GET / HTTP/1.1" 304 208 "-" "Mozilla/5.0 (Windows NT 6.1; WOW64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/36.0.1985.143 Safari/537.36"
11.22.33.44 - - [27/Aug/2014:00:49:24 -0400] "GET / HTTP/1.1" 304 208 "-" "Mozilla/5.0 (Windows NT 6.1; WOW64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/36.0.1985.143 Safari/537.36"
By 'basic' flask app, I mean: no sql database (as in none, not as in non-relational), no site users, no factory, no blueprint, etc.
The relevant directory /var/www/myapp/ looks like this (using virtualenv to run the app):
myapp/
+ myapp/
| + static/
| + templates/
| + venv/
| | __init__.py
| myapp.wsgi
Although I have tried several versions of the myapp.conf file, these two are representative:
<VirtualHost *:80>
ServerName myapp.com
WSGIDaemonProcess myapp user=flask group=www-data home=/var/www/myapp/
WSGIScriptAlias / /var/www/myapp/myapp.wsgi
<Directory /var/www/myapp/myapp/>
WSGIProcessGroup myapp
WSGIApplicationGroup % {GLOBAL}
WSGIScriptReloading On
Order allow,deny
Allow from all
</Directory>
ErrorLog ${APACHE_LOG_DIR}/error.log
LogLevel warn
CustomLog ${APACHE_LOG_DIR}/access.log combined
</VirtualHost>
And:
<VirtualHost *:80>
ServerName myapp.com
WSGIScriptAlias / /var/www/myapp/myapp.wsgi
<Directory /var/www/myapp/myapp/>
Order allow,deny
Allow from all
</Directory>
Alias /static /var/www/myapp/myapp/static
<Directory /var/www/myapp/myapp/static/>
Order allow,deny
Allow from all
</Directory>
ErrorLog ${APACHE_LOG_DIR}/error.log
LogLevel warn
CustomLog ${APACHE_LOG_DIR}/access.log combined
</VirtualHost>
The two general types of myapp.wsgi files I have tried are:
#!/usr/bin/python
import sys
import logging
logging.basicConfig(stream=sys.stderr)
sys.path.insert(0,"/var/www/myapp/")
from myapp import app as application
And:
activate_this = '/var/www/myapp/myapp/venv/bin/activate_this.py'
execfile(activate_this, dict(__file__=activate_this))
import os
import sys
import logging
logging.basicConfig(stream=sys.stderr)
sys.path.insert(0, '/var/www/myapp/')
from myapp import app as application
#commenting out same in __init__.py
if __name__ == '__main__':
application.run()
The app does run successfully on my local machine, and I always chowned the /var/www/ directory for each user identified in the .conf file.
Any thoughts, tips, pointers, etc are extraordinarily welcome. Thanks very kindly.

Categories

Resources