FastAPI + NGINX + Gunicorn: Teach you step by step to deploy a high-performance Python web application

I. Introduction

Deploying a FastAPI application to your server is a complex task. If you are not familiar with technologies such as NGINX , Gunicorn and Uvicorn , you may waste a lot of time. If you are new to the Python language or want to use Python to build your own web application, the content of this article may save you time during your first deployment.

FastAPI is one of the most popular Python libraries for developing API applications. It is known for its excellent performance and ease of use. If you use machine learning models in web applications, then it is probably your tool of choice.

NGINX, Gunicorn and Uvicorn are all proven technologies that are often used as reverse proxies and ASGI servers to deploy Python web applications. If you're familiar with Django or Flask, you've probably heard of some of them before.

Next, I'll show how to combine these tools to deploy a FastAPI web application. The following are the main contents:

  • Introduce the basic knowledge of FastAPI, NGINX, Gunicorn and Uvicorn.

  • Configure Gunicorn + Uvicorn as ASGI server.

  • Set up NGINX as a reverse proxy server.

  • Generate a free SSL certificate with Let's Encrypt.

2. Introduction to technical framework

2.1、FastAPI

FastAPI is a modern, high-performance web framework for building APIs in Python and based on standard type hints.

It has the following main features:

  • Efficient operation : With Starlette and pydantic, FastAPI provides excellent performance similar to NodeJS and Go. FastAPI is much faster than Flask, it is actually one of the fastest web frameworks for Python. The only framework that is faster than FastAPI is Starlette (FastAPI is actually built on Starlette).

  • Rapid development : It can significantly increase the speed of development.

  • Reduced Errors : Reduces the possibility of human error.

  • Intuitive and easy to use : Supports powerful editor features, auto-completion and less time debugging.

  • Easy to learn : The design is simple and clear, so you can spend less time reading the documentation.

  • Reduce the amount of duplicate code : Code duplication is minimized.

  • Robust and reliable : Provides production-ready code and automatic generation of interactive documentation.

  • Based on standardization : Follow open standards such as API, OpenAPI and JSON Schema.

The framework is designed to optimize the developer experience, allowing you to build best-practice, production-ready APIs with clean code.

2.2、Gunicorn

Gunicorn is an implementation of a WSGI server for Python applications.

Gunicorn is a WSGI -compliant web server for Python applications that receives requests sent from the client to the web server and forwards them to the Python application or web framework such as Flask or Django to serve the request Run the appropriate application code.

2.3、Uvicorn

Unlike the Flask framework, FastAPI does not include any built-in development server. Therefore, we need Uvicorn . It implements the ASGI standard and is lightning fast. ASGI stands for Asynchronous Server Gateway Interface .

  • Uvicorn is an ASGI web server implementation for Python.

  • Uvicorn currently supports HTTP/1.1 and WebSockets.

2.4、Nginx

Nginx is an asynchronous framework web server that can also be used as a reverse proxy, load balancer and HTTP cache. The software was created by Igor Sysoev and first publicly released in 2004. The company of the same name was founded in 2011 to provide support. Nginx is free open source software released under the terms of a BSD-like license. A large number of web servers use Nginx, usually as a load balancer.

Nginx has the following characteristics:

  • Faster : A single request will receive a faster response; in a high-concurrency environment, Nginx has a faster response than other WEB servers.

  • High scalability : Nginx is based on a modular design and consists of multiple modules with extremely low coupling, so it has high scalability. Many high-traffic websites tend to develop customized modules that suit their business characteristics.

  • High reliability : Nginx's reliability comes from the excellent design of its core framework code and the simplicity of its module design. In addition, the commonly used modules provided by the official are very stable, and each worker process is relatively independent. When a worker process fails, the master process can quickly start a new worker sub-process to provide services.

  • Low memory consumption : Under normal circumstances, 10,000 inactiveHTTP Keep-Aliveconnections consume only the memory in Nginx2.5MB, which is the basis for Nginx to support high concurrent connections; a single machine supports more than 100,000 concurrent connections: Theoretically, the upper limit of concurrent connections supported by Nginx Depending on the memory, 100,000 is far from the limit.

  • Hot deployment : The separation design of the master process and the worker process enables Nginx to provide hot deployment function, that is, to upgrade the Nginx executable file under the premise of uninterrupted service 24/7. Of course, it also supports functions such as updating configuration items and replacing log files without stopping the service.

  • The most liberal BSD license agreement : This is a powerful driving force for Nginx to develop rapidly. The BSD license agreement not only allows users to use Nginx for free, it also allows users to directly use or modify the Nginx source code in their own projects and then publish it.

