FastAPI Deployment: Docker, NGINX and Gunicorn

This blog teaches you how to deploy your web API using FastAPI, Docker, NGINX and Gunicorn. You will learn the basics of these tools and how to configure them for optimal performance.

1. Introduction

In this tutorial, you will learn how to deploy your web API using FastAPI, Docker, NGINX and Gunicorn. These are some of the most popular and powerful tools for web development and deployment. By the end of this tutorial, you will have a fully functional and scalable web API that can handle high traffic and complex requests.

But before we dive into the details, let’s briefly review what these tools are and why we need them.

FastAPI is a modern and fast web framework for building APIs with Python. It has many features that make it easy and enjoyable to develop web applications, such as automatic documentation, data validation, authentication, testing, and more. FastAPI is based on Starlette, a lightweight ASGI framework that supports asynchronous operations and websockets.

Docker is a software platform that allows you to build, run, and share applications using containers. Containers are isolated environments that contain everything an application needs to run, such as code, libraries, dependencies, and configuration. Docker makes it easy to create, deploy, and manage containers across different platforms and environments.

NGINX is a web server that can also act as a reverse proxy, load balancer, and HTTP cache. NGINX is known for its high performance, stability, and scalability. It can handle millions of concurrent connections and serve static and dynamic content efficiently. NGINX can also improve the security and reliability of your web application by providing features such as SSL/TLS encryption, HTTP/2 support, rate limiting, and access control.

Gunicorn is a Python WSGI HTTP server that can run multiple workers to handle requests. Gunicorn is compatible with many web frameworks, including FastAPI. Gunicorn can work well with NGINX, as NGINX can handle the incoming connections and pass them to Gunicorn workers via a Unix socket or a TCP port. Gunicorn can also handle the communication between the web application and the database or other services.

Now that you have a general idea of what these tools are, let’s see how we can use them to deploy our web API.

2. What is FastAPI?

FastAPI is a web framework for building APIs with Python. It is designed to be fast, easy, and fun to use. FastAPI has many features that make it a great choice for web development, such as:

  • Automatic documentation: FastAPI generates interactive documentation for your API using Swagger and ReDoc. You can explore and test your API directly from the browser, without writing any extra code.
  • Data validation: FastAPI uses Pydantic to validate and serialize the data that you receive and send. You can define your data models using standard Python types and annotations, and FastAPI will handle the validation, parsing, and conversion for you.
  • Authentication: FastAPI supports various authentication methods, such as OAuth2, JWT, API keys, cookies, and more. You can easily integrate your API with third-party services and secure your endpoints with different scopes and permissions.
  • Testing: FastAPI has built-in support for testing your API using pytest. You can write your tests using the same syntax and tools that you use for your code, and FastAPI will provide you with useful helpers and fixtures to make your testing easier and faster.
  • And more: FastAPI also offers many other features, such as dependency injection, background tasks, file uploads, websockets, CORS, and more. You can check out the official documentation for more details and examples.

FastAPI is based on Starlette, a lightweight ASGI framework that supports asynchronous operations and websockets. This means that FastAPI can handle concurrent requests and real-time communication efficiently and elegantly. FastAPI also inherits Starlette’s compatibility with many other ASGI frameworks and libraries, such as Uvicorn, Hypercorn, HTTPX, and more.

If you want to learn more about FastAPI, you can visit the official website or the GitHub repository. You can also join the Gitter chat or the Discord server to ask questions and share your experience with other FastAPI users.

3. What is Docker and why use it?

Docker is a software platform that allows you to build, run, and share applications using containers. Containers are isolated environments that contain everything an application needs to run, such as code, libraries, dependencies, and configuration. Docker makes it easy to create, deploy, and manage containers across different platforms and environments.

