You are currently viewing Part 7: Containerizing your microservice with Docker

Part 7: Containerizing your microservice with Docker

  • Post author:
  • Post category:Python

Welcome to Part 7 of the tutorial series: “Build a Production-Ready User Management Microservice with Flask and SQLAlchemy: A Step-by-Step Guide”. In this part, you’ll containerize your Flask microservice using Docker. Containerization simplifies deployment, ensures consistency across environments, and makes your application portable. By the end of this tutorial, you’ll have a Dockerized Flask microservice ready for deployment.

What You learn in part 7

  • Understand the benefits of containerization for microservices.
  • Create a Dockerfile for your Flask application.
  • Use Docker Compose to manage multi-container setups.
  • Run your microservice in a containerized environment.
  • Optimize your Docker setup for production.

Prerequisites

Before you begin, ensure you’ve completed Part 1Part 2Part 3Part 4Part 5, and Part 6 of the series. You should have:

  • A fully functional Flask microservice.
  • Unit tests for your application.
  • Docker installed on your machine. If not, download and install Docker from here.

Step 1: Understand the benefits of containerization

Containerization packages your application and its dependencies into a single, lightweight, and portable unit called a container. Benefits include:

  • Consistency: Containers ensure your application runs the same way in development, testing, and production.
  • Isolation: Each container runs in its own isolated environment, avoiding conflicts between dependencies.
  • Portability: Containers can run on any system with Docker installed, making deployment easier.
  • Scalability: Containers can be easily scaled up or down to handle varying loads.

Step 2: Create a Dockerfile

Dockerfile is a script that defines how to build a Docker image for your application. Place the Dockerfile in the root directory of your project (at the same level as README.md and user_management_microservice). Here’s the Dockerfile tailored to your project structure:

# Use an official Python runtime as the base image
FROM python:3.9-slim

# Set environment variables
ENV PYTHONDONTWRITEBYTECODE=1
ENV PYTHONUNBUFFERED=1

# Set the working directory in the container
WORKDIR /app

# Copy the requirements file into the container
COPY requirements.txt /app/
COPY user_management_microservice/requirements.txt /app/user_management_microservice/

# Install dependencies
RUN pip install --no-cache-dir -r requirements.txt
RUN pip install --no-cache-dir -r user_management_microservice/requirements.txt

# Copy the application code into the container
COPY . /app/

# Expose the port the app runs on
EXPOSE 5000

# Set the entrypoint command to run the Flask application
CMD ["python", "user_management_microservice/run.py"]

Explanation

  • FROM python:3.9-slim: Uses a lightweight Python 3.9 image as the base.
  • ENV PYTHONDONTWRITEBYTECODE=1: Prevents Python from writing .pyc files, reducing image size.
  • ENV PYTHONUNBUFFERED=1: Ensures Python output is sent straight to the terminal (no buffering).
  • WORKDIR /app: Sets /app as the working directory inside the container.
  • COPY requirements.txt /app/: Copies the root requirements.txt file.
  • COPY user_management_microservice/requirements.txt /app/user_management_microservice/: Copies the requirements.txt file inside the user_management_microservice directory.
  • RUN pip install: Installs dependencies from both requirements.txt files.
  • COPY . /app/: Copies the entire project directory into the container.
  • EXPOSE 5000: Exposes port 5000 for the Flask application.
  • CMD ["python", "user_management_microservice/run.py"]: Runs the Flask application using the run.py file.

Step 3: Build the docker image

Build the Docker image using the docker build command:

docker build -t user_management_microservice .
  • -t user-management-microservice: Tags the image with the name user_management_microservice.
  • .: Specifies the build context (current directory).

Step 4: Run the docker container

Run the container using the docker run command:

docker run -p 5000:5000 user_management_microservice
  • -p 5000:5000: Maps port 5000 on your local machine to port 5000 in the container.
  • user-management-microservice: The name of the Docker image to run.

Test one of your APIs endpoint to see your Flask microservice running in a Docker container.

Step 5: Use Docker Compose for Multi-Container Setup

Docker Compose simplifies managing multi-container applications. Create a docker-compose.yml file in the root of your project:

services:
  web:
    image: user-management-microservice
    build: .
    ports:
      - "5000:5000"
    environment:
      FLASK_ENV: production
      DATABASE_URL: postgresql://user:password@db:5432/user_management
    depends_on:
      - db

  db:
    image: postgres:13
    environment:
      POSTGRES_USER: user
      POSTGRES_PASSWORD: password
      POSTGRES_DB: user_management
    volumes:
      - postgres_data:/var/lib/postgresql/data

volumes:
  postgres_data:

Explanation

  • web: Defines the Flask application service.
    • image: Uses the user-management-microservice image.
    • build: Builds the image from the current directory.
    • ports: Maps port 5000.
    • environment: Sets environment variables for Flask.
    • depends_on: Ensures the db service starts before the web service.
  • db: Defines the PostgreSQL database service.
    • image: Uses the official PostgreSQL 13 image.
    • environment: Sets database credentials.
    • volumes: Persists database data in a Docker volume.

Step 6: Run the application with docker compose

Start the application using Docker Compose:

docker-compose up

This command:

  • Builds the web service (if not already built).
  • Starts the web and db services.
  • Attaches logs to the terminal.

Test one of your APIs endpoint to see your Flask microservice running in a Docker container.

Step 7: Optimize for production

To prepare your Docker setup for production:

  1. Use environment variables for secrets:
    • Store sensitive data (e.g., database credentials, JWT secret) in environment variables or a secrets manager.
  2. Use a production web server:
    • Replace Flask’s development server with gunicorn or uWSGI.
  3. Minimize image Size:
    • Use multi-stage builds to reduce the final image size.
  4. Add health checks:
    • Add health checks to ensure your application is running correctly.

Your microservice is now containerized and ready for deployment.

Full Code for Part 7

You can find the complete code for this tutorial in the GitHub repository.

Facebook Comments