3. Server security settings

If your application is deployed on a LAN, you may not need to pay attention to this for the time being, but if your application is deployed on a cloud server or VPS, in order to ensure the security of your application, it is recommended that you still need to make some necessary security settings on the server. , to avoid being attacked.

3.1. Enable automatic updates

First, make sure your server has the latest software:

sudo apt update && sudo apt upgrade -y

The following are common commands you'll see when using Debian-based servers:

  1. Use the command sudo apt updateto update the package list index on your system.

  2. Use the command sudo apt upgrade -yto upgrade installed packages to the latest version. Use -ythe flag to skip the confirmation step and proceed directly to the installation.

Next, set up automatic security updates so you don't have to perform updates manually. To do this you need to install and enable unnattended-upgrades:

sudo apt install unattended-upgrades

After the installation is complete, edit the file /etc/apt/apt.conf.d/20auto-upgradesand set it up according to the following configuration:

APT::Periodic::Update-Package-Lists "1";  # 每天自动更新软件包列表
APT::Periodic::Unattended-Upgrade "1";    # 系统将自动升级到最新版本的软件包
APT::Periodic::AutocleanInterval "7";     # 每周运行一次自动清理操作,删除旧的和不必要的包文件

Finally, /etc/apt/apt.conf.d/50unattended-upgradesmake edits in the file to ensure that the system automatically reboots when a kernel update is required:

Unattended-Upgrade::Automatic-Reboot "true";

After completing the above steps, your system will automatically perform security updates and reboot if needed to apply kernel updates.

3.2. Create a non-root user

To reduce the damage caused by hacker attacks, creating a non-root user is necessary. Here are some commands to create a non-root user and set up SSH key login:

  • Create a new non-root user:
sudo adduser fastapi-user # 将fastapi-user替换为您喜欢的用户名
  • Add this user to the sudo group to gain administrator rights:
sudo usermod -aG sudo fastapi-user # 将fastapi-user替换为您创建的用户名
  • Log in to the server using the newly created user:
su - fastapi-user # 使用新用户登录,将fastapi-user替换为您创建的用户名
  1. Set up authentication using SSH keys:

If you don't have an SSH key yet, open a terminal on your local machine and run the following command (note to replace your-email-replace-with-your-email with your actual email):

ssh-keygen -t ed25519 -C "your-email-replace-with-your-email"

This will generate a pair of SSH keys.

Copy the public SSH key and paste it on the remote server (note to replace your-public-key-with-your-public-key with the actual public key):

echo "your-public-key-replace-with-your-public-key" >> ~/.ssh/authorized_keys
chmod 600 ~/.ssh/authorized_keys
  • Disable root login and password authentication:

Edit the file with sudo permissions /etc/ssh/sshd_config(e.g. using sudo vim /etc/ssh/sshd_configcommand).

Change the values ​​of the following lines to show:

PermitRootLogin no
PasswordAuthentication no

This will disable root login and use of passwords for SSH authentication.

  • After saving and closing the file, restart the SSH service for the changes to take effect:
sudo service ssh restart

Once you complete the above steps, log in using your newly created non-root user and SSH key, and make sure root login and password authentication are disabled.

3.3. Other safety measures

Most cloud providers offer firewall services. If your cloud provider does not provide firewall services, you can manually configure the firewall to limit incoming traffic to only necessary ports, such as ports 80 , 443 , and 22 .

Additionally, you can install and configure fail2ban to prevent brute force authentication attacks. Fail2ban is a tool for protecting Linux servers from malicious login attempts. It monitors system log files and automatically bans source IP addresses based on set rules.

If you want to learn more about best practices for securing your Linux servers, check out this guide from Linode. These guides will provide you with detailed information on how to set up and enhance server security.

4. Install software tools

In order to install the necessary software tools, follow these steps:

4.1. Install Python:

sudo add-apt-repository ppa:deadsnakes/ppa
sudo apt update
sudo apt install python3.11 python3.11-venv -y

4.2. Install Supervisor and NGINX:

sudo apt install supervisor nginx -y

Supervisor is a process control system for Unix-like operating systems (including Linux). It is used to monitor and manage program processes. NGINX is a commonly used multi-purpose software that is often used as a reverse proxy to deploy web applications.

4.3. Enable and start Supervisor:

sudo systemctl enable supervisor
sudo systemctl start supervisor

Using enablethe command will ensure that Supervisor starts automatically on boot and using startthe command starts the Supervisor service immediately.

