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 1, Part 2, Part 3, Part 4, Part 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
A 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:
- Use environment variables for secrets:
- Store sensitive data (e.g., database credentials, JWT secret) in environment variables or a secrets manager.
- Use a production web server:
- Replace Flask’s development server with
gunicorn
or uWSGI
.
- Minimize image Size:
- Use multi-stage builds to reduce the final image size.
- 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