The DevOps Lifecycle
The DevOps lifecycle is the repeating set of stages a team moves through to take an idea, turn it into working software, run it in production, and learn from how it behaves. People often draw it as a sideways figure-eight (the “infinity loop”) because the work never really stops — you finish one cycle and immediately start the next, carrying lessons forward. Understanding each stage, and the tools that live there, gives you a mental map for everything else you will learn in DevOps and on a Linux server. This page walks the loop in order and shows where common tools fit.
Why a loop and not a line
A traditional release process was a one-way line: write code, hand it to QA, hand it to operations, ship it, and walk away. The problem is that software is never “done” — bugs appear, traffic grows, and users ask for changes. DevOps treats delivery as a loop: the output of the last stage (what you learn from running the app) becomes the input to the first stage (what you plan next).
The loop has two halves. The left half (plan, code, build, test) is development — turning ideas into a tested artifact. The right half (release, deploy, operate, monitor) is operations — getting that artifact to users and keeping it healthy. The two halves meet in the middle, which is the whole point of “Dev” + “Ops”.
The loop is continuous, but you do not have to automate every stage on day one. Start by making one painful stage (usually deploy) repeatable, then expand. Trying to build the entire pipeline before shipping anything is a common beginner trap.
The eight stages
1. Plan
You decide what to build next: features, bug fixes, and technical work. This is where you write tickets, break work into small pieces, and prioritize. Crucially, this is where monitoring data from the previous loop lands — a spike in errors or a slow page becomes a planning item.
- Tools: Jira, GitHub Projects, Linear, Trello.
- When to use this well: small, frequent batches of work beat giant releases. Smaller changes are easier to test, deploy, and undo.
2. Code
Developers write the source code and commit it to a version control system (a tool that records every change so you can review history and roll back). Git is the universal standard.
git checkout -b feature/login-rate-limit
git add .
git commit -m "Add rate limiting to login endpoint"
git push origin feature/login-rate-limit
- Tools: Git, GitHub/GitLab/Bitbucket, VS Code.
- Skill: clean commits and pull requests so others can review your work.
3. Build
The build stage turns source code into a runnable artifact (the packaged output, e.g. a .jar, a compiled binary, or a container image). On Linux you often build a Docker image — a self-contained package of your app plus everything it needs to run.
docker build -t myapp:1.4.0 .
Output:
[+] Building 23.7s (12/12) FINISHED
=> exporting to image
=> => naming to docker.io/library/myapp:1.4.0
- Tools: Docker, Maven/Gradle, npm, Make.
4. Test
Automated tests check that the build actually works before it reaches users. This includes unit tests (small, fast checks of one function) and integration tests (checks that parts work together).
npm test
Output:
Test Suites: 14 passed, 14 total
Tests: 212 passed, 212 total
Time: 9.114 s
- Tools: Jest, JUnit, pytest, Cypress.
- When NOT to skip: never disable a failing test to “go faster”. A red test is the loop protecting you.
5. Release
Release is the decision and act of marking a tested artifact as ready to go out. Often this means tagging a version and storing the artifact in a registry (a server that holds your built images or packages).
docker tag myapp:1.4.0 registry.example.com/myapp:1.4.0
docker push registry.example.com/myapp:1.4.0
- Tools: GitHub Releases, container registries (Docker Hub, GitHub Container Registry), Artifactory.
6. Deploy
Deploy puts the released artifact onto the servers that real users hit. On a single Ubuntu server this might mean pulling the image and restarting a systemd service (the standard Ubuntu tool that starts and supervises long-running programs).
sudo systemctl restart myapp
sudo systemctl status myapp
Output:
● myapp.service - My App
Loaded: loaded (/etc/systemd/system/myapp.service; enabled)
Active: active (running) since Mon 2026-06-15 10:22:01 UTC; 3s ago
- Tools: Ansible, Kubernetes, Terraform, GitHub Actions, systemd.
- When to use which: one server → systemd + a deploy script; many servers/containers → Kubernetes.
7. Operate
Operate is keeping the running system healthy: managing the OS, the firewall, backups, certificates, and scaling. On Ubuntu you spend a lot of time here with apt, systemd, and ufw (the Uncomplicated Firewall, Ubuntu’s simple front-end for managing which ports are open).
sudo apt update && sudo apt upgrade -y
sudo ufw status verbose
Output:
Status: active
To Action From
-- ------ ----
22/tcp ALLOW IN Anywhere
443/tcp ALLOW IN Anywhere
- Tools: systemd, ufw, cron, Ansible, cloud consoles.
8. Monitor
Monitoring watches the live system and tells you when something is wrong — high error rates, slow responses, full disks. The observability (the ability to understand a system’s internal state from its outputs) data you collect here is what feeds the next Plan stage, closing the loop.
sudo journalctl -u myapp -n 50 --no-pager
df -h /var/log
Output:
Filesystem Size Used Avail Use% Mounted on
/dev/vda1 49G 31G 16G 67% /
- Tools: Prometheus, Grafana, Loki, the ELK stack,
journalctl, Datadog.
How monitoring feeds back into planning
This is the part most tutorials skip. A monitoring alert is not the end of the story — it is raw material for the next loop:
| Monitoring signal | Becomes this planning item |
|---|---|
| Login endpoint p95 latency spiked | Plan a query/index fix |
| 5xx errors after each deploy | Plan automated rollback |
Disk on /var/log at 90% | Plan log rotation in /etc/logrotate.d |
| Repeated failed SSH logins | Plan firewall + fail2ban hardening |
By routing real-world signals straight back into Plan, the team improves the product and the pipeline every cycle. That feedback flow is what makes it a loop rather than a line.
Best Practices
- Make small, frequent changes — they are safer and easier to undo than big-bang releases.
- Automate the most painful stage first (usually deploy), then widen the loop over time.
- Never ship a build with failing tests; treat a red pipeline as a stop signal.
- Always have a tested rollback (e.g. keep the previous image tag so you can
docker runit again). - Feed every production incident back into the Plan stage so the same problem cannot recur.
- Keep monitoring and logs (
journalctl,/var/log) reviewed regularly, not only during outages. - Store config and infrastructure as code in Git so the whole loop is reproducible.