Mastering CI/CD with GitHub Actions and Docker
- Published on
- Published on
- Blog Post views
- ... Views
- Reading time
- 2 min read

In todayโs fast-paced development world, automation is key.
Whether you're working solo or in a team, a strong CI/CD setup ensures reliability, efficiency, and peace of mind.
In this blog, Iโll walk you through how I implemented CI/CD in my own project using GitHub Actions and Dockerโfrom pull request checks to Docker Hub deployments.
๐ What is CI/CD and Why It Matters
In software projects, CI/CD (Continuous Integration and Continuous Deployment) plays a crucial role in maintaining the quality and reliability of the codebase. Whether itโs an open-source or private project, a robust CI/CD pipeline helps manage code changes, streamline development, and boost collaboration.
๐ Key Benefits
-
Code Integration
CI/CD pipelines automatically integrate code on every push, reducing conflicts and keeping branches aligned. -
Automated Testing
Unit, integration, and E2E tests run automatically, helping you catch bugs early. -
Workflows
Tools like GitHub Actions let you define automated workflows for builds, tests, deployments, and more. -
Code Quality Checks
Linting, static analysis, and security scans help ensure high standards. -
Deployment Automation
CD pipelines handle deployments reliably and consistently across environments.
โ๏ธ Setting Up CI with GitHub Actions
Letโs start by setting up a simple CI pipeline that ensures code builds successfully when a pull request is created.
๐ File Structure
Create a file at:
.github/workflows/build.yml
### ๐ ๏ธ CI Workflow Code
```yaml
name: Build on PR
on:
pull_request:
branches:
- main
jobs:
build:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v3
- name: Use Node.js
uses: actions/setup-node@v3
with:
node-version: '20'
- name: Install Dependencies
run: npm install
- name: Run Build
run: npm run build
โ What It Does
- Triggers on PRs to the
main
branch. - Uses an Ubuntu runner.
- Checks out code, sets up Node.js v20.
- Installs dependencies and runs the build command.
This ensures all PRs are validated for successful builds before merging.
๐ณ Dockerizing the App for CD
Before we can deploy, letโs containerize our app. Assume weโre deploying the user-app
from a monorepo.
๐ Dockerfile (docker/Dockerfile.user)
FROM node:20.12.0-alpine3.19
WORKDIR /usr/src/app
COPY package.json package-lock.json turbo.json tsconfig.json ./
COPY apps ./apps
COPY packages ./packages
RUN npm install
RUN npm run generate-prisma
RUN npm run build --filter=user-app
CMD ["npm", "run", "start-user-app"]
๐ Breakdown
- Uses a lightweight Node.js Alpine image.
- Sets up the working directory and copies configs and code.
- Installs dependencies, generates Prisma client, builds the specific app.
- Starts the user app.
๐ Continuous Deployment to Docker Hub
Now, letโs automate the deployment of this Docker image using GitHub Actions.
๐งช Prerequisites
-
Create Docker Hub account
-
Make a new repo on Docker Hub
-
Add GitHub secrets:
DOCKER_USERNAME
DOCKER_PASSWORD
(use access token)
๐ File Structure
Create:
.github/workflows/deploy.yml
๐งฉ Deployment Workflow Code
name: Build and Deploy to Docker Hub
on:
push:
branches:
- main
jobs:
build-and-push:
runs-on: ubuntu-latest
steps:
- name: Check Out Repo
uses: actions/checkout@v2
- name: Log in to Docker Hub
uses: docker/login-action@v2
with:
username: ${{ secrets.DOCKER_USERNAME }}
password: ${{ secrets.DOCKER_PASSWORD }}
- name: Build and Push Docker image
uses: docker/build-push-action@v4
with:
context: .
file: ./docker/Dockerfile.user
push: true
tags: your-dockerhub-username/your-repo-name:latest
- name: Verify Pushed Image
run: docker pull your-dockerhub-username/your-repo-name:latest
๐ Replace
Replace:
your-dockerhub-username
your-repo-name
with your actual Docker Hub credentials.
๐ง Summary
Weโve covered:
- Setting up a CI workflow to validate PR builds.
- Dockerizing a monorepo-based app.
- Automating Docker image builds and pushing to Docker Hub.
CI/CD pipelines like this one keep your development process efficient, collaborative, and production-ready.
๐ Source Code
You can explore the full implementation in my repository here: ๐ GitHub Repo