Automation

Automating CI/CD with GitHub Actions for Dockerized Python Apps

Learn to automate CI/CD pipelines for Dockerized Python applications using GitHub Actions with step-by-step instructions.

5 min read

Learn how to automate CI/CD pipelines for Dockerized Python applications using GitHub Actions. This guide will walk you through setting up a deployment pipeline, highlighting best practices around security and troubleshooting.

Overview of CI/CD with GitHub Actions for Docker

Continuous Integration and Continuous Deployment (CI/CD) are foundational concepts in modern software development. CI/CD allows developers to automate the testing and deployment of applications, ensuring faster feedback loops and reliable delivery of code changes.

GitHub Actions is a powerful platform for implementing CI/CD workflows. It integrates directly with GitHub repositories and provides a seamless way to automate testing, building, and deploying processes. Docker, on the other hand, is a containerization platform that ensures software runs consistently across different environments.

By combining GitHub Actions and Docker in a CI/CD pipeline, developers can:

  • Automate the building and deployment of applications.
  • Ensure applications run the same in development and production.
  • Increase overall development speed and reliability.

Prerequisites

Before starting, ensure you have the following ready:

prerequisites

  • A Python application with a Dockerfile that builds the application.
  • An AWS EC2 instance to serve as a deployment environment.
  • Basic knowledge of GitHub repositories, Docker commands, and CI/CD principles.
  • Admin or write permissions to a GitHub repository to configure Actions workflows.
  • A Docker Hub account with a Personal Access Token for managing Docker images.
  • SSH access to your AWS EC2 instance.

Configuring Docker on EC2 Instance

Correctly setting up Docker on your EC2 instance is a fundamental step for deploying your application.

steps

  1. Connect to the EC2 instance via SSH.

    bash
    ssh -i your-key.pem ubuntu@<YOUR_INSTANCE_PUBLIC_IP>
  2. Update the package manager and install Docker.

bash
   sudo apt update # Update package manager
   sudo apt install -y docker.io # Install Docker

   # Start and enable Docker at boot
   sudo systemctl start docker
   sudo systemctl enable docker

   # Verify Docker installation
   docker --version # Docker version XX.X.X, build XXXXXX
  1. Add your user to the docker group to avoid using sudo for Docker commands.
bash
   sudo usermod -aG docker $USER
   newgrp docker # Apply group changes immediately
   docker run hello-world # Verify Docker access
  1. (Optional) Configure the firewall to allow inbound traffic on port 5000.
    bash
    sudo ufw allow 5000

Your EC2 instance is now ready with Docker installed and configured.


Setting Up Self-Hosted Runner for GitHub Actions

For this guide, we will configure a self-hosted GitHub Actions runner on the EC2 instance.

IT_GUIDES_COMPONENT_2 IT_GUIDES_COMPONENT_3

  1. Start the self-hosted runner and configure it to run as a background process.
bash
   ./run.sh & # Start in the background
   ps -ef | grep runner # Verify the process is running

Back in the GitHub repository, confirm that the runner status has updated to online.


Deploying Python Application with Workflow Files

We will now create and test a GitHub Actions workflow to automate building and deploying the Python application.

steps

  1. Create the directory structure for GitHub workflows.

    bash
    mkdir -p .github/workflows
  2. Write a GitHub Actions workflow YAML file, deploy.yml.

    yaml
    name: CI/CD Pipeline
    
    on:
      push:
        branches:
          - main
    
    jobs:
      build-deploy:
        runs-on: self-hosted
        steps:
        - name: Check out Code
          uses: actions/checkout@v3
    
        - name: Log in to Docker Hub
          run: echo "${{secrets.DOCKER_HUB_TOKEN}}" | docker login -u ${{secrets.DOCKER_HUB_USERNAME}} --password-stdin
    
        - name: Build Docker Image
          run: docker build -t ${{secrets.DOCKER_HUB_USERNAME}}/python-app:latest .
    
        - name: Push Docker Image to Registry
          run: docker push ${{secrets.DOCKER_HUB_USERNAME}}/python-app:latest
    
        - name: Deploy Docker Container
          run: |
            docker stop python-app || true
            docker rm python-app || true
            docker run -d -p 5000:5000 --name python-app ${{secrets.DOCKER_HUB_USERNAME}}/python-app:latest
  3. Add Docker Hub credentials securely to GitHub Secrets.

    • Navigate to Settings > Secrets and variables > Actions > New repository secret.
    • Add DOCKER_HUB_USERNAME and DOCKER_HUB_TOKEN.
  4. Test the pipeline:

    • Commit the changes to the main branch.
    • Navigate to the Actions tab to monitor workflow execution and confirm successful deployment.

Your Python application is now deployed on the EC2 instance.


Troubleshooting Common Pipeline Issues



FAQ

How do I fix GitHub Actions permission errors with Docker Hub?

Ensure your Docker Hub token is correctly scoped and updated with permissions for read, write, and delete operations.

Can I use GitHub-hosted runners instead of self-hosted ones?

Yes. Replace runs-on: self-hosted with a GitHub-hosted type, such as runs-on: ubuntu-latest, for convenience at scale.

What port does the Python Flask app expose by default?

The Flask app runs on port 5000 by default. Make sure this port is open in your EC2 instance security group.