DEV Community

Hritik Raj
Hritik Raj

Posted on

Python Deployment: A Deep Dive into GitHub Actions and Docker

Cover image for a post about GitHub Actions and Python deployment

Hello everyone! ๐Ÿ‘‹

I'm currently on a learning journey into the world of DevOps and SRE, and I'm excited to share my experience with the DevOps SRE Daily Challenge.

This week's task was a big one: setting up a full CI/CD pipeline to deploy a Python application.

A huge shout-out to my mentor, Sagar Utekar, for guiding me through this. It was a fantastic learning experience, and I wanted to document the process for anyone else starting out.

๐Ÿ‘‰ You can check out the final code on my GitHub repo: Hritikraj8804/devops-python-app


What are GitHub Actions? (The Brains of the Operation) ๐Ÿง 

First things first, I had to understand the tool. GitHub Actions is a powerful CI/CD platform built right into GitHub. It lets you automate almost anything โ€” from running tests on every commit to deploying your application to the cloud.

The key components I learned about are:

  • Workflow: The main YAML file in .github/workflows/ that defines the process.
  • Event: The trigger, like a push to the main branch.
  • Job: A set of steps that run on a server.
  • Step: An individual task, like running a command.
  • Action: A reusable piece of code, often from the Marketplace (like actions/checkout).
  • Runner: The virtual server that executes your job.

My Goal: Automate Pushing a Docker Image to Docker Hub

Instead of deploying directly to a server via SSH, I decided to containerize my app with Docker.

The goal: automatically build a Docker image and push it to Docker Hub every time I pushed new code.

Hereโ€™s how I achieved it. ๐Ÿš€


Step 1: The Dockerfile - The Recipe for My App ๐Ÿ“œ

A Dockerfile is a script that tells Docker how to build your image. Itโ€™s the foundation of your container.

Hereโ€™s the Dockerfile I created for my simple Python Flask app:

# Use an official Python runtime as a parent image
FROM python:3.10-slim

# Set the working directory in the container
WORKDIR /app

# Copy the requirements file and install dependencies
COPY requirements.txt .
RUN pip install --no-cache-dir -r requirements.txt

# Copy the rest of the application's code
COPY . .

# Expose port 8000
EXPOSE 8000

# Command to run the application using Gunicorn
CMD ["gunicorn", "--bind", "0.0.0.0:8000", "app:app"]

Enter fullscreen mode Exit fullscreen mode

Step 2: Manual Build and Push (Practice Run) ๐Ÿ—๏ธ

Before automating, I verified the process manually.

  1. Build the image:

docker build -t my-python-app .

  1. Log in to Docker Hub:

docker login

  1. Tag for Docker Hub:

docker tag my-python-app hritikraj8804/my-python-app

  1. Push to Docker Hub:

docker push hritikraj8804/my-python-app

โœ… Success! My image was on Docker Hub. Now it was time to make GitHub handle this automatically.


The Magic: Automating with GitHub Actions โœจ

This is where it all came together. I created a workflow file at .github/workflows/docker-publish.yml.


The Secret Ingredient: Managing Secrets and Variables ๐Ÿ”‘

You canโ€™t just put your credentials directly in code! GitHub provides a secure way to manage this:

  • Secrets ๐Ÿคซ: For sensitive data like API keys and passwords. Theyโ€™re encrypted and hidden once set. I used these for DOCKERHUB_TOKEN.
  • Variables ๐Ÿ“: For non-sensitive values you want to reuse, like project names.

I went to Settings โ†’ Secrets and variables โ†’ Actions in my repo and added:

  • DOCKERHUB_USERNAME
  • DOCKERHUB_TOKEN

The Workflow File (docker-publish.yml)

This YAML file tells GitHub Actions exactly what to do.

name: Build and Push Docker Image

on:
  push:
    branches: [ main ]
  workflow_dispatch:

jobs:
  build-and-push:
    runs-on: ubuntu-latest
    steps:
      - name: Checkout code
        uses: actions/checkout@v4

      - name: Log in to Docker Hub
        uses: docker/login-action@v3
        with:
          username: ${{ secrets.DOCKERHUB_USERNAME }}
          password: ${{ secrets.DOCKERHUB_TOKEN }}

      - name: Build and push Docker image
        uses: docker/build-push-action@v5
        with:
          context: .
          push: true
          tags: ${{ secrets.DOCKERHUB_USERNAME }}/devops-python-app:latest
Enter fullscreen mode Exit fullscreen mode

Once I pushed this file to my main branch, GitHub Actions automatically kicked in and pushed my image to Docker Hub. ๐ŸŽ‰


What I Learned ๐Ÿ’ก

This challenge was a huge step forward for me.
Going from manual steps to a fully automated CI/CD pipeline felt like magic. โœจ

Key takeaways:

  • GitHub Actions is powerful and flexible for automation.
  • Docker makes applications portable and deployment-ready.
  • Secrets management is essential for security in DevOps.

๐Ÿ‘‰ If youโ€™re starting your DevOps journey, I highly recommend building something like this yourself. Nothing beats hands-on learning!


Top comments (0)