How to Deploy a FastAPI Application with Docker and PostgreSQL
Deploying web applications can often become a daunting task, especially when trying to manage dependencies, databases, and server configurations. However, with the right tools and techniques, you can streamline this process significantly. In this article, we will walk you through deploying a FastAPI application using Docker and PostgreSQL while ensuring that your application is maintainable, scalable, and efficient.
What is FastAPI?
FastAPI is a modern web framework for building APIs with Python 3.7+ based on standard Python type hints. It is known for its high performance, ease of use, and automatic generation of OpenAPI documentation. This makes it an excellent choice for developing RESTful APIs quickly and efficiently.
Why Use Docker?
Docker is a platform that enables developers to package applications into containers, ensuring that they run consistently across different computing environments. The benefits of using Docker include:
- Isolation: Each application runs in its own environment, eliminating conflicts between dependencies.
- Scalability: Docker makes it easy to scale applications by creating multiple containers.
- Portability: Docker containers can run on any system that supports Docker, making deployments easier.
Use Case: FastAPI with PostgreSQL
PostgreSQL is a powerful, open-source relational database system that is well-suited for complex queries and large datasets. Combining FastAPI with PostgreSQL in a Docker environment allows for rapid development and deployment of data-driven applications.
Prerequisites
Before we start, ensure you have the following installed:
- Python 3.7 or later
- Docker and Docker Compose
- Basic knowledge of Python and SQL
Step-by-Step Guide to Deploying FastAPI with Docker and PostgreSQL
Step 1: Setting Up the FastAPI Application
First, create a directory for your project:
mkdir fastapi-docker-postgres
cd fastapi-docker-postgres
Next, create a file named main.py
within this directory. This will contain your FastAPI application code:
# main.py
from fastapi import FastAPI
from pydantic import BaseModel
import uvicorn
import asyncpg
import os
app = FastAPI()
DATABASE_URL = os.getenv("DATABASE_URL")
class Item(BaseModel):
name: str
description: str = None
@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
@app.get("/items/")
async def read_items():
conn = await asyncpg.connect(DATABASE_URL)
rows = await conn.fetch("SELECT * FROM items")
await conn.close()
return rows
if __name__ == "__main__":
uvicorn.run(app, host="0.0.0.0", port=8000)
Step 2: Create the Database Setup
Next, create a PostgreSQL database that our FastAPI app will connect to. Create a setup.sql
file to create the necessary table:
-- setup.sql
CREATE TABLE IF NOT EXISTS items (
id SERIAL PRIMARY KEY,
name VARCHAR(100),
description TEXT
);
Step 3: Create the Dockerfile
Now, create a Dockerfile
in the same directory to define how your FastAPI application will be built:
# Dockerfile
FROM python:3.9
WORKDIR /app
COPY requirements.txt .
RUN pip install --no-cache-dir -r requirements.txt
COPY . .
CMD ["uvicorn", "main:app", "--host", "0.0.0.0", "--port", "8000"]
Step 4: Create the requirements.txt
Create a requirements.txt
file to list the dependencies:
fastapi
uvicorn
asyncpg
Step 5: Create the Docker Compose File
Docker Compose allows us to define and run multi-container Docker applications. Create a docker-compose.yml
file:
version: '3.8'
services:
db:
image: postgres:13
environment:
POSTGRES_DB: fastapi_db
POSTGRES_USER: user
POSTGRES_PASSWORD: password
volumes:
- postgres_data:/var/lib/postgresql/data
ports:
- "5432:5432"
web:
build: .
environment:
DATABASE_URL: postgres://user:password@db/fastapi_db
ports:
- "8000:8000"
depends_on:
- db
volumes:
postgres_data:
Step 6: Build and Run the Application
With everything set up, you can now build and run your application using Docker Compose. In the terminal, run:
docker-compose up --build
Step 7: Initialize the Database
To create the necessary table in PostgreSQL, you will need to execute the SQL commands defined in setup.sql
. You can do this by accessing the PostgreSQL container:
docker exec -it fastapi-docker-postgres_db_1 psql -U user -d fastapi_db -f /app/setup.sql
Step 8: Test Your FastAPI Application
Once your application is running, you can test it. Open your browser or use a tool like Postman to access the endpoints:
- To create an item:
POST http://localhost:8000/items/
- To fetch items:
GET http://localhost:8000/items/
Troubleshooting Common Issues
- Database Connection Errors: Ensure your environment variables are set correctly in the
docker-compose.yml
file. - Container Not Starting: Check the logs for errors with
docker-compose logs
. - Data Not Persisting: Ensure that you have defined a volume for PostgreSQL in your
docker-compose.yml
.
Conclusion
Deploying a FastAPI application with Docker and PostgreSQL allows you to create a robust and scalable solution for your API needs. By following the steps outlined in this guide, you can set up a development environment that is portable and easy to maintain. With the power of FastAPI and PostgreSQL, you can build high-performance applications with ease. Happy coding!