After completing the above steps, you have successfully installed Python, Supervisor, and NGINX, and have enabled and started the Supervisor service.

5. Set up the FastAPI application

First, clone the sample application into /home/fastapi-usera directory:

git clone https://github.com/dylanjcastillo/fastapi-nginx-gunicorn

This will clone the code from the public repository. If you are deploying an application from a private GitHub repository, set a GitHub deployment key and use that key to clone the repository.

Next, create a virtual environment and activate it:

cd /home/fastapi-user/fastapi-nginx-gunicorn
python3.11 -m venv .venv
source .venv/bin/activate

These commands will take you to the project directory, create a virtual environment there and activate it. Once activated successfully, your command line prompt should appear in front of you .venv.

Now, install the required packages using the dependencies specified in the requirements.txt file:

pip install -r requirements.txt

This will install packages such as fastapi , gunicorn and uvicorn in the current virtual environment .

To verify that everything went well, run the application:

uvicorn main:app

There should be no errors when running this command. You can also verify that it is working by opening a new terminal window, connecting to the server, and making a request using the following command:

curl http://localhost:8000

You should receive the following response:

{"message":"It's working!"}

Now that you have successfully run your FastAPI application, you will configure Gunicorn as a WSGI server.

6. Configure Gunicorn

There are two steps to configure Gunicorn. First, explicitly specify Gunicorn ’s configuration requirements. Second, set up the Supervisor program to run Gunicorn.

6.1 Setting up Gunicorn

First, create a file called gunicorn_start in the project directory :

vim gunicorn_start

Then, add the following content to the file:

#!/bin/bash

NAME=fastapi-app
DIR=/home/fastapi-user/fastapi-nginx-gunicorn
USER=fastapi-user
GROUP=fastapi-user
WORKERS=3
WORKER_CLASS=uvicorn.workers.UvicornWorker
VENV=$DIR/.venv/bin/activate
BIND=unix:$DIR/run/gunicorn.sock
LOG_LEVEL=error

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 \
  --log-file=-

Here is an explanation of your settings:

  • Line 1 indicates that this script will be executed by the bash shell.

  • Lines 3 through 11 specify the configuration options you will pass to Gunicorn. Most parameters are intuitive, except WORKERS , WORKER_CLASS and BIND :

  • WORKERS : Define the number of worker processes to use, usually the number of CPU cores + 1 is recommended.

  • WORKER_CLASS : Specifies the type of worker process to use. In this example, you specify Uvicorn Worker as the ASGI server.

  • BIND : Specifies the server socket that Gunicorn is bound to.

  • Lines 13 and 14 change the current location to the project directory and activate the virtual environment.

  • Lines 16 to 24 run Gunicorn with the specified parameters.

Save and close the file. Then, make it executable by running the following command:

chmod u+x gunicorn_start

Finally, create a folder run in the project directory to store the Unix socket files you defined in the parameters BIND:

mkdir run

6.2 Configure Supervisor

First, create a directory named logs in the project directory to store the application’s error logs:

mkdir logs

Next, create the Supervisor’s configuration file by running the following command:

sudo vim /etc/supervisor/conf.d/fastapi-app.conf

Copy and paste the following into the file:

[program:fastapi-app]
command=/home/fastapi-user/fastapi-nginx-gunicorn/gunicorn_start
user=fastapi-user
autostart=true
autorestart=true
redirect_stderr=true
stdout_logfile=/home/fastapi-user/fastapi-nginx-gunicorn/logs/gunicorn-error.log

This configuration file specifies the gunicorn_start script created earlier and sets fastapi-user as the user. Supervisor will start the application when the server starts and restart the application if it fails. The error log will be recorded in the logs/gunicorn-error.log file in the project directory.

Reload the Supervisor configuration and restart the service by running the following commands:

sudo supervisorctl reread
sudo supervisorctl update

Finally, you can check the status of your program by running the following command:

sudo supervisorctl status fastapi-app

If all goes well, the status of the fastapi-app service should show RUNNING .

You can also test it by opening a new terminal window, connecting to the server, and making a GET request using:

curl --unix-socket /home/fastapi-user/fastapi-nginx-gunicorn/run/gunicorn.sock localhost

You should see the following output:

