DevOps Project — Part 3

Dergham Lahcene
6 min readFeb 20, 2023

--

Containerize FastAPI Application (CRUD App) with Postgresql Database

Containerization

Once you’ve developed the FastAPI application ( Part 2 ), you’ll need to containerize it using Docker. To do this, you’ll need to create a Dockerfile that specifies how to build the Docker image for your application.

What is Docker:

Docker is a platform for developing, shipping, and running applications. It allows developers to package their applications and all their dependencies into a single container that can run anywhere, providing a consistent and reproducible environment.

  1. Dockerfile: A Dockerfile is a text file that contains a set of instructions for building a Docker image. It describes the base image to use, the commands to run, and the files to add to the image.
  2. Docker image: A Docker image is a lightweight, standalone, and executable package that contains everything needed to run an application, such as code, libraries, and system tools. It is built from a Dockerfile and can be deployed and run on any infrastructure that supports Docker.
  3. Docker container: A Docker container is a running instance of a Docker image. It provides an isolated environment for running an application and includes everything needed to run the application, such as the code, dependencies, and configuration.
  4. Docker Compose: Docker Compose is a tool for defining and running multi-container Docker applications. It allows you to define a set of services that make up your application, along with their configuration and dependencies, in a YAML file. You can then use the docker-compose command to start, stop, and manage your application.

Overall, Docker provides a powerful platform for building, packaging, and running applications in a consistent and reproducible way, making it easier to develop, deploy, and scale applications.

Create Dockerfile for the App and build it:

Here are some best practices for Dockerizing a FastAPI application:

  1. Use a lightweight base image: Choose a base image that is lightweight and specific to your needs. Avoid using a generic base image like Ubuntu, as it can be quite large and include unnecessary packages.
  2. Minimize the number of layers: Try to minimize the number of layers in your Dockerfile. This can help reduce the size of your final image and speed up the build process.
  3. Copy only necessary files: Copy only the necessary files into your Docker image. This can help reduce the size of your final image.
  4. Use multi-stage builds: Use multi-stage builds to separate the build process from the final image. This can help reduce the size of the final image by discarding any unnecessary files from the build stage.
  5. Set environment variables: Use environment variables to configure your FastAPI application. This can help make your application more portable and easier to configure.
  6. Use a non-root user: Use a non-root user to run your application. This can help improve the security of your application.

Here’s an example Dockerfile for a FastAPI application:

# Use a lightweight base image
FROM tiangolo/uvicorn-gunicorn-fastapi:python3.10-slim as base

# Copy only necessary files
COPY requirements.txt ./

# Install dependencies
RUN apt-get update && apt-get install -y \
build-essential \
libpq-dev \
&& rm -rf /var/lib/apt/lists/*
RUN pip install --no-cache-dir -r requirements.txt

# Copy application code
COPY ./ ./

# Create and activate virtual environment
RUN python -m venv /opt/venv
ENV PATH="/opt/venv/bin:$PATH"

# Set environment variables
ENV APP_MODULE=main:app
ENV PORT=5000

# Use a non-root user
USER 1000

# Start the application
CMD ["uvicorn", "--host", "0.0.0.0", "--port", "5000", "main:app"]

To build the Docker image for your FastAPI application, you can follow these steps:

  1. Create a Dockerfile in your FastAPI project directory. You can use the example Dockerfile from my previous answer as a starting point.
  2. Open a terminal and navigate to your project directory.
  3. Run the following command to build the Docker image:
docker build -t your-image-name .

Replace your-image-name with the name you want to give your Docker image. The . at the end of the command specifies the current directory as the build context.

4. Wait for the image to build. This may take a few minutes depending on the size of your application and the complexity of your Dockerfile.

5. Once the build is complete, you can verify that the image was created by running the following command:

docker images

This will display a list of all the Docker images on your system, including the one you just created.

Your FastAPI application is now Dockerized and ready to run in a container. You can run the container using the docker run command and specifying the image name and any necessary options.

To run the container for your Dockerized FastAPI application, you can follow these steps:

  1. Open a terminal and navigate to your project directory.
  2. Run the following command to start the container:
docker run -p 5000:5000 your-image-name

Replace your-image-name with the name you gave your Docker image when you built it.

The -p option specifies the port mapping between the container and the host. In this example, we're mapping port 5000 on the host to port 5000in the container. If your FastAPI application is running on a different port, you'll need to adjust the port mapping accordingly.

3. Once the container is running, you can access your FastAPI application by opening a web browser and navigating to http://localhost:5000.

If your FastAPI application has a different root path, you’ll need to include that in the URL. For example, if your application’s root path is /api, you would navigate to http://localhost:5000/api.

That’s it! Your FastAPI application is now running in a Docker container and is accessible from your web browser. You can stop the container at any time by pressing Ctrl+C in the terminal where it's running.

Compose your app :

Docker Compose is a tool for defining and running multi-container Docker applications. It makes it easy to set up and run multiple Docker containers that work together.

Here’s an example docker-compose.yml file for a FastAPI application with a PostgreSQL database:

version: '3'

services:
app:
build: .
ports:
- "5000:5000"
depends_on:
- db
environment:
- DATABASE_URL=postgresql://fatsapi_db_user:fatsapi_db_passwd@db:5432/fatsapi_db
command: uvicorn main:app --host 0.0.0.0 --port 5000

db:
image: postgres
restart: always
environment:
POSTGRES_USER: fatsapi_db_user
POSTGRES_PASSWORD: fatsapi_db_passwd
POSTGRES_DB: fatsapi_db
ports:
- "5432:5432"

n this example, we define two services: app and db. The app service builds a Docker image from the current directory (.) and runs the FastAPI application using Uvicorn. It also maps port 5000 on the host to port 5000 in the container.

The db service uses the official PostgreSQL Docker image and sets environment variables for the database user, password, and name.

The app service depends on the db service, which means that Docker Compose will start the db service before the app service.

To start the Docker containers, navigate to the directory containing the docker-compose.yml file and run the following command:

docker-compose up

This will start the containers and show the logs in the terminal. You can access the FastAPI application by opening a web browser and navigating to http://localhost:5000.

To stop the Docker containers, press Ctrl+C in the terminal where they're running, or run the following command:

docker-compose down

Example of docker-compose up command output :

And now you can navigate to http://localhost:5000/

Your app is dockerized and ready !!! Congratulations

Next step : Deploy the FastAPI application and the Postgres Database with Kubernetes

Thank you for your attention ❤

Lahcene Dergham

--

--