Introduction#
Before automating with CI/CD and GitOps, I was running manual builds, copying files by hand, or SSHing into servers just to restart a service. It worked, but it was repetitive, error-prone, and honestly boring.
With my GitOps pipeline in my homelab, my goal is simple:
- Automate what can be automated
- Learn about pipelines and DevOps operations
- Avoid relying on GitHub or external services
- Maintain full control over deployments
Since I already use Gitea, Docker, and Ansible, these tools became the foundation of my GitOps workflow.
Diagram#
graph TD A[[Code Push]] -->|trigger| B[Build Job] B -->|compile & build| C[Test Job] C -->|validate| D[Release Job] D -->|package image| E[Deployment Job] E -->|ansible-playbook| F[[Deployed]]
1. My Setup and Tools#
- Gitea : A self-hosted Git service that replaces GitHub. Fast, lightweight, and mine.
- Gitea Runner : Executes workflows (like GitHub Actions, but locally).
- Docker : Packages my applications into images.
- Ansible : Automates deployment to my servers.
- Semaphore : A UI for Ansible that lets me trigger playbooks easily, from pipelines via webhooks.
2. Pipeline Design#
Here’s how my workflow looks in practice:
- Push code → A commit to
main
triggers a workflow in Gitea. - Build → The runner compiles and builds the project.
- Test → Unit tests and linting ensure code quality.
- Release → A Docker image is built, tagged, and stored.
- Deploy → Semaphore triggers Ansible playbooks that pull the new image and restart services in my homelab.
Every commit goes through the same lifecycle, no more manual steps.
3. Implementation Details#
Some details that make the pipeline work smoothly:
- Deployment logs → Semaphore keeps track of every deployment.
- Notifications → Discord webhooks alert me after each job.
- Cleanup → Old packages are cleaned to avoid wasting space.
- Secrets → All credentials are stored in Gitea Secrets.
Conclusion#
Building my own CI/CD pipeline taught me a lot about automation and DevOps practices. More importantly, it gave me a workflow I trust : simple, reproducible, and entirely under my control.
Next, I want to add:
- Advanced testing stages,
- Staging environments,
- Better notifications,
- Full CI/CD for my Ansible repository.
In the end, this pipeline is not just about saving time. It’s about trusting the process.
More#
- Checkout an example with this blog : Building a Complete CI/CD Pipeline : Introduction