Static files cant see flask server - nginx

I am new to Nginx and I currently trying to deploy my web app on my server.
I have static files (built from react) being served by Nginx. The static files make calls to port 5000, my flask server. When testing, flask cannot receive any calls from my static files.
The (static-flask) setup runs on my local machine, so I am assuming that there is a problem with my config with Nginx.
Here is my Nginx setup (in sites-enabled):
server {
listen 80;
server_name MY_IP_ADDRESS;
location / {
root MY_LOCATION_TO_STATIC_FILES;
index index.html;
try_files $uri /index.html;
}
}
I am guessing that once Nginx serves the static files, the client (static files) make calls to localhost:5000, but does not refer to port 5000 on my server?
How would I serve the static files such that they can refer to the server's localhost:5000?
Edit
I guess I should be more specific with my project. I want to serve my static files when the user hits www.mydomain.com, and when the user interacts with the website, they make calls to a flask server running on port 5000 on my server.
I could consider serving static files from flask, but that would be highly inefficient.

Use nginx proxy:
location / {
proxy_set_header Host $host;
proxy_set_header X-Real-IP $remote_addr;
proxy_pass http://localhost:5000;
}

Try this
server {
server_name www.yourdomain.com;
location /static {
alias /home/user/path/static;
}
location / {
proxy_pass http://localhost:8000;
include /etc/nginx/proxy_params;
proxy_redirect off;
}
}
Change alias to your path project

Related

nginx not finding css file

I have just put my flask app on ubuntu. I am using gunicorn and nginx. The app is loading and nginx can find the templates. However the CSS files are not being served. If I enter the URL to access the CSS file in the browser I get a 403.
Here is my config file
server {
listen 80;
server_name myip;
location /static {
alias /home/ubuntu/enrich/website/static;
}
location / {
proxy_pass http://localhost:8000;
include /etc/nginx/proxy_params;
proxy_redirect off;
}
}
Any idea where I am going wrong?
Thx
S

Nginx multiple Apps on same port reverse proxy

I'm trying to run a django app and and angular one on my VPS using Nginx. Below is my config file code:
server {
listen 80;
server_name www.the-patron.com the-patron.com;
charset utf-8;
location = /favicon.ico { access_log off; log_not_found off; }
location /staticfiles/ {
root /root/thepatron/The-Patron-Backend;
}
# Django Backend
location /back/ {
include proxy_params;
proxy_pass http://unix:/root/thepatron/The-Patron-Backend/thepatron.sock;
}
# Angular Frontend
location / {
proxy_pass http://localhost:4200/;
proxy_set_header Upgrade $http_upgrade;
proxy_set_header Connection 'upgrade';
proxy_set_header Host $host;
proxy_http_version 1.1;
proxy_cache_bypass $http_upgrade;
}
}
Here my Angular app is running well and the Django one isn't. If I change location /backend/ to location / on line 12 and location / to location /frontend/ on line 18 then I will get the Django app to run while the Angular app will not.
How can I run both and change the location of each?
As my previous approach to host my Angular and Django apps separately was totally wrong. I finally managed to solve my issue thanks to the comments of #Vipulw above.
What worked for me is that I built my Angular application to production and placed the generated build folder inside my static files folder in my Django app directory, and then configured my Nginx to serve that Angular build.
Below is my new Nginx config file:
# Angular Reverse Proxy
server {
listen 80;
server_name <Domain name or IP address>;
root /root/<path to Django app>/static/<Angular app build folder>;
index index.html;
location / {
try_files $uri $uri/ /index.html;
}
}
# Django Reverse Proxy
server {
listen 8080;
server_name <Domain name or IP address>;
location / {
include proxy_params;
proxy_pass http://unix:/root/<path to Django app>/<myapp>.sock;
}
}
Additional Note:
In this way mentioned above, my Angular app is running on port 80 while my Django app is running on port 8080. Everything is working fine this way but I don't see that as the best way to do run both Angular and Django. After a little bit of research, I found that the best way to serve Angular and Django in one app is to let the default Django route to point to the Angular build. The default Django route right now is pointing to the Django Rest Framework root directory.
Sadly, I don't know how to let Django's default route to point to the Angular build file at the moment.

How to host a Flask app on a subfolder / URL prefix with Nginx?

