How to serve static asset files with Flask and NGINX
For a web app that’s using a flask reverse proxy with NGINX and gunicorn:
The problem I'm having is when I try to serve static asset files (css, and javascript), I get error messages in the browser’s console when the index.html is loaded. The server/browser is able to find and serve these css and .js files but the styling is not applied to the page and the javascript files error out, something goes wrong when the server sends the response to the browser.
The error messages I'm currently getting are: " Uncaught SyntaxError: Unexpected token '<' ". These errors are given for all the javascript files I try to use by calling them in the script tags inside of index.html.
Also, for each of the css files called by link tags , I get a warning in the browser’s console that says: “Resource interpreted as Stylesheet but transferred with MIME type text/html: “<url>” ”When I check the network tab of the browser, for each served css and .js file, the response header indicates that it’s Content-Type is text/html (when it should be “application/javascript” for the .js files and “text/css” for the css files, which is what i set their types to in their link and script tags. ) </url>
How can I fix this, since these asset files are located in the server’s directory system like so: domain.com/static/assets
The nginx configuration to access these files seems to be working, but when ensuring they get sent and handled with the correct specifications (content-type , mime-type) something goes wrong.
Any help is very much appreciated.
Thank you in advance.
3 Replies
The nginx config is:
user root;
worker_processes auto;
error_log /var/log/nginx/error.log warn;
pid /var/run/nginx.pid;
events {
worker_connections 1024; # increase if you have lots of clients
accept_mutex off; # set to 'on' if nginx worker_processes > 1
}
http {
#include mime.types;
include /etc/nginx/mime.types;
#default_type application/octet-stream;
access_log /var/log/nginx/access.log combined;
sendfile on;
server {
listen 443 default_server ssl;
listen 80;
index index.html;
server_name jobsdecoder.com;
charset utf-8;
ssl_certificate /etc/nginx/certs/jobsdecoder.com/35bdf9be78f9b6d8.crt;
ssl_certificate_key /etc/nginx/certs/generated-private-key.key;
charset_types text/css application/javascript text/javascript *;
location / {
#root ~/ubuntu/FrontEnd/build;
#alias ~/ubuntu/FrontEnd/build;
include proxy_params;
#include /etc/nginx/mime.types;
proxy_pass http://50.116.17.59:5006;
types{
text/css css;
application/javascript js;
#text/javascript js;
image/x-icon ico;
}
}
location = / {
include /etc/nginx/mime.types;
root ~/ubuntu/landingpage/jobfinderportal_master_New;
include proxy_params;
proxy_pass http://127.0.0.3:5007;
types {
text/css css;
application/javascript js;
#text/javascript js;
#stylesheet css;
}
}
location /static/ {
root ~/ubuntu/landingpage/jobfinderportal_master_New/;
types {
text/css css;
application/javascript js;
#text/javascript js;
#stylesheet text/css;
}
add_header Content-Type text/css;
add_header Content-Type application/javascript;
}
location /searchjobs {
root ~/ubuntu/landingpage/jobfinderportal_master_New/templates;
include proxy_params;
proxy_pass http://111.0.0.2:6000;
}
location /jobs {
include proxy_params;
proxy_pass http://111.0.0.2:6000;
}
}
}
I am not sure, but I feel like you are manipulating the mime types a lot.
I have created one example project that shows how you could do it. Furthermore, I actually didn't put any mime type specific configuration. It is pretty much out of the box. https://github.com/bluebrown/flaskginx
The gist is the below with leaving the HTTP block default. Only a custom server block.
server {
listen 80;
server_name localhost;
# proxy to flask
location / {
proxy_pass http://flask:5000;
}
# note that I put the actual files in
# /usr/share/nginx/html/static/
# as this is how the path combined looks like
location /static/ {
root /usr/share/nginx/html;
}
}