We did try to run a uvicorn server on our remote server, however, you might have noticed some of these issues:
In this tutorial, we will make our fastapi application, available to the public. Let's begin with installing supervisor and nginx. Supervisor is a process manager, it takes care of monitoring, running and restarting our process in case of a shutdown. Nginx is a popular reverse proxy, it takes requests from the internet and passes it on to gunicorn/uvicorn.
johnwick@fastapixcelery:~$ sudo apt install supervisor nginx
johnwick@fastapixcelery:~$ sudo systemctl enable supervisor
johnwick@fastapixcelery:~$ sudo systemctl start supervisor
Now, we can define a script that will take care of starting gunicorn workers and we can hook this script to the supervisor. Before that we need to define the script in a file. We are going to put the script in infra > gunicorn_conf.bash
Feel free to put it in any place that looks suitable to you.
johnwick@fastapixcelery:~/project$ pwd
/home/johnwick/project
johnwick@fastapixcelery:~/project$ mkdir infra
johnwick@fastapixcelery:~/project$ cd infra/
johnwick@fastapixcelery:~/project/infra$ touch gunicorn_conf.bash
#make it executable
johnwick@fastapixcelery:~/project/infra$ chmod +x gunicorn_conf.bash
johnwick@fastapixcelery:~/project/infra$ mkdir run
johnwick@fastapixcelery:~/project/infra$ nano gunicorn_conf.bash
Put the below script in gunicorn_conf.bash and save the file.
#!/bin/bash
NAME=fastapi-gunicorn
DIR=/home/johnwick/project
USER=johnwick
GROUP=johnwick
WORKERS=1
WORKER_CLASS=uvicorn.workers.UvicornWorker
VENV=$DIR/env/bin/activate
BIND=unix:$DIR/infra/run/gunicorn.sock
LOG_LEVEL=info
cd $DIR
source $VENV
exec gunicorn main:app \
--name $NAME \
--workers $WORKERS \
--worker-class $WORKER_CLASS \
--user=$USER \
--group=$GROUP \
--bind=$BIND \
--log-level=$LOG_LEVEL
Now, we need to hook this gunicorn configration file to supervisor. This will enable supervisor to call this file as a command everytime we reload/restart the process.
johnwick@fastapixcelery:~/project/infra$ cd /
johnwick@fastapixcelery:/$ cd etc/supervisor/conf.d/
johnwick@fastapixcelery:/etc/supervisor/conf.d$ sudo touch gunicorn.conf
johnwick@fastapixcelery:/etc/supervisor/conf.d$ sudo nano gunicorn.conf
Paste the below configurations, modify them as required, and save the file.
[program:fastapi-app]
command=/home/johnwick/project/infra/gunicorn_conf.bash
user=johnwick
autostart=true
autorestart=true
redirect_stderr=true
stdout_logfile=/home/johnwick/project/logs/fastapi_gunicorn.log
We need to inform supervisor to recognise the gunicorn process, We need to run the update command for it.
(env) johnwick@fastapixcelery:~/project/infra$ sudo supervisorctl update
(env) johnwick@fastapixcelery:~/project/infra$ sudo supervisorctl
fastapi-app RUNNING pid 42252, uptime 0:04:01
supervisor> status
fastapi-app RUNNING pid 42252, uptime 0:04:03
supervisor> restart fastapi-app
fastapi-app: stopped
fastapi-app: started
supervisor>
In case you faced any issues, and your status says exit/backoff. Please visit /project/logs directory and read the gunicorn logs.
Again if you send a curl request to the gunicorn socket, ideally you should get the ping pong :)
(env) johnwick@fastapixcelery:~/project/infra$ curl --unix-socket /home/johnwick/project/infra/run/gunicorn.sock localhost
{"ping":"pong!!"}
Brige the gap between Tutorial hell and Industry. We want to bring in the culture of Clean Code, Test Driven Development.
We know, we might make it hard for you but definitely worth the efforts.
© Copyright 2022-23 Team FastAPITutorial