I built an end-to-end DevOps platform that covers the full life of a code change: from a git push, through automated testing and deployment, to metrics, alerts and logs for the running application in Kubernetes. Deploying by hand is slow and error-prone, and knowing whether a release is healthy is a separate problem, so this project removes every manual step between a commit and a live, observable application.
The pipeline starts with GitHub Actions. On every pull request it runs automated tests, builds a Docker image, and scans it with Trivy, blocking the change if a critical vulnerability turns up. When a change is merged to main, the image is tagged with the commit SHA and pushed to GitHub Container Registry, and a final job commits the new tag into the Kubernetes manifests. Argo CD watches that Git repository and keeps my local Kubernetes cluster (Docker Desktop) in sync with it, so deployment became a pull-based GitOps flow with no manual kubectl, and with self-healing that undoes any manual change made to the cluster.
For visibility I added a monitoring and logging stack, all deployed through Argo CD as well. The app exposes request counts, request durations and runtime metrics, which Prometheus scrapes and Grafana shows on a golden-signals dashboard (traffic, errors, latency and saturation). Alert rules flag a high error rate, slow requests, high memory use or an app that is down. For logs, the app writes structured JSON with a request ID on every line. Grafana Alloy ships them to Loki, so I can move from a spike on a metrics panel to the exact log lines behind it, and follow a single request by its ID.
The most useful part was working through the problems a real pipeline throws up. A pinned security-scan action I had chosen no longer resolved after a supply-chain incident, the scan caught a critical CVE bundled inside npm in the base image (fixed by updating the base and removing npm from the runtime image), the container registry package was private by default, and a bot job failed because it ran git pull --rebase before committing. I also replaced the end-of-life Promtail with Alloy. This project taught me how CI, CD and observability fit together, and how real delivery pipelines are built beyond “docker build and run.”




Top comments (0)