This repository contains a demo project created as part of my DevOps studies in the TechWorld with Nana – DevOps Bootcamp.
Demo Project: Complete CI/CD Pipeline with EKS and private DockerHub registry
Technologies used: Kubernetes, Jenkins, AWS EKS, Docker Hub, Java, Maven, Linux, Docker, Git
Project Description:
- Write K8s manifest files for Deployment and Service configuration
- Integrate deploy step in the CI/CD pipeline to deploy newly built application image from DockerHub private registry to the EKS cluster
- So the complete CI/CD project we build has the following configuration:
- a. CI step: Increment version
- b. CI step: Build artifact for Java Maven application
- c. CI step: Build and push Docker image to DockerHub
- d. CD step: Deploy new application version to EKS cluster
- e. CD step: Commit the version update
Before starting, complete the following module:
- CD - Deploy to EKS cluster from Jenkins Pipeline: https://github.com/explicit-logic/eks-module-11.4
The Kubernetes manifest files define how the application is deployed and exposed:
Note: The variables
$APP_NAMEand$APP_IMAGEare substituted with actual values usingenvsubstduring the pipeline deploy stage.
The gettext-base package provides the envsubst command used for variable substitution in manifest templates.
- Connect to the Jenkins server and enter the Jenkins container:
ssh root@<DROPLET_IP>
docker ps
docker exec -it -u 0 <container_id> bash- Install
gettext-baseand verify the installation:
apt-get update && apt-get install -y gettext-base
envsubst -V- Exit the container.
Secrets are scoped per namespace. In this setup, one secret is used per namespace.
- Configure your local connection to the EKS cluster:
aws configure list
aws eks update-kubeconfig --name demo-cluster --region <your-region>- Create the Docker registry secret:
kubectl create secret docker-registry dockerhub \
--docker-server=docker.io \
--docker-username=<your-username> \
--docker-password=<your-password>- Verify the secret was created:
kubectl get secret- Navigate to Manage Jenkins → Plugins → Available Plugins
- Search for and install: Ignore Committer Strategy
This plugin prevents multibranch pipelines from triggering new builds when commits are made by specified email addresses — used here to break the CI commit loop caused by Jenkins version-bump commits.
Jenkins needs a GitHub Personal Access Token to clone the repository and update commit statuses.
Create the token:
- Go to github.com/settings/tokens/new
- Set Note to
jenkins - Select the following scopes:
| Scope | Reason |
|---|---|
admin:repo_hook |
Create, read, and delete webhooks |
public_repo |
Access public repositories |
repo:status |
Update commit statuses |
- Click Generate token and copy it immediately
Add the token to Jenkins:
- Navigate to Manage Jenkins → Credentials
- Click Add Credentials and fill in:
| Field | Value |
|---|---|
| Kind | Username with password |
| ID | github |
| Username | Your GitHub username (not your email) |
| Password | Your personal access token (starts with ghp_) |
- Go to Dashboard → New Item
- Name it
cicd-dockerhub, select Multibranch Pipeline, click OK
Branch Sources:
Click Add source → GitHub and configure:
| Field | Value |
|---|---|
| Credentials | github |
| Repository HTTPS URL | https://github.com/explicit-logic/eks-module-11.6 |
Click Validate to confirm access.
Behaviors — click Add and enable:
Discover branches
Build Configuration:
- Script Path:
Jenkinsfile
Build Strategies:
- Add Ignore Committer Strategy
- List of author emails to ignore:
jenkins@example.com
- List of author emails to ignore:
- Check Allow builds when a changeset contains non-ignored author(s)
This combination ensures that version-bump commits made by Jenkins do not re-trigger the pipeline, preventing an infinite build loop.
- Click Save — Jenkins will scan the repository and create a job for each branch.
- Go to IAM → Users → Create user
- Name:
jenkins
- Name:
- Select Attach policies directly and attach the following managed policies:
AmazonEKSClusterPolicyAmazonEKSWorkerNodePolicyAmazonEC2ContainerRegistryFullAccess
- Complete user creation.
- Find the user's ARN in the IAM console:
- Map the IAM user to the cluster:
eksctl create iamidentitymapping \
--cluster demo-cluster \
--region <REGION> \
--arn arn:aws:iam::<ACCOUNT_ID>:user/jenkins \
--group system:masters \
--username jenkins- In IAM, open the
jenkinsuser → Security credentials → Create access key - Use case: Application running outside AWS
- Copy the Access key and Secret access key
- Go to
cicd-dockerhub→ Credentials → Global → Add Credentials - Add two Secret text credentials:
| ID | Secret |
|---|---|
AWS_ACCESS_KEY_ID |
<Access key> |
AWS_SECRET_ACCESS_KEY |
<Secret access key> |
Trigger the pipeline and verify the deployment.









