1. Introduction
A developer opens their laptop, writes 25 lines of code, and pushes it.
To them, it feels small. A bug fix. A new field. A minor feature. Twenty-five lines shouldn’t take more than a few minutes to reason about.
But somewhere between that git push and the moment a real user sees the change, the change has to pass through a series of engineering processes: it needs to be tracked, committed, built, tested, validated, secured, packaged, deployed, exposed to users, and eventually monitored in production.
The interesting part is that no single step makes the feature production-ready. The final result comes from all of these steps working together.
What looks like “just code” is actually the smallest part of the journey. Dozens of tools. Multiple teams. Systems the developer never directly touches — but silently depends on.
This is the story of that journey — what actually happens, step by step, between a developer’s keyboard and production.
2. DevOps Lifecycle
Before looking at individual tools, it helps to see the entire journey at once.
That 25-line change doesn’t move directly from a developer’s laptop to production. It moves through a sequence of stages, with each stage answering a different question: What are we building? Can we build it? Does it work? Is it safe? Where will it run? How does it reach users? And how do we know it’s still working?
The journey looks roughly like this:
Planning → Development → Source Control → Build → Testing → Security → Infrastructure → Deployment → Networking → Monitoring → Feedback
Each stage has a purpose — and more importantly, each stage produces something the next stage depends on:
- Planning defines what should be built.
- Development turns that requirement into code.
- Source Control records what changed.
- Build creates something that can be executed.
- Testing verifies that it behaves correctly.
- Security checks whether it is safe to release.
- Infrastructure provides where it will run.
- Deployment moves the application into that environment.
- Networking makes it reachable by users.
- Monitoring tells us what is happening after release.
- Feedback brings what we learned back into the next change.
This is where the DevOps ecosystem starts to make sense. The tools aren’t isolated pieces sitting next to each other — they exist because each stage needs to pass something forward to the next.
In the rest of this journey, we’ll take this flow apart and follow those 25 lines of code through each stage, one at a time.
3. From Requirement to Code
Every feature starts before a single line of code is written.
Someone decides it needs to exist — a product need, a bug report, a business requirement. That decision has to be captured, discussed, and broken down into something a developer can actually pick up and work on.
Jira is where that happens. The requirement becomes a ticket — scoped, prioritized, and assigned. It’s the single source of truth for what needs to be built and who’s building it.
Confluence sits alongside it, holding the why and the how. Design docs, technical decisions, API contracts, architecture notes — the context a developer needs so the ticket isn’t just a one-line instruction floating with no background.
Only once the requirement is clear does the developer open their editor and start writing those 25 lines.
When the code is ready, it doesn’t stay on the developer’s laptop — it moves into GitHub / GitLab. This is the moment the change stops being personal and becomes shared. It’s tracked, versioned, reviewed by teammates, and tied back to the original Jira ticket — so anyone looking at the commit later knows exactly what it was for and why it exists.
This is the first handoff in the chain:
requirement → task → implementation → source control
The code exists now — but it’s still just a change sitting in a branch. Nothing has verified that it actually works yet.
That’s the next stage.
4. From Code to a Verified Build
The code is written. It’s sitting in a branch on GitHub or GitLab. But “written” and “working” are two very different things — and nobody ships based on trust alone.
This is where CI (Continuous Integration) takes over. The moment that branch is pushed or a pull request is opened, tools like Jenkins, GitHub Actions, or CircleCI pick it up automatically. No one has to remember to run anything manually — the pipeline triggers itself.
But CI isn’t just “run the build.” It’s a sequence of checks, and the code has to clear all of them before it’s allowed to move forward:
- Build — the code is compiled and packaged into something executable. If it doesn’t even build, nothing else matters.
- Testing — tools like Selenium run automated tests to confirm the feature actually behaves the way it’s supposed to, not just that it compiles.
- Code Quality — SonarQube scans the code itself: complexity, duplication, bad patterns, maintainability issues. Code can work and still be fragile.
- Security — Trivy scans for known vulnerabilities — in the code, in dependencies, in the container image — before any of it gets closer to production.
If any one of these fails, the pipeline stops right there. The 25 lines don’t move forward until every check passes.
What comes out the other end isn’t just “code that runs” — it’s a verified build: compiled, tested, quality-checked, and scanned. Something a team can actually trust enough to hand off to the next stage.
And that next stage is where this verified build stops being just code — and starts becoming something that can run somewhere real.
5. From Application to Infrastructure
A verified build is still just a file sitting in a pipeline. It doesn’t run anywhere yet — it has no home. This stage is about giving it one, and it involves three distinct ideas that are easy to blur together: packaging, provisioning, and configuration.
Docker handles packaging. The application, along with everything it needs to run — dependencies, runtime, environment settings — gets bundled into a single image. That image behaves the same way whether it’s running on a developer’s laptop, a test server, or in production. This solves the classic “it worked on my machine” problem, because the machine itself is now part of the package.
But an image still needs somewhere to run. That’s infrastructure — the servers, networks, and storage the application will actually live on. This is where AWS, GCP, or Azure come in, providing the raw compute and resources.
The question is how that infrastructure gets created. Doing it by hand — clicking through a cloud console — doesn’t scale and isn’t repeatable. Terraform solves this by treating infrastructure as code: the servers, networks, and resources needed are written down in config files, and Terraform provisions exactly what’s described, every time, consistently.
Once the infrastructure exists, it still needs to be set up correctly — software installed, settings applied, services configured. That’s Ansible’s job: configuration. Terraform builds the house; Ansible furnishes it.
So the distinction is this:
- Docker — package the application
- Terraform — provision the infrastructure
- Ansible — configure that infrastructure
The 25 lines now exist as a packaged image, with real infrastructure ready to run it. But “ready to run” and “actually running for users” are still two different things.
That’s the next stage.
6. From Infrastructure to Production
The infrastructure exists. The image is packaged. But right now, that image is just sitting there — nothing has actually placed it onto a running server, and no user has a way to reach it.
This is where Kubernetes takes over. It takes the Docker image and actually runs it — deciding which server it lands on, how many copies (replicas) should run for reliability, and what happens if one of those copies crashes. If a container dies, Kubernetes restarts it automatically. If traffic spikes, it can scale up more copies to handle the load. The application isn’t just deployed once — it’s managed, continuously, without a human watching it 24/7.
But how does that deployment actually happen — who tells Kubernetes “here’s the new version, roll it out”? That’s Argo CD. It watches the Git repository, and the moment it sees a new verified build ready to go, it syncs that change into Kubernetes automatically. This is GitOps: Git becomes the single source of truth for what should be running, and Argo CD makes sure what’s actually running always matches it. No manual deployment steps, no one SSH-ing into a server — the desired state is declared in Git, and the system converges toward it.
At this point, the application is technically live inside the cluster. But it’s still sealed off — running in an internal network Kubernetes manages, invisible to the outside world.
That’s where Nginx comes in, acting as the entry point — routing incoming requests from real users to the correct running instance of the application inside the cluster. Without it, the feature could be running perfectly and still be completely unreachable.
This is the moment those 25 lines stop being “deployed” in an abstract sense and become something a real user can actually open in a browser and use.
But shipping it isn’t the finish line.
7. Production Doesn’t Mean Finished
The feature is live. A user can open the app and actually see those 25 lines in action. It’s tempting to treat this as the finish line — but this is exactly where things start to get interesting.
Code that passed every test in a controlled pipeline can still behave differently under real traffic, real data, and real user behavior. Something might be slow under load. A dependency might fail intermittently. A memory leak might only show up after hours of runtime. None of this shows up in a test suite — it only shows up in production.
That’s why Prometheus exists. It continuously collects metrics from the running application and infrastructure — response times, error rates, CPU and memory usage, request volume — every few seconds, around the clock. It doesn’t wait for something to break; it’s always watching.
Raw metrics on their own aren’t useful to a human staring at a wall of numbers. Grafana turns that data into dashboards — graphs and visualizations that make it obvious, at a glance, whether the system is healthy or something’s drifting wrong.
But dashboards only help if someone’s actually looking at them. That’s where Slack comes in — when Prometheus detects something crossing a threshold (error rates spiking, latency climbing), an alert gets pushed straight into a team channel. The right people find out in seconds, not hours later when a user complains.
This closes the loop. What’s learned in production — a bug that only shows up at scale, a slow endpoint, an unexpected failure — feeds back into Planning, becoming the next Jira ticket, the next 25 lines, the next trip through this entire pipeline.
The feature didn’t just get released once. It’s now being watched, measured, and improved — continuously.
And that’s the real answer to the question this article started with: those 25 lines didn’t become a production feature through one step. They became one through eleven stages, dozens of tools, and a system built to make sure the loop never really closes.
Top comments (0)