How to Set Up a FastAPI Project with PostgreSQL and Docker
FastAPI is a modern, fast (high-performance), web framework for building APIs with Python 3.7+ based on standard Python type hints. It’s perfect for building applications that require speed and efficiency, and when combined with PostgreSQL—a powerful, open-source relational database—you can build robust applications. Using Docker helps streamline development and deployment by containerizing your application. In this article, we will walk through the steps to set up a FastAPI project with PostgreSQL using Docker.
Why Choose FastAPI and PostgreSQL?
FastAPI
- High Performance: Built on Starlette for the web parts and Pydantic for the data parts, FastAPI is designed for performance.
- Easy to Use: FastAPI's intuitive design allows developers to build APIs quickly.
- Automatic Documentation: FastAPI automatically generates interactive API documentation using Swagger UI and ReDoc.
PostgreSQL
- Robust Features: PostgreSQL supports advanced data types and offers powerful querying capabilities.
- ACID Compliance: It provides strong consistency guarantees, making it ideal for applications requiring reliability.
- Open Source: Being open-source, PostgreSQL can be freely used and modified.
Docker
- Environment Consistency: Docker ensures that your application runs the same way across different environments.
- Isolation: Each service can run in its own container, reducing conflicts and improving security.
- Easy Deployment: Docker simplifies the deployment process, enabling you to package your application and its dependencies together.
Prerequisites
Before you begin, ensure you have the following installed on your machine: - Python 3.7+ - Docker and Docker Compose - PostgreSQL
Step 1: Create a Project Directory
Create a new directory for your FastAPI project:
mkdir fastapi-postgres-docker
cd fastapi-postgres-docker
Step 2: Set Up Docker Compose
Create a docker-compose.yml
file to define the services for your application.
version: '3.8'
services:
db:
image: postgres:latest
environment:
POSTGRES_DB: mydatabase
POSTGRES_USER: user
POSTGRES_PASSWORD: password
ports:
- "5432:5432"
api:
build: .
volumes:
- ./app:/app
ports:
- "8000:8000"
depends_on:
- db
Explanation:
- db: This service runs the PostgreSQL database.
- api: This service will run the FastAPI application.
Step 3: Create the FastAPI Application
Create a new directory for your FastAPI application and initialize it:
mkdir app
cd app
touch main.py
Code Example: FastAPI Setup
Open main.py
and add the following code:
from fastapi import FastAPI
from pydantic import BaseModel
import databases
import sqlalchemy
DATABASE_URL = "postgresql://user:password@db/mydatabase"
database = databases.Database(DATABASE_URL)
metadata = sqlalchemy.MetaData()
app = FastAPI()
class Item(BaseModel):
name: str
description: str = None
@app.on_event("startup")
async def startup():
await database.connect()
@app.on_event("shutdown")
async def shutdown():
await database.disconnect()
@app.post("/items/")
async def create_item(item: Item):
query = "INSERT INTO items(name, description) VALUES (:name, :description)"
await database.execute(query, values={"name": item.name, "description": item.description})
return item
@app.get("/items/{item_id}")
async def read_item(item_id: int):
query = "SELECT * FROM items WHERE id = :id"
return await database.fetch_one(query, values={"id": item_id})
Explanation:
- DATABASE_URL: This connects FastAPI to the PostgreSQL database.
- Item Model: A Pydantic model to validate the incoming request data.
- Startup and Shutdown Events: Connect and disconnect from the database when the application starts and stops.
Step 4: Create a Dockerfile
Create a Dockerfile
in the project root to define how to build the FastAPI application.
FROM python:3.9
WORKDIR /app
COPY ./app /app
RUN pip install fastapi[all] databases[postgresql] sqlalchemy psycopg2-binary
CMD ["uvicorn", "main:app", "--host", "0.0.0.0", "--port", "8000", "--reload"]
Explanation:
- Base Image: Using the Python 3.9 image.
- Working Directory: Set to
/app
. - Dependencies: Install FastAPI, databases, SQLAlchemy, and PostgreSQL driver.
- Command: Start the FastAPI server using Uvicorn.
Step 5: Run the Docker Containers
In the project root directory, run the following command to build and start your containers:
docker-compose up --build
This command builds the images and starts the services defined in the docker-compose.yml
file.
Step 6: Test Your API
Once the containers are up, you can test your FastAPI application. Open your web browser or a tool like Postman and navigate to http://localhost:8000/docs
to access the interactive API documentation.
Example Requests:
- Create an Item:
- POST to
http://localhost:8000/items/
with JSON body:json { "name": "Sample Item", "description": "This is a sample item" }
- Get Item by ID:
- GET
http://localhost:8000/items/1
Troubleshooting Tips
- If you encounter a connection error, ensure PostgreSQL is running and accessible.
- Verify that the environment variables in the
docker-compose.yml
match those used in your FastAPI application.
Conclusion
Setting up a FastAPI project with PostgreSQL and Docker may seem daunting, but by following the steps outlined in this article, you can quickly create a robust API. FastAPI's speed and ease of use, combined with PostgreSQL's reliability and Docker's containerization, make for a powerful stack suitable for modern web applications. Start building your applications today, and take advantage of the performance and efficiency that these technologies offer!