This content originally appeared on DEV Community and was authored by Hritik Raj
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 themain
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"]
Step 2: Manual Build and Push (Practice Run)
Before automating, I verified the process manually.
- Build the image:
docker build -t my-python-app .
- Log in to Docker Hub:
docker login
- Tag for Docker Hub:
docker tag my-python-app hritikraj8804/my-python-app
- 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
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!
This content originally appeared on DEV Community and was authored by Hritik Raj