2-how-to-deploy-a-fastapi-application-on-docker-with-postgresql.html

How to Deploy a FastAPI Application on Docker with PostgreSQL

FastAPI is a modern, fast (high-performance), web framework for building APIs with Python 3.6+ based on standard Python type hints. It is known for its speed and ease of use, making it an excellent choice for developing microservices and building applications quickly. When combined with Docker, FastAPI can be easily deployed across various environments, ensuring consistency and reliability. In this article, we will walk through the steps to deploy a FastAPI application using Docker along with PostgreSQL as our database.

Why Use Docker for Deployment?

Before diving into the implementation, let’s understand why Docker is a preferred choice for deploying applications:

  • Isolation: Docker containers encapsulate an application and its dependencies, ensuring that it runs the same way regardless of where it's deployed.
  • Scalability: Docker makes scaling applications much simpler. You can easily create multiple instances of your application.
  • Portability: A Docker image can be run on any system that supports Docker, making it easy to move from development to production.
  • Environment Consistency: With Docker, you can ensure that your development, testing, and production environments are consistent.

Prerequisites

Before we begin, ensure you have the following installed on your machine:

  • Python 3.6 or higher
  • Docker and Docker Compose
  • PostgreSQL

Step 1: Setting Up Your FastAPI Application

First, let’s create a simple FastAPI application. Create a new directory for your project and navigate into it:

mkdir fastapi-docker-postgresql
cd fastapi-docker-postgresql

Now, create a file named main.py and add the following code:

from fastapi import FastAPI
from pydantic import BaseModel
import asyncpg
import os

app = FastAPI()

DATABASE_URL = os.getenv("DATABASE_URL")

class Item(BaseModel):
    name: str
    description: str = None

@app.get("/")
async def root():
    return {"message": "Welcome to FastAPI with PostgreSQL!"}

@app.post("/items/")
async def create_item(item: Item):
    conn = await asyncpg.connect(DATABASE_URL)
    await conn.execute('''
        INSERT INTO items(name, description) VALUES($1, $2)
    ''', item.name, item.description)
    await conn.close()
    return item

Explanation

  • We import FastAPI and create an instance of it.
  • We define a simple GET endpoint and a POST endpoint to create items.
  • The application connects to a PostgreSQL database using the asyncpg library.

Step 2: Create a PostgreSQL Database

Next, you need to set up a PostgreSQL database. For this, we will use Docker to run a PostgreSQL container. Create a file named docker-compose.yml in the same directory:

version: '3.8'

services:
  db:
    image: postgres:13
    environment:
      POSTGRES_DB: fastapi_db
      POSTGRES_USER: user
      POSTGRES_PASSWORD: password
    ports:
      - "5432:5432"

  web:
    build: .
    ports:
      - "8000:8000"
    environment:
      DATABASE_URL: postgres://user:password@db/fastapi_db
    depends_on:
      - db

Explanation

  • db service: Runs a PostgreSQL database with specified environment variables for the database name, user, and password.
  • web service: Builds our FastAPI application and sets the DATABASE_URL environment variable needed for database connectivity.

Step 3: Dockerfile for FastAPI Application

Next, we need to create a Dockerfile to define how our FastAPI application will be built inside a Docker container. Create a file named Dockerfile:

FROM python:3.9

WORKDIR /app

COPY requirements.txt requirements.txt
RUN pip install --no-cache-dir -r requirements.txt

COPY . .

CMD ["uvicorn", "main:app", "--host", "0.0.0.0", "--port", "8000", "--reload"]

Explanation

  • We are using the official Python image and setting the working directory.
  • The requirements.txt file (which we will create next) contains our application dependencies.
  • Finally, we specify the command to run the FastAPI application using uvicorn.

Step 4: Create requirements.txt

Create a requirements.txt file in the same directory and add the following dependencies:

fastapi
uvicorn
asyncpg

Step 5: Build and Run the Docker Containers

Now that everything is set up, you can build and run the Docker containers using Docker Compose. Run the following command in your terminal:

docker-compose up --build

This command will build the images and start both the PostgreSQL and FastAPI services. If everything goes well, you should see output indicating that both services are running.

Step 6: Testing Your FastAPI Application

Once the containers are running, you can test your FastAPI application. Open your web browser and navigate to http://localhost:8000, where you should see a welcome message.

To test the POST endpoint, you can use a tool like Postman or curl. Here’s how to do it with curl:

curl -X POST "http://localhost:8000/items/" -H "Content-Type: application/json" -d '{"name": "Item 1", "description": "This is a test item."}'

Troubleshooting Common Issues

  • Database Connection Errors: Ensure that the PostgreSQL container is running and that the environment variables are set correctly.
  • Dependency Issues: If you encounter errors while installing dependencies, check your requirements.txt for typos or version mismatches.

Conclusion

Deploying a FastAPI application with PostgreSQL using Docker is a straightforward process that can significantly streamline your development workflow. By following the steps outlined in this article, you can create a portable, scalable, and consistent environment for your Python applications. Whether you are building microservices or API-driven applications, this setup can enhance your development agility and deployment efficiency. Happy coding!

SR
Syed
Rizwan

About the Author

Syed Rizwan is a Machine Learning Engineer with 5 years of experience in AI, IoT, and Industrial Automation.