I have a small, test FastAPI web application that is serving a simple HTML page that requires a css style sheet located in the static folder. It is installed on a Linode server (Ubuntu 20.04 LTS), nginx, gunicorn, uvicorn workers, and supervisorctl. I have added a certificate using certbot.
The application works fine in http but does not access the static files in https. When accessed in http all static-based features work but when accessed with https it lacks all styling from css stylesheet. I need to get this working so I can load a much more complex app that needs css and other static folder-stored features.
The file structure is:
/home/<user_name>/application- main.py- static |_ css |_ bootstrap- templates |_ index.html
main.py:
import fastapiimport uvicornfrom fastapi import Requestfrom fastapi.responses import HTMLResponsefrom fastapi.staticfiles import StaticFilesfrom fastapi.templating import Jinja2Templatesapi = fastapi.FastAPI()api.mount('/static', StaticFiles(directory='static'), name='static')templates = Jinja2Templates(directory="templates")@api.get('/')@api.get('/index', response_class=HTMLResponse)def index(request: Request): message = None return templates.TemplateResponse("index.html", {"request": request,'message': message})if __name__ == '__main__': uvicorn.run(api, port=8000, host='127.0.0.1')
nginx is at /etc/nginx/sites-enabled/<my_url>.nginx
server { listen 80; server_name www.<my_url>.com <my_url>.com; server_tokens off; charset utf-8; location / { try_files $uri @yourapplication; } location /static { gzip on; gzip_buffers 8 256k; alias /home/<user_name>/application/static; expires 365d; } location @yourapplication { gzip on; gzip_buffers 8 256k; proxy_pass http://127.0.0.1:8000; proxy_set_header Host $host; proxy_set_header X-Real-IP $remote_addr; proxy_set_header X-Forwarded-Protocol $scheme; } }server { listen 443 ssl; server_name www.<my_url>.com; ssl_certificate /etc/letsencrypt/live/<my_url>.com/fullchain.pem; # mana> ssl_certificate_key /etc/letsencrypt/live/<my_url>.com/privkey.pem; # ma> include /etc/letsencrypt/options-ssl-nginx.conf; # managed by Certbot ssl_dhparam /etc/letsencrypt/ssl-dhparams.pem; # managed by Certbot location / { try_files $uri @yourapplication; } location /static { gzip on; gzip_buffers 8 256k; alias /home/<user_name>/application/static; expires 365d; } location @yourapplication { gzip on; gzip_buffers 8 256k; proxy_pass http://127.0.0.1:8000; proxy_set_header Host $host; proxy_set_header X-Real-IP $remote_addr; proxy_set_header X-Forwarded-Protocol $scheme; }}
and am serving using supervisor script:
[program:api]directory=/home/<user_name>/applicationcommand=gunicorn -b 127.0.0.1:8000 -w 4 -k uvicorn.workers.UvicornWorker main:apienvironmentenvironment=PYTHONPATH=1autostart=trueautorestart=truestopasgroup=truekillasgroup=truestderr_logfile=/var/log/app/app.err.logstdout_logfile=/var/log/app/app.out.log
The css stylesheet is called in the html using url_for like this:
<link href="{{ url_for('static', path='/css/ATB_style.css') }}" rel="stylesheet">
I have tried a whole host of modifications to the location /static block in nginx including:
- adding slash after static in either line or both
- trying to add https://static or https://www.<my_url>.com/home/<my_url>/application/static
- adding and removing the location static from the http and https lines
- changing proxy_pass to https://127.0.0.1:8000;
- added root /home/<user_name>/application to the server section
I have loaded this server twice, once letting certbot modify the nginx file the second, and current configuration, where I did it manually. I am at a complete loss on what to do.