{"message":"It's working!"

Finally, if you make changes to your code, you can restart the service to apply the changes by running:

sudo supervisorctl restart fastapi-app

Now you have an application that uses Gunicorn and Uvicorn as an ASGI server. Next, you'll set up a reverse proxy server using NGINX.

7. Configure NGINX

Create a new NGINX configuration file for your project :

sudo vim /etc/nginx/sites-available/fastapi-app

Open the NGINX configuration file and paste the following:

upstream app_server {
    server unix:/home/fastapi-user/fastapi-nginx-gunicorn/run/gunicorn.sock fail_timeout=0;
}

server {
    listen 80;

    # add here the ip address of your server
    # or a domain pointing to that ip (like example.com or www.example.com)
    server_name XXXX;

    keepalive_timeout 5;
    client_max_body_size 4G;

    access_log /home/fastapi-user/fastapi-nginx-gunicorn/logs/nginx-access.log;
    error_log /home/fastapi-user/fastapi-nginx-gunicorn/logs/nginx-error.log;

    location / {
        proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
        proxy_set_header Host $http_host;
        proxy_redirect off;

        if (!-f $request_filename) {
            proxy_pass http://app_server;
            break;
        }
        }
}

This is the NGINX configuration file. Here's how it works:

  • Lines 1 through 3 app_serverdefine a cluster of servers called NGINX that will proxy requests. Requests are redirected to the Unix socket file located at /home/fastapi-user/fastapi-nginx-gunicorn/run/gunicorn.sock. The settingfail_timeout=0 tells NGINX not to treat the server as failed even if it is unresponsive.

  • Lines 1 through 5 define the configuration of the virtual server that NGINX will use to handle requests. In this example, it listens on port 80. Replace XXXX with your IP or site name.

  • Lines 12 and 13 specify keepalive_timeoutto set the maximum time a client can keep a persistent connection open and client_max_body_sizeto set the limit on the size of the client request body that NGINX allows.

  • Lines 15 and 16 specify where NGINX will write its access and error logs.

  • Lines 18 to 27 define how NGINX will handle requests to the root directory /. You provide some specifications to handle the headers and set up a directive to proxy the request to the one you app_serverdefined earlier.

Enable site configuration by creating a symbolic link from the file by running the following command sites-available:sites-enabled

sudo ln -s /etc/nginx/sites-available/fastapi-app /etc/nginx/sites-enabled/

Test whether the configuration file is normal and restart NGINX:

sudo nginx -tsudo systemctl restart nginx

If all went well, you should now be able to download it from your browser or using curl. You should see the following output again:

{"message":"It's working!"}

You should now have your FastAPI application running with Gunicorn+Uvicorn as the ASGI server and NGINX in front of them as a reverse proxy.

7.1. Permission error

If you get a permission error indicating that NGINX cannot access the Unix socket, you can add user www-data (usually the user under which the NGINX process runs) to the fastapi-user group. You can use the following command:

sudo usermod -aG fastapi-user www-data

If you have not purchased a domain name for your API application, there is no need to read further. If you already have a domain name, proceed to the next step to obtain an SSL certificate and enable HTTPS.

8. Use Certbot to get a free SSL certificate

This only applies to the domain name you wish to obtain an SSL certificate for. If you are using Ubuntu , you can skip this step. Otherwise, you first need to install snapd :

sudo apt install snapd

Next, make sure you have the latest version available:

sudo snap install core; sudo snap refresh core

Install Certbot and make sure certbotthe command is executable:

sudo snap install --classic certbot
sudo ln -s /snap/bin/certbot /usr/bin/certbot

Next, generate a certificate for your domain name by running the following command interactively:

sudo certbot --nginx

Finally, Certbot will automatically handle the renewal of your certificate. To test if it works, run the following command:

sudo certbot renew --dry-run

If all goes well, you should see the Congratulations, all simulated renewals succeeded… message.

You should now be able to successfully send requests over HTTPS.

9. Conclusion

This article introduces how to use NGINX , Gunicorn and Uvicorn to deploy FastAPI applications. FastAPI is one of the most popular Python web frameworks. It has become the first choice for deploying machine learning-driven web applications, so if you want to continue to pay attention to the field of AI and do some application development practices, it is helpful to be familiar with it.

In this article you learned:

  • Why and when you should use FastAPI, NGINX, Gunicorn and Uvicorn .

  • How to set up Gunicorn+Uvicorn as ASGI server .

  • How to use Supervisor to run Gunicorn .

  • How to use certbot to configure NGINX and generate a free SSL certificate .

If you are interested in this article and want to learn more about practical skills in the field of AI, you can follow the "Technology Frenzy AI" public account . Here, you can see the latest and hottest articles and practical case tutorials in the AIGC field.

Guess you like

Origin blog.csdn.net/FrenzyTechAI/article/details/132696546