Introduction
Continuous Integration and Continuous Deployment (CI/CD) are essential for modern software development. In this tutorial, I will walk you through setting up a CI/CD pipeline for a Flask application using GitHub Actions and Docker. By the end of this guide, you will have an automated workflow that builds, tests, and pushes a Docker image to Docker Hub.
Prerequisites
Before we get started, ensure you have the following:
- Python 3.x installed on your machine.
- Docker installed and configured.
- A GitHub repository for your Flask project.
- A Docker Hub account to store container images.
Step 1: Setting Up the Flask Application
Let's start by creating a simple Flask application.
-
Create a project directory:
mkdir flask-cicd && cd flask-cicd
-
Create a virtual environment and activate it:
python3 -m venv venv source venv/bin/activate # On macOS/Linux venv\Scripts\activate # On Windows
-
Install Flask:
pip install flask
-
Create an
app.py
file:
from flask import Flask app = Flask(__name__) @app.route('/') def home(): return "Hello, Flask CI/CD!" if __name__ == '__main__': app.run(host='0.0.0.0', port=5000)
-
Create a
requirements.txt
file:
flask
Step 2: Dockerizing the Flask Application
Create a Dockerfile
in the project directory:
# Use official Python image
FROM python:3.10
WORKDIR /app
COPY requirements.txt requirements.txt
RUN pip install --no-cache-dir -r requirements.txt
COPY . .
EXPOSE 5000
CMD ["python", "app.py"]
To test the Docker container locally, build and run it:
docker build -t flask-cicd .
docker run -p 5000:5000 flask-cicd
Step 3: Setting Up GitHub Actions for CI/CD
Now, we will create a GitHub Actions workflow to automate building and pushing our Docker image to Docker Hub.
- Inside your project, create
.github/workflows/main.yml
and add the following:
name: Flask CI/CD
on:
push:
branches: [ "main" ]
pull_request:
branches: [ "main" ]
permissions:
contents: read
jobs:
build:
runs-on: ubuntu-latest
steps:
- name: Checkout Repository
uses: actions/checkout@v4
- name: Set up Python 3.10
uses: actions/setup-python@v3
with:
python-version: "3.10"
- name: Install Dependencies
run: |
python -m pip install --upgrade pip
pip install flake8 pytest
if [ -f requirements.txt ]; then pip install -r requirements.txt; fi
- name: Lint with flake8
run: |
flake8 . --count --select=E9,F63,F7,F82 --show-source --statistics
flake8 . --count --exit-zero --max-complexity=10 --max-line-length=127 --statistics
- name: Log in to Docker Hub
uses: docker/login-action@v3
with:
username: ${{ secrets.DOCKER_USERNAME }}
password: ${{ secrets.DOCKER_PASSWORD }}
- name: Set up Docker Buildx
uses: docker/setup-buildx-action@v3
- name: Build and Push Docker Image
uses: docker/build-push-action@v5
with:
context: .
file: Dockerfile
push: true
tags: ${{ secrets.DOCKER_USERNAME }}/flask-app:latest
Also, remember to create a .gitignore
file and .dockerignore
file.
Step 4: Configuring GitHub Secrets
To securely authenticate with Docker Hub, add the following GitHub Secrets in your repository:
-
DOCKER_USERNAME
: Your Docker Hub username. -
DOCKER_PASSWORD
: Your Docker Hub password.
Step 5: Pushing Code and Running the Pipeline
Now, push your code to GitHub:
git init
git add .
git commit -m "Initial commit"
git branch -M main
git remote add origin
git push -u origin main
Once pushed, GitHub Actions will automatically run the workflow. You can check the status under the Actions tab in your repository.
Conclusion
Congratulations! 🎉 You have successfully set up a CI/CD pipeline for your Flask application using GitHub Actions and Docker. Now, every time you push code, your application will be tested, built, and deployed automatically.
Feel free to share your thoughts and improvements in the comments below! 🚀