Why use Docker for web deployment? Here are some of the benefits of using Docker:

  • Portability: Docker containers can run on any machine that has Docker installed, regardless of the operating system, hardware, or cloud provider. This means that you can develop your application on your local machine, test it on a staging server, and deploy it to production without worrying about compatibility issues.
  • Consistency: Docker containers ensure that your application runs the same way in every environment, as they have the same code, libraries, dependencies, and configuration. This means that you can avoid the common problem of “it works on my machine, but not on yours”.
  • Isolation: Docker containers isolate your application from the host system and other containers, preventing any interference or conflicts. This means that you can run multiple applications on the same machine without affecting each other, and also improve the security and reliability of your application.
  • Efficiency: Docker containers are lightweight and fast, as they share the same kernel and resources of the host system, and only contain the essential components of the application. This means that you can run more containers on the same machine, and also reduce the startup and shutdown time of your application.
  • Reusability: Docker containers are based on images, which are snapshots of the container’s state. You can create your own images, or use existing images from the Docker Hub, a public repository of images for various applications and services. You can also share your images with others, or use them as a base for creating new containers.

If you want to learn more about Docker, you can visit the official website or the documentation. You can also check out the blog or the YouTube channel for tutorials and updates.

4. Creating a Dockerfile for FastAPI

A Dockerfile is a text file that contains the instructions for building a Docker image. A Docker image is a snapshot of a container’s state, which can be used to create and run new containers. To create a Dockerfile for FastAPI, you need to follow these steps:

  1. Choose a base image: A base image is an existing image that provides the foundation for your new image. You can choose a base image from the Docker Hub, or create your own. For this tutorial, we will use the official Python image, which comes with Python and pip pre-installed. You can specify the version of Python you want to use by adding a tag to the image name. For example, python:3.9 will use Python 3.9 as the base image.
  2. Copy your code and requirements: You need to copy your FastAPI code and the requirements.txt file to the image. The requirements.txt file contains the list of packages that your application depends on, such as FastAPI, Uvicorn, Pydantic, etc. You can use the COPY instruction to copy files from your local directory to the image. You also need to create a working directory for your application using the WORKDIR instruction.
  3. Install your dependencies: You need to install your dependencies using pip. You can use the RUN instruction to execute commands in the image. You should also use the --no-cache-dir option to avoid caching the packages and reduce the image size.
  4. Expose the port: You need to expose the port that your application will use to communicate with the outside world. You can use the EXPOSE instruction to inform Docker that your container will listen on a specific port. For this tutorial, we will use port 80, which is the default port for HTTP.
  5. Define the entrypoint: You need to define the entrypoint for your container, which is the command that will be executed when the container starts. You can use the ENTRYPOINT instruction to specify the executable and the arguments that will be passed to it. For this tutorial, we will use Uvicorn as the ASGI server to run our FastAPI application. You can pass the name of your FastAPI module, the port, and other options to Uvicorn.

Here is an example of a Dockerfile for FastAPI:

# Use the official Python image as the base image
FROM python:3.9

# Copy the code and the requirements.txt file to the image
COPY ./app /app
COPY ./requirements.txt /app

# Create a working directory for the application
WORKDIR /app

# Install the dependencies using pip
RUN pip install --no-cache-dir -r requirements.txt

# Expose the port 80 for the application
EXPOSE 80

# Define the entrypoint for the container
ENTRYPOINT ["uvicorn", "main:app", "--host", "0.0.0.0", "--port", "80"]

You can save this file as Dockerfile in the same directory as your FastAPI code and requirements.txt file. You can then use the docker build command to build your image, and the docker run command to run your container.

5. Building and running the Docker image

Once you have created your Dockerfile, you can build your Docker image using the docker build command. The docker build command takes the path to the directory where your Dockerfile is located, and optionally a name and a tag for your image. For example, you can run the following command to build your image and name it fastapi-app with the tag v1:

docker build -t fastapi-app:v1 .

The . at the end of the command indicates the current directory, where your Dockerfile is located. You can also use a different path or a URL to your Dockerfile. The -t option allows you to specify a name and a tag for your image, which will help you identify and manage your images. You can use any name and tag you want, as long as they follow the naming conventions.

The docker build command will read your Dockerfile and execute the instructions in it, one by one. It will also create intermediate images for each instruction, which will be cached and reused for future builds. This will speed up the build process and reduce the image size. You can see the output of the docker build command in your terminal, which will show you the progress and the status of each instruction.

After the docker build command finishes, you can run your Docker image using the docker run command. The docker run command takes the name or the ID of the image you want to run, and optionally some options and arguments. For example, you can run the following command to run your image and map the port 80 of the container to the port 8000 of the host machine:

docker run -p 8000:80 fastapi-app:v1

The -p option allows you to publish the port of the container to the port of the host machine, using the format host_port:container_port. This will enable you to access your application from the host machine, using the host port. You can use any port you want, as long as it is not already in use by another process.

The docker run command will create and start a new container from your image, and execute the entrypoint command that you defined in your Dockerfile. You can see the output of the docker run command in your terminal, which will show you the logs of your application. You can also use the -d option to run your container in the background, and the --name option to give your container a name.

Now you can open your browser and go to http://localhost:8000 (or the port you mapped) to see your FastAPI application running inside a Docker container. You can also use the docker ps command to see the list of running containers, and the docker stop command to stop your container.

6. What is NGINX and why use it?

NGINX is a web server that can also act as a reverse proxy, load balancer, and HTTP cache. NGINX is known for its high performance, stability, and scalability. It can handle millions of concurrent connections and serve static and dynamic content efficiently. NGINX can also improve the security and reliability of your web application by providing features such as SSL/TLS encryption, HTTP/2 support, rate limiting, and access control.

Why use NGINX for web deployment? Here are some of the benefits of using NGINX:

  • Reverse proxy: A reverse proxy is a server that sits between the client and the backend server, and forwards the client’s requests to the backend server. NGINX can act as a reverse proxy for your FastAPI application, and handle the incoming connections and pass them to the Gunicorn workers via a Unix socket or a TCP port. This way, NGINX can offload some of the tasks from the backend server, such as SSL/TLS termination, compression, caching, and buffering.
  • Load balancer: A load balancer is a server that distributes the incoming traffic among multiple backend servers, and returns the response from the most appropriate server. NGINX can act as a load balancer for your FastAPI application, and balance the load among multiple Gunicorn workers or instances. This way, NGINX can improve the performance and availability of your application, and also provide failover and health checks.
  • HTTP cache: An HTTP cache is a server that stores the responses from the backend server, and serves them to the client without contacting the backend server again. NGINX can act as an HTTP cache for your FastAPI application, and cache the responses from the Gunicorn workers or instances. This way, NGINX can reduce the latency and bandwidth consumption of your application, and also handle the requests that do not need to be processed by the backend server.

If you want to learn more about NGINX, you can visit the official website or the documentation. You can also check out the blog or the YouTube channel for tutorials and updates.

7. Configuring NGINX as a reverse proxy

In the previous section, you learned how to build and run your FastAPI application using Docker. However, running your application directly on the port 80 of the host machine may not be the best practice, as it may expose your application to security risks and performance issues. A better way to run your application is to use NGINX as a reverse proxy, which will sit between the client and your application, and handle the incoming connections and pass them to your application via a Unix socket or a TCP port.

To configure NGINX as a reverse proxy, you need to follow these steps:

  1. Install NGINX: You need to install NGINX on your host machine, if you haven’t already. You can use the apt command to install NGINX on Ubuntu, or the yum command to install NGINX on CentOS. For example, you can run the following command to install NGINX on Ubuntu:
  2. sudo apt update
    sudo apt install nginx
    
  3. Create a server block: A server block is a configuration file that defines how NGINX will handle requests for a specific domain or IP address. You need to create a server block for your FastAPI application, and specify the location, the proxy settings, and the SSL/TLS settings. You can create a server block in the /etc/nginx/sites-available directory, and name it as fastapi-app. For example, you can create a server block with the following content:
  4. server {
        # Listen on port 80 for HTTP requests
        listen 80;
    
        # The domain name or IP address of your application
        server_name example.com;
    
        # Redirect HTTP requests to HTTPS
        return 301 https://$server_name$request_uri;
    }
    
    server {
        # Listen on port 443 for HTTPS requests
        listen 443 ssl;
    
        # The domain name or IP address of your application
        server_name example.com;
    
        # The path to the SSL certificate and the key files
        ssl_certificate /etc/letsencrypt/live/example.com/fullchain.pem;
        ssl_certificate_key /etc/letsencrypt/live/example.com/privkey.pem;
    
        # The location of the root directory for static files
        root /var/www/html;
    
        # The location of the FastAPI application
        location / {
            # The proxy settings for passing requests to the FastAPI application
            proxy_pass http://unix:/tmp/fastapi-app.sock;
            proxy_set_header Host $http_host;
            proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
            proxy_set_header X-Forwarded-Proto $scheme;
        }
    }
    
  5. Enable the server block: You need to enable the server block by creating a symbolic link from the /etc/nginx/sites-available directory to the /etc/nginx/sites-enabled directory. You can use the ln command to create a symbolic link. For example, you can run the following command to enable the server block for your FastAPI application:
  6. sudo ln -s /etc/nginx/sites-available/fastapi-app /etc/nginx/sites-enabled/
    
  7. Test and reload NGINX: You need to test the configuration of NGINX and reload it to apply the changes. You can use the nginx command to test and reload NGINX. For example, you can run the following commands to test and reload NGINX:
  8. sudo nginx -t
    sudo nginx -s reload
    

Now you have configured NGINX as a reverse proxy for your FastAPI application. You can access your application from the domain name or the IP address of your host machine, using HTTPS. You can also use the curl command to test your application from the terminal. For example, you can run the following command to test your application:

curl -k https://example.com

8. What is Gunicorn and why use it?

Gunicorn is a Python WSGI HTTP server that can run multiple workers to handle requests. WSGI stands for Web Server Gateway Interface, which is a standard interface between web servers and web applications in Python. Gunicorn is compatible with many web frameworks, including FastAPI. Gunicorn can work well with NGINX, as NGINX can handle the incoming connections and pass them to Gunicorn workers via a Unix socket or a TCP port. Gunicorn can also handle the communication between the web application and the database or other services.

Why use Gunicorn for web deployment? Here are some of the benefits of using Gunicorn:

  • Scalability: Gunicorn can scale up your application by creating multiple workers, which are processes that run your application code and handle requests. You can configure the number of workers according to your needs and resources, and Gunicorn will automatically manage them for you. You can also use different types of workers, such as sync, async, or gevent, to optimize the performance of your application.
  • Reliability: Gunicorn can ensure the reliability of your application by monitoring the health of the workers and restarting them if they fail or timeout. You can also configure the timeout and graceful shutdown settings for your workers, and use signals to control them. Gunicorn can also log the errors and events of your application, and integrate with other logging tools.
  • Simplicity: Gunicorn is easy to install and use, as it has minimal dependencies and configuration. You can install Gunicorn using pip, and run your application using a simple command. You can also use a configuration file to customize the settings of Gunicorn, and use environment variables to override them.

If you want to learn more about Gunicorn, you can visit the official website or the documentation. You can also check out the GitHub repository or the Gitter chat for source code and support.

9. Running FastAPI with Gunicorn and NGINX

In the previous sections, you learned how to create a Dockerfile for your FastAPI application, build and run your Docker image, and configure NGINX as a reverse proxy. Now, you are ready to run your FastAPI application with Gunicorn and NGINX, and enjoy the benefits of scalability, reliability, and simplicity.

To run your FastAPI application with Gunicorn and NGINX, you need to follow these steps:

  1. Run your Docker image with Gunicorn: You need to run your Docker image with Gunicorn as the entrypoint command, and specify the number and the type of the workers, and the Unix socket or the TCP port to communicate with NGINX. You can use the docker run command with the --entrypoint option to override the entrypoint command of your image, and pass the arguments to Gunicorn. For example, you can run the following command to run your image with four sync workers and a Unix socket named /tmp/fastapi-app.sock:
  2. docker run --entrypoint gunicorn -p 8000:80 fastapi-app:v1 -w 4 -k sync -b unix:/tmp/fastapi-app.sock app:app
    
  3. Configure NGINX to use the Unix socket or the TCP port: You need to configure NGINX to use the Unix socket or the TCP port that you specified in the previous step, and proxy the requests to your FastAPI application. You can edit the server block that you created in the previous section, and change the proxy_pass directive accordingly. For example, if you used a Unix socket named /tmp/fastapi-app.sock, you can change the proxy_pass directive to:
  4. proxy_pass http://unix:/tmp/fastapi-app.sock;
    
  5. Test and reload NGINX: You need to test the configuration of NGINX and reload it to apply the changes. You can use the nginx command to test and reload NGINX. For example, you can run the following commands to test and reload NGINX:
  6. sudo nginx -t
    sudo nginx -s reload
    

Now you have successfully run your FastAPI application with Gunicorn and NGINX. You can access your application from the domain name or the IP address of your host machine, using HTTPS. You can also use the curl command to test your application from the terminal. For example, you can run the following command to test your application:

curl -k https://example.com

Congratulations! You have completed this tutorial on how to deploy your FastAPI application using Docker, NGINX and Gunicorn. You have learned the basics of these tools and how to configure them for optimal performance. You have also created a fully functional and scalable web API that can handle high traffic and complex requests. We hope you enjoyed this tutorial and found it useful for your web development projects.

10. Conclusion

In this tutorial, you have learned how to deploy your FastAPI application using Docker, NGINX and Gunicorn. You have learned the basics of these tools and how to configure them for optimal performance. You have also created a fully functional and scalable web API that can handle high traffic and complex requests.

Here are the main points that you have covered in this tutorial:

  • FastAPI is a modern and fast web framework for building APIs with Python. It has many features that make it easy and enjoyable to develop web applications, such as automatic documentation, data validation, authentication, testing, and more.
  • Docker is a software platform that allows you to build, run, and share applications using containers. Containers are isolated environments that contain everything an application needs to run, such as code, libraries, dependencies, and configuration. Docker makes it easy to create, deploy, and manage containers across different platforms and environments.
  • NGINX is a web server that can also act as a reverse proxy, load balancer, and HTTP cache. NGINX is known for its high performance, stability, and scalability. It can handle millions of concurrent connections and serve static and dynamic content efficiently. NGINX can also improve the security and reliability of your web application by providing features such as SSL/TLS encryption, HTTP/2 support, rate limiting, and access control.
  • Gunicorn is a Python WSGI HTTP server that can run multiple workers to handle requests. Gunicorn is compatible with many web frameworks, including FastAPI. Gunicorn can work well with NGINX, as NGINX can handle the incoming connections and pass them to Gunicorn workers via a Unix socket or a TCP port. Gunicorn can also handle the communication between the web application and the database or other services.
  • Dockerfile is a text file that contains the instructions to build a Docker image. You can use a Dockerfile to specify the base image, the dependencies, the commands, and the ports for your FastAPI application. You can also use a Dockerfile to automate the building and running of your Docker image.

We hope you enjoyed this tutorial and found it useful for your web development projects. If you have any questions or feedback, feel free to leave a comment below. Thank you for reading and happy coding!

Leave a Reply

Your email address will not be published. Required fields are marked *