I have a flask app which I want to host it on a subfolder of a website, like example.com/cn.
I configured my nginx like
location /cn {
proxy_pass http://localhost:8000/;
}
So if I access example.com/cn, It will redirect to the index page of flask.
However, I have wrote the routes of other pages on flask like app.route('/a'). So if I click the link of page a, the URI is example.com/a, then nginx cannot redirect it to the right ​page.
​I think I can rewrite all the routes on flask like app.route('/cn/a'), but it's complex. And if someday I want to deploy it on example.com/en, I think I need to rewrite all the routes again.
Does anyone have other methods?
You need to add APPLICATION_ROOT params to your flask app:
from flask import Flask, url_for
from werkzeug.serving import run_simple
from werkzeug.wsgi import DispatcherMiddleware
app = Flask(__name__)
app.config['APPLICATION_ROOT'] = '/cn'
if you need to host more than one application on your server, you can configure nginx to redirect all request to your specific flask app served by gunicorn like this. (it is not necessary if your server hosts only one application) Find out more about gunicorn and nginx here: https://docs.gunicorn.org/en/stable/deploy.html
server {
listen 8000;
server_name example.com;
proxy_intercept_errors on;
fastcgi_intercept_errors on;
location / {
include proxy_params;
proxy_pass http://unix:/path_to_example_flask_app_1/app.sock;
}
location /cn/{
include proxy_params;
proxy_pass http://unix:/path_to_example_flask_app_cn/app.sock;
}
}
serve flask app with gunicorn:
A complete exmaple here: https://www.digitalocean.com/community/tutorials/how-to-serve-flask-applications-with-gunicorn-and-nginx-on-ubuntu-18-04
#move into project directory
/path_to_gunicorn/gunicorn --workers 3 --bind unix:app.sock -m 007 run:app
If you are using flask_restful instead, you can specify the root path also in the following way:
from flask import Flask
from flask_restful import Api
app = Flask(__name__)
app.debug = False
api = Api(app, prefix='/cn')
api.add_resource(ResourceClass, '/example_path') #will be served when the resource is requested at path /cn/example_path
if __name__ == '__main__':
app.run(host="0.0.0.0", port=8000)
I have found a perfect solution here.
You can use url_prefix="/cn" option when defining blueprints:
https://flask.palletsprojects.com/en/2.0.x/blueprints/#nesting-blueprints
Suppose you want to host your application under /api with Nginx.
First, config your URL prefix to location and X-Forwarded-Prefix header:
server {
listen 80;
server_name _;
location /api {
proxy_pass http://127.0.0.1:5000/;
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
proxy_set_header X-Forwarded-Proto $scheme;
proxy_set_header X-Forwarded-Host $host;
proxy_set_header X-Forwarded-Prefix /api;
}
}
Then use Werkzeug's ProxyFix middleware to tell Flask it's behind a proxy:
from werkzeug.middleware.proxy_fix import ProxyFix
from flask import Flask
app = Flask(__name__)
app.wsgi_app = ProxyFix(
app.wsgi_app, x_for=1, x_proto=1, x_host=1, x_prefix=1
)
See also:
Deploying with Nginx
Tell Flask it is Behind a Proxy
P.S. If you are using OpenAPI, also remember to update the servers field to indicate the location of the server.

Nginx won't serve static files

I followed this tutorial to deploy my Django project on DigitalOcean. I've installed Nginx and Supervisor and all worked until I set DEBUG option in the settings.py to False
I tried to configure nginx.conf and settings.py million times. Changing root to alias wouldn't help.
Nginx configuration file:
upstream app_server {
server unix:/home/db1/run/gunicorn.sock fail_timeout=0;
}
server {
listen 80;
# add here the ip address of your server
# or a domain pointing to that ip (like example.com or www.example.com)
server_name ...;
keepalive_timeout 5;
client_max_body_size 4G;
access_log /home/db1/logs/nginx-access.log;
error_log /home/db1/logs/nginx-error.log;
location /static/ {
root /home/db1/site1/static;
}
# checks for static file, if not found proxy to app
location / {
try_files $uri #proxy_to_app;
}
location #proxy_to_app {
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
proxy_set_header Host $http_host;
proxy_redirect off;
proxy_pass http://app_server;
}
}
Settings.py
STATIC_URL = '/static/'
STATIC_ROOT = os.path.join(BASE_DIR, 'static/')
It's quite tricky, just use one of those two lines according to status of DEBUG
STATIC_ROOT = os.path.join(BASE_DIR, 'static/') #Production
STATICFILES_DIRS = (os.path.join(BASE_DIR, 'static/'), ) #Development
Here is a few steps that helped me in solving this problem. Don't know exactly which one is an actual solution)
Changing the owner of static folders to a recently created user (a newly created user for new project like in tutorial)
Connection to the server via IP address only (without PORT)
Still, I don't get it why adding a PORT will cause static files to be held at server

NGINX Not Loading Resources for Second Server

I'm new to NGINX (well hosting in general), so please excuse my ignorance. I have a Phoenix web app running on localhost:4000 and an ASP.NET web app running on localhost:5123. I'm trying to utilize NGINX to create a reverse proxy so that either web app can be accessed from the same domain. My NGINX config file contains the following:
server {
listen 80;
server_name example.com;
location / {
proxy_pass http://localhost:4000;
}
location /test {
rewrite /test(.*) /$1 break;
proxy_pass http://localhost:5123;
}
}
I'm able to access server 1 on example.com/ and server 2 on example.com/test, however, server 2 is not able to load its own css, javascript and image files. Is there a way to ensure server 1 and server 2 utilize their own resources via the NGINX config setup?
You are on the right way. There are some lines missing on your second service:
Replace...
location /test {
rewrite /test(.*) /$1 break;
proxy_pass http://localhost:5123;
}
with...
location /test {
rewrite /test/(.*) /$1 break;
rewrite ^/test$ /test/ permanent;
proxy_pass http://localhost:5123/;
proxy_redirect / /test/;
proxy_set_header Host $host;
proxy_buffering off;
}
I don't know if this is the best way to achieve this. Long time ago I used this configuration to implement an etherpad-service on my server. That time I had not the option to use a subdomain. Anyway - using a subdomain for your second service would be better.

Resources