How to deploy FastAPI with Nginx and Supervisor
In this tutorial, I will show you how to deploy a FastAPI app with Nginx and Supervisor.
First, launch a compute instance with a cloud platform of your choice. I will be using Ubuntu version 20.04 along with the default python version 3.8 and default ubuntu user.
Update packages.
sudo apt-get update
Install pip, venv, and nginx.
sudo apt-get -y install python3-pip python3-venv nginx supervisor
If you go to your IP address, you should see the welcome to nginx page.
Create a directory for the app.
mkdir hello_world
cd hello_world
Create and activate the virtualenv.
python3 -m venv venv
. venv/bin/activate
Install fastapi, uvicorn, and gunicorn.
pip install fastapi "uvicorn[standard]" gunicorn
Create the main.py
file.
nano main.py
Paste the following code and save the file.
from fastapi import FastAPI
app = FastAPI()
@app.get("/")
def read_root():
return {"Hello": "World"}
Create the supervisord.conf
file in /etc/supervisor/conf.d/
cd /etc/supervisor/conf.d
sudo nano supervisord.conf
Paste the following in supervisord.conf.
[inet_http_server]
port=127.0.0.1:9001
[rpcinterface:supervisor]
supervisor.rpcinterface_factory = supervisor.rpcinterface:make_main_rpcinterface
[supervisorctl]
serverurl=http://127.0.0.1:9001
[supervisord]
[program:hello_world]
environment = PYTHONUNBUFFERED=1
user=ubuntu
directory=/home/ubuntu/hello_world/
command=/home/ubuntu/hello_world/venv/bin/gunicorn -w 4 -k uvicorn.workers.UvicornWorker main:app
autostart=true
autorestart=true
stderr_logfile=/var/log/hello_world/hello_world.err.log
stdout_logfile=/var/log/hello_world/hello_world.out.log
Note: Since Python output is buffered, the PYTHONUNBUFFERED=1 allows us to see output in our logs immediately.
Create the log folder and change the owner.
sudo mkdir /var/log/hello_world
sudo chown -R ubuntu:ubuntu /var/log/hello_world
Start supervisord.
sudo supervisord -c /etc/supervisor/conf.d/supervisord.conf
Verify that fastapi is running.
curl localhost:8000
Configure nginx.
cd /etc/nginx/conf.d/
sudo nano default.conf
Create a default.conf
. Make sure to replace the IP address.
server {
listen 80;
server_name 123.456.789.10 example.com;
location / {
proxy_pass http://localhost:8000;
}
}
Restart nginx.
sudo service nginx restart
Go to the IP in your browser. You should see hello world.
Other useful commands:
sudo supervisorctl
sudo supervisorctl status
sudo supervisorctl stop all
sudo supervisorctl start all
sudo supervisorctl reload
sudo supervisorctl restart
sudo supervisorctl tail -f hello_world
sudo supervisorctl tail -f hello_world stderr
sudo service supervisor stop
sudo service supervisor start