The Ultimate Guide to Deploy FastAPI Application on Ubuntu with Nginx

The Ultimate Guide to Deploy FastAPI Application on Ubuntu with Nginx

I am assuming that you have an Ubuntu server and it's 18.04 or later that could be from the EC2 instance or any other VPS from DigitalOcean or Azure.

Firstly, Update & upgrade the existing packages with the blew command

sudo apt update
sudo apt upgrade

Install python3, pip and virtualenv:

sudo apt install python3 python3-pip python3-venv

Let’s set up your FastAPI application, initially Create a new directory in home with name backend

mkdir backend

Take a clone of your project from git inside the backend directory

git clone <your project repository URL>

Set up a Python virtual environment (venv) and activate the virtual environment:

python3 -m venv venv

source venv/bin/activate

Then install all packages in your requirements.txt file:

pip install -r requirements.txt

Make sure that uvicorn installed in your virtual environment. If not installed then run the blew command

pip install uvicorn

Now I am assuming that you are in backend directory and you have already installed the prerequisite packages successfully and you can now start your application with the blew command

uvicorn your_app_module:app --host --port 8000
# N.B: Replace your_app_module with the Python module where your FastAPI app is defined.

So far so good. To deploy your FastAPI application with the specified uvicorn command, you need to ensure that the application runs continuously and reliably. One common approach is to use a process manager systemd to manage your application as a service on your Ubuntu server. Here's a step-by-step guide to deploying your FastAPI application using systemd:

Create a systemd service unit file to define how your FastAPI application should be managed.

sudo touch /etc/systemd/system/backend.service

In this file, define the service as follows, adjust the paths and settings as needed, and save it.

Description=FastAPI Application
ExecStart=/home/ubuntu/backend/project/venv/bin/uvicorn --host --port 8000

Reload systemd to recognize the new service and start your FastAPI application as a service:

sudo systemctl daemon-reload
sudo systemctl start backend

If you want your FastAPI application to start automatically when the server reboots, enable the service

sudo systemctl enable backend

Check the status of your FastAPI application service to ensure it's running without errors

sudo systemctl status backend

If you encounter any errors in the process I have already discussed then try to follow the instructions accordingly and fix it.

If you want to serve your FastAPI application behind a web server like Nginx, you can set up a reverse proxy to forward requests to your FastAPI application. This can help with load balancing, SSL termination, and other server-related tasks

Let’s install nginx on Ubuntu server

sudo apt-get install nginx

Create a new Nginx server block configuration file for your FastAPI application. You can create a file in the /etc/nginx/sites-available/ directory. For example:

sudo vim /etc/nginx/sites-available/backend.conf

Inside this file, configure the reverse proxy settings for your FastAPI application. Here's an example configuration:

server {
    listen 80;
    server_name; # Replace with your actual domain name or IP address
    location / {
        proxy_set_header Host $host;
        proxy_set_header X-Real-IP $remote_addr;
        proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
    access_log /var/log/nginx/backend-access.log;
    error_log /var/log/nginx/backend-error.log;
    # Additional Nginx configuration can be added as needed

Create a symbolic link to enable the Nginx server block:

sudo ln -s /etc/nginx/sites-available/backend.conf /etc/nginx/sites-enabled/

Test the Nginx configuration for syntax errors:

sudo nginx -t

If there are no errors, proceed to the next step. Restart Nginx to apply the configuration changes:

sudo systemctl restart nginx

Now your backend is accessible from the internet, but it doesn’t meet the industry standard yet because https isn’t available and many more nginx config could be added there. However, try to test your work by going to http://<your domain/IP> with a web browser.