Note
The actual GitHub Actions workflow for this project is located under:
.github/workflows/ci.yamlGitHub only recognizes workflow files placed inside the
.github/workflows/directory. Because of this limitation, the workflow itself cannot be stored inside theDay-06/folder.This directory exists solely to document the concepts, design decisions, implementation details, and lessons learned during Day 06 of the project.
The implementation lives in
.github/workflows/ci.yaml, while this README serves as the accompanying technical documentation.
This is the github actions pipeline link: WORKFLOW LINK.
Day-06/
└── README.md
.github/
└── workflows/
└── ci.yaml
- README.md documents the CI/CD implementation and engineering decisions.
- ci.yaml contains the executable GitHub Actions workflow.
This GitHub Actions workflow automates the container build and deployment process for the application.
On every push to the main branch, the workflow:
- Builds a Docker image.
- Pushes the image to GitHub Container Registry (GHCR).
- Updates the Kubernetes deployment manifest with the new image tag.
- Commits the updated manifest back to the repository.
- Allows ArgoCD to automatically deploy the new version.
- Removes older container images from GHCR.
After containerizing the application (Day 02), deploying it to Kubernetes (Day 03), and managing infrastructure using Terraform (Day 04), the next logical step was automating the software delivery process.
The objective of this stage was to eliminate manual image builds and deployment updates by creating a repeatable CI/CD workflow capable of:
- Building application images automatically.
- Versioning images using immutable tags.
- Publishing images to a container registry.
- Updating Kubernetes manifests automatically.
- Supporting GitOps-based deployments through ArgoCD.
This forms the foundation for future stages involving security scanning, monitoring, and production-style deployment workflows.
on:
push:
branches: [ main ]The workflow runs automatically whenever changes are pushed to the main branch.
Downloads the latest source code into the GitHub Actions runner.
uses: actions/checkout@v4Authenticates to GitHub Container Registry using the automatically generated GITHUB_TOKEN.
docker login ghcr.ioRequired permissions:
permissions:
contents: write
packages: writeBuilds the application image using the Dockerfile created in Day 02.
docker build \
-t ghcr.io/janemils/devops-project-1:${GITHUB_SHA} \
-f Day-02/Dockerfile .Each image is tagged using the commit SHA to ensure version traceability.
Pushes the newly built image to GitHub Container Registry.
docker push ghcr.io/janemils/devops-project-1:${GITHUB_SHA}Updates the image reference in the deployment manifest with the latest image tag.
Before:
image: ghcr.io/janemils/devops-project-1:<old-tag>After:
image: ghcr.io/janemils/devops-project-1:<new-commit-sha>This ensures the Git repository always contains the latest deployable version.
Commits the updated deployment manifest back to the repository.
git add Day-03/deployment.yaml
git commit
git pushThe commit message includes:
[skip ci]
to prevent the workflow from triggering itself again.
The workflow does not deploy directly to Kubernetes.
Instead:
GitHub Actions
↓
Update deployment.yaml
↓
Push changes to Git
↓
ArgoCD detects changes
↓
Deploy to Kubernetes
This follows the GitOps model where Git remains the single source of truth.
To prevent registry growth, older container images are automatically removed.
min-versions-to-keep: 3Only the latest three container images are retained.
Developer Pushes Code
↓
GitHub Actions Triggered
↓
Build Docker Image
↓
Push Image to GHCR
↓
Update Kubernetes Manifest
↓
Commit Changes to Git
↓
ArgoCD Detects Changes
↓
Deploy Updated Version
- GitHub Actions workflow automation.
- CI/CD pipeline fundamentals.
- GitHub Container Registry (GHCR).
- Immutable image versioning using commit SHAs.
- Automated Kubernetes manifest updates.
- GitOps deployment patterns with ArgoCD.
- Registry lifecycle management.
- Separation of CI responsibilities (GitHub Actions) and CD responsibilities (ArgoCD).
Updating the deployment manifest from within the workflow caused a new Git commit, which could potentially trigger the pipeline again.
This was solved by including:
[skip ci]
in the automated commit message.
During development, image pulls required authentication because the repository and registry packages were private.
This highlighted the importance of registry permissions and image pull secrets when working with Kubernetes.
Using mutable tags such as latest makes rollbacks and troubleshooting difficult.
To address this, every image is tagged using the Git commit SHA, providing a clear link between deployed workloads and source code revisions.