3-setting-up-a-cicd-pipeline-for-python-applications-using-docker-and-github-actions.html

Setting Up a CI/CD Pipeline for Python Applications Using Docker and GitHub Actions

In today's fast-paced software development landscape, Continuous Integration (CI) and Continuous Deployment (CD) pipelines are essential for automating the testing, building, and deployment of applications. For Python developers, leveraging tools like Docker and GitHub Actions can streamline this process. In this article, we will explore how to set up a CI/CD pipeline for Python applications using these technologies, ensuring your code is efficiently tested and deployed with minimal manual intervention.

What is CI/CD?

Continuous Integration (CI) is a development practice where developers frequently integrate their code changes into a shared repository. Each integration is automatically built and tested, allowing teams to detect errors quickly.

Continuous Deployment (CD) is an extension of CI, where the application is automatically deployed to production after passing all tests. Together, CI/CD enhances code quality, reduces integration issues, and accelerates the deployment process.

Why Use Docker and GitHub Actions?

Docker

Docker is a platform that allows you to develop, ship, and run applications in containers. By using Docker, you can ensure that your application runs consistently regardless of the environment. This eliminates the "it works on my machine" problem.

GitHub Actions

GitHub Actions is a CI/CD service integrated into GitHub that allows you to automate your workflow directly in your repository. With GitHub Actions, you can define workflows that are triggered by events like code pushes, pull requests, or even on a schedule.

Use Case: Setting Up a CI/CD Pipeline for a Python Application

Let's walk through setting up a CI/CD pipeline for a simple Python application using Docker and GitHub Actions.

Step 1: Create a Simple Python Application

First, create a basic Python application. For this example, we'll use a simple Flask app. Here’s how to set it up:

Directory Structure:

my-python-app/
│
├── app.py
├── requirements.txt
├── Dockerfile
└── .github/
    └── workflows/
        └── ci-cd.yml

app.py:

from flask import Flask

app = Flask(__name__)

@app.route('/')
def hello():
    return "Hello, World!"

if __name__ == "__main__":
    app.run(host='0.0.0.0', port=5000)

requirements.txt:

Flask==2.2.2

Step 2: Create a Dockerfile

Next, we need to create a Dockerfile to containerize our application.

Dockerfile:

# Use the official Python image
FROM python:3.10-slim

# Set the working directory
WORKDIR /app

# Copy the requirements file
COPY requirements.txt .

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

# Copy the application code
COPY . .

# Expose the port the app runs on
EXPOSE 5000

# Define the command to run the app
CMD ["python", "app.py"]

Step 3: Set Up GitHub Actions Workflow

Now, let’s create a GitHub Actions workflow to automate our CI/CD process. This workflow will build the Docker image, run tests, and deploy the application.

.github/workflows/ci-cd.yml:

name: CI/CD Pipeline

on:
  push:
    branches:
      - main

jobs:
  build:
    runs-on: ubuntu-latest

    steps:
      - name: Checkout code
        uses: actions/checkout@v2

      - name: Set up Docker Buildx
        uses: docker/setup-buildx-action@v1

      - name: Log in to Docker Hub
        uses: docker/login-action@v1
        with:
          username: ${{ secrets.DOCKER_USERNAME }}
          password: ${{ secrets.DOCKER_PASSWORD }}

      - name: Build and push Docker image
        uses: docker/build-push-action@v2
        with:
          context: .
          push: true
          tags: your-dockerhub-username/my-python-app:latest

  deploy:
    runs-on: ubuntu-latest
    needs: build

    steps:
      - name: Deploy to Server
        run: |
          ssh user@your-server-ip 'docker pull your-dockerhub-username/my-python-app:latest && docker run -d -p 5000:5000 your-dockerhub-username/my-python-app:latest'

Step 4: Configure GitHub Secrets

To protect sensitive data, like your Docker Hub credentials, you should add them as secrets in your GitHub repository:

  1. Go to your repository on GitHub.
  2. Click on "Settings" > "Secrets and variables" > "Actions".
  3. Add DOCKER_USERNAME and DOCKER_PASSWORD as secrets.

Step 5: Testing the CI/CD Pipeline

Once everything is set up, make a change to your Python application (for example, update the message in app.py), commit your changes, and push to the main branch. This will trigger the GitHub Actions workflow.

Troubleshooting Common Issues

  • Docker Image Build Failures: Ensure your Dockerfile syntax is correct and all dependencies are listed in requirements.txt.
  • Workflow Not Triggering: Check your branch name in the workflow file; it should match the branch you're pushing to.
  • Deployment Issues: Verify the SSH connection to your server and ensure Docker is installed and running.

Conclusion

Setting up a CI/CD pipeline for Python applications using Docker and GitHub Actions not only automates your workflow but also enhances your development process by ensuring consistent builds and deployments. By following the steps outlined in this guide, you can streamline your Python application development and focus more on writing code rather than managing deployments.

With continuous integration and deployment, your team can work more efficiently, reduce bugs, and deliver features faster. Start implementing your CI/CD pipeline today and experience the benefits firsthand!

SR
Syed
Rizwan

About the Author

Syed Rizwan is a Machine Learning Engineer with 5 years of experience in AI, IoT, and Industrial Automation.