Introduction
FastAPI is a Python web framework for building APIs & web applications. It supports modern Python features like async & type hints, making it fast and efficient. In addition, it uses the Asynchronous Server Gateway Interface (ASGI) standard for asynchronous, concurrent connectivity with clients, and it can work with WSGI if needed.
In this article, you will learn everything required to deploy FastAPI Applications using Gunicorn & Nginx on an Ubuntu 20.04 server, such as setting up a FastAPI application in a virtual environment, using Gunicorn as an application server, Nginx as a reverse proxy & securing Nginx using an SSL Certificate. It does not include steps to install any database server for standardization because FastAPI can be used with any database server. You can refer to the following articles for database server installation:
- Install MySQL on Ubuntu 20.04 
- Install PostgreSQL on Ubuntu 20.04 
- Install MongoDB on Ubuntu 20.04 
Prerequisites
- Deploy a fresh Ubuntu 20.04 Server 
- Create non-root sudo user 
- Point a domain/subdomain to your server's public IP 
Caution: Inspect the commands before execution. Some commands might require changes according to your system, such as user, project name, project directory, domain, etc.
Setup FastAPI Application
- Initialize Project Directory - You can skip this step if you already have a git repository containing all your code. In that case, you can clone your repository, which will make a new directory for your project. Here we will create a directory to contain everything related to our project, including the codebase & virtual environment. - Create a folder for your project. - $ mkdir /home/demo/fastapi_demo- Open the project directory. - $ cd /home/demo/fastapi_demo
- Create Virtual Environment - A virtual environment is a Python tool for dependency management and project isolation. This means that each project can have any package installed locally in an isolated directory instead of being installed globally. - Install Python virtual environment package. - $ sudo apt update $ sudo apt install python3-venv- Create a Python virtual environment for your project. - $ python3 -m venv venv- Throughout this article, whenever a command is needed to be executed inside the virtual environment, the command snippets will start with (venv) $. - Enter the virtual environment. - $ source venv/bin/activate- Exit the virtual environment. - (venv) $ deactivate
- Install Dependencies - Make sure you use only the - pipcommand regardless of the version of pip installed on your host machine. When you are inside a virtual environment, the path is modified (until you exit) in such a way that the- pipcommand will refer to the pip executable file of the isolated virtual environment if you use pip3 or any command other than pip it might execute globally.- Install wheel Python package. - (venv) $ pip install wheel- Install fastapi Python package. - (venv) $ pip install fastapi[all]
- Make Basic FastAPI Application - You can skip this step if you already have a FastAPI Application ready to deploy. Here we have provided a very basic "Hello World" project code for demonstration purposes. - Create and edit - app.py- $ nano app.py- Paste the following code and save the file using CTRL + X then ENTER. - from fastapi import FastAPI app = FastAPI() @app.get("/") async def home(): return {"message": "Hello World"}
- Test Deployment - Deploy a temporary web server for testing. - (venv) $ uvicorn app:app- To verify if everything works, open a duplicate terminal and run. - $ curl http://localhost:8000- The expected output for provided demo code is: - {"message": "Hello World"}
Deploy FastAPI using Gunicorn
Gunicorn is a Python WSGI HTTP Server for UNIX. It makes managing and monitoring a web application much easier. Given its customizable nature, we can use ASGI features by using Uvicorn's worker class.
- Install Gunicorn - Install the gunicorn Python package. - (venv) $ pip install gunicorn
- Test Deployment - Deploy a temporary web server for testing. - (venv) $ gunicorn app:app -k uvicorn.workers.UvicornWorker- To verify if everything works, open a duplicate terminal and run. - $ curl http://localhost:8000- The expected output for the provided demo code is: - {"message": "Hello World"}
- Create Systemd Service - Add configuration file for Gunicorn. - $ nano gunicorn_conf.py- Paste the following code and save the file using CTRL + X then ENTER. - from multiprocessing import cpu_count # Socket Path bind = 'unix:/home/demo/fastapi_demo/gunicorn.sock' # Worker Options workers = cpu_count() + 1 worker_class = 'uvicorn.workers.UvicornWorker' # Logging Options loglevel = 'debug' accesslog = '/home/demo/fastapi_demo/access_log' errorlog = '/home/demo/fastapi_demo/error_log'- Create and edit systemd unit file. - $ sudo nano /etc/systemd/system/fastapi_demo.service- Paste the following code and save the file using CTRL + X then ENTER. - [Unit] Description=Gunicorn Daemon for FastAPI Demo Application After=network.target [Service] User=demo Group=www-data WorkingDirectory=/home/demo/fastapi_demo ExecStart=/home/demo/fastapi_demo/venv/bin/gunicorn -c gunicorn_conf.py app:app [Install] WantedBy=multi-user.target- Start & enable the service. - $ sudo systemctl start fastapi_demo $ sudo systemctl enable fastapi_demo- To verify if everything works run the following command. - $ sudo systemctl status fastapi_demo- Expected output:  - Also, you can check the response using the following command. - $ curl --unix-socket unix:/home/demo/fastapi_demo/gunicorn.sock localhost- The expected output for the provided demo code is: - {"message": "Hello World"}
Setup Nginx as Reverse Proxy
Nginx is an open-source, lightweight & powerful web server. It is recommended to use Nginx as a reverse proxy for seamless request handling. Also, you can take advantage of Nginx's vhost / virtual server feature to host multiple web applications on a single host if you wish to do so. You can also offload some load from your WSGI/ASGI server by serving static files directly using the additional location directive in our server block.
- Install Nginx - $ sudo apt update $ sudo apt install nginx
- Add vhost configuration - Add vhost file to - sites-availabledirectory.- $ sudo nano /etc/nginx/sites-available/fastapi_demo- Paste the following content (replace your_domain with your actual domain) and save the file using CTRL + X then ENTER. - server { listen 80; server_name your_domain www.your_domain; location / { proxy_pass http://unix:/home/demo/fastapi_demo/gunicorn.sock; } }
- Activate vhost configuration - Add a soft link of the vhost file in the - sites-enableddirectory.- $ sudo ln -s /etc/nginx/sites-available/fastapi_demo /etc/nginx/sites-enabled/
- Test and reload the configuration - Test the configuration. - $ sudo nginx -t- Expected output: - nginx: the configuration file /etc/nginx/nginx.conf syntax is ok nginx: configuration file /etc/nginx/nginx.conf test is successful- Reload Nginx. - $ sudo systemctl reload nginx
Secure Nginx with an SSL Certificate
An SSL Certificate is used to encrypt the traffic between users and the origin server. It is essential for applications dealing with sensitive data. We will use Let's Encrypt to obtain an SSL Certificate for free. Please make sure you have pointed your domain to the server's public IP.
- Install Certbot - $ sudo apt install -y certbot python3-certbot-nginx
- Install Certificate on Nginx - You will be asked to enter your email address when you run the following command. Please enter your email address and leave the rest set as default. - $ sudo certbot --nginx -d your_domain -d www.your_domain
- Verify the Accessibility - You can verify if the SSL Certificate is configured properly or not by opening the following link in your web browser. - https://your_domain
- Test Auto-Renewal - Let's Encrypt certificates are only valid for 90 days, but certbot will handle auto-renewals. You can verify if the auto-renewal works by running the following command: - $ sudo certbot renew --dry-run- If the above command doesn't throw an error, it means your SSL certificate will be renewed automatically without any issues. 
Conclusion
In this article, you learned how to use virtual environments to isolate dependencies, set up a FastAPI application, use Gunicorn as an application server, Nginx as a reverse proxy server & secure Nginx using an SSL Certificate. For more information related to FastAPI, visit the official FastAPI website.
