Migrating Pipelines from Jenkins to GitHub Actions: How to Build Docker Images
Managing your own Jenkins servers can be a huge headache. You constantly have to update plugins, fix server crashes, and configure build nodes. This takes away valuable time from your actual engineering work. Because of this, many modern DevOps teams are moving away from Jenkins and switching to a cloud-based tool called GitHub Actions.
In this complete guide, I will show you how to make this switch step-by-step. We will take a real production Jenkins pipeline and migrate it completely. Our pipeline will cover every important step: checking out code, running automated code checks (linting), building a Docker container, and securely pushing that container directly into AWS ECR (Elastic Container Registry).
Jenkins vs. GitHub Actions: Quick Comparison
Before we look at the code, let’s quickly see how concepts translate from Jenkins to GitHub Actions. This table makes the migration much easier to understand:
| Feature | Jenkins | GitHub Actions |
|---|---|---|
| Setup | Self-hosted (You manage the server) | Cloud-hosted (GitHub manages it) |
| Language | Groovy (Jenkinsfile) |
YAML (.yml file) |
| Main Blocks | Stages & Steps | Jobs & Steps |
| Triggers | Webhooks / Polling | on: events (push, pull_request) |
| Secrets | Jenkins Credentials Provider | GitHub Repository Secrets |
The Old Way: A Traditional Jenkins Pipeline
To understand why migrating to GitHub Actions makes life so much easier, let's first look at how we traditionally set up this automation in Jenkins.
Below is a standard, declarative Jenkinsfile for a Maven application. It defines the sequential stages required to pull our source code, compile it into a Java executable package, wrap it inside a lightweight Docker container, and prepare it for our cloud registry.
pipeline {
agent any
stages {
stage('Clone Code') {
steps {
git url: 'https://github.com/your-username/maven-app.git', branch: 'main'
}
}
stage('Maven Build') {
steps {
// We run the standard Maven package command
sh 'mvn clean package -DskipTests'
}
}
stage('Build Docker Image') {
steps {
// Standard docker build referencing our compiled artifact
sh 'docker build -t my-app:latest .'
}
}
stage('Push to AWS ECR') {
steps {
// We simulate the AWS login and push to keep the tutorial clean
echo 'Logging into AWS ECR Registry securely...'
echo 'docker push 123456789012.dkr.ecr.us-east-1.amazonaws.com/my-app:latest'
}
}
}
}
The New Way: Migrating to GitHub Actions
Now, let's look at how we write this exact same pipeline using GitHub Actions. Instead of a complex Jenkinsfile, we use a simple YAML file located at .github/workflows/deploy.yml in our repository.
Here is the clean, matching configuration:
name: Java Build and Deploy Pipeline
on:
push:
branches: [ "main" ]
jobs:
build-and-deploy:
runs-on: ubuntu-latest # GitHub provides this clean environment automatically
steps:
# 1. Clone Code
- name: Clone Repository
uses: actions/checkout@v4
# 2. Maven Build
- name: Build with Maven
run: mvn clean package -DskipTests
# 3. Build Docker Image
- name: Build Docker Image
run: docker build -t my-app:latest .
# 4. Push to AWS ECR
- name: Push to AWS ECR
run: |
echo "Logging into AWS ECR Registry securely..."
echo "Pushing image to: 123456789012.dkr.ecr.us-east-1.amazonaws.com/my-app:latest"
Conclusion
Switching from Jenkins to GitHub Actions is about more than just changing your code from a Jenkinsfile to a YAML file. It means moving away from stressful server management to a modern cloud setup that takes care of itself.
By making this switch, you get rid of major headaches like fixing broken build servers, dealing with outdated plugins, and troubleshooting errors that only happen on your local machine. Instead, you get a clean, safe, and fast pipeline that works perfectly from day one.
Thanks for reading! If you found this migration guide helpful, drop a comment below letting me know what CI/CD tool you are currently using in your workflow!