My full-stack to devops roadmap started the day a client's app went down at 2am and I realized I could write the feature that broke but I had no idea how to safely roll it back. I was a competent full-stack developer: Laravel and Next.js, databases, APIs. What I could not do was reason about the box it all ran on. The lesson that pushed me into DevOps was simple and a little embarrassing: I already owned half the job and had been treating the other half as someone else's problem. This is the roadmap I actually followed over about 14 months, in the order that built on itself, while still taking client work the whole time.
I want to be honest up front about what a full-stack background hands you for free, because it is more than you think, and about what is genuinely new, because underestimating that part is where people stall.
What transfers for free, and what is genuinely new?
A lot of DevOps content is written as if you are starting from zero. You are not. If you have shipped real full-stack apps, you already have instincts that take career changers from other fields months to build. The trap is assuming the whole field works that way and getting blindsided by the parts that do not map to application code at all.
- Transfers for free: debugging. Reading a stack trace and reading a kernel log are the same muscle. Bisecting a failing deploy is bisecting a failing test run with different nouns.
- Transfers for free: reading docs under pressure. You already know how to skim an unfamiliar API reference and find the one flag that matters. AWS docs are just very large.
- Transfers for free: automation instinct. If writing the same shell command twice already annoys you, you have the temperament. DevOps is that annoyance, professionalized.
- Genuinely new: networking. Subnets, routing tables, security groups, what a CIDR block actually means. Nothing in app development teaches this and you cannot fake it.
- Genuinely new: IAM and the principle of least privilege. Thinking about identity, roles, and trust policies is a whole separate skill from writing auth in your app.
- Genuinely new: the ops mindset of designing for failure. Application code assumes the network works. Infrastructure work assumes everything fails and asks what happens next.
Why does the order matter so much?
I wasted my first two months jumping straight to Kubernetes tutorials because that is what the job postings listed. It was useless. I did not understand the Linux underneath, so every error was a black box. The order below is not arbitrary; each stage gives you the vocabulary to understand the next one. Skip Linux and Docker is magic. Skip networking and your first real AWS deploy is a guessing game. Build the base first.
The staged plan I followed
Each stage is tied to a concrete project, because reading does not stick and certificates without hands-on work fool only you. The rule I held myself to: do not advance until I had built the thing, not just watched someone build it.
- Stage 1 (Linux + shell, ~6 weeks): Rent a $5/month VPS and run everything yourself. Project: deploy one of my own Laravel apps by hand, no panel, configuring Nginx, PHP-FPM, and systemd from scratch. Learn the file system, permissions, processes, and journalctl.
- Stage 2 (Networking basics, ~3 weeks): DNS, TCP/IP, ports, what a reverse proxy does, how TLS terminates. Project: put a real domain in front of the VPS with Let's Encrypt and understand every hop from browser to app.
- Stage 3 (A cloud provider + the cert track, ~4 months): Pick AWS and commit to the Solutions Architect Associate. The cert forces you to learn VPCs, IAM, S3, and EC2 properly instead of cargo-culting. I wrote up the exact study plan in my AWS Solutions Architect Associate study post.
- Stage 4 (Docker + containers, ~6 weeks): Project: containerize a full app, write a real multi-stage Dockerfile, then a docker-compose stack with the app, a database, and a queue worker. Now Stage 1's manual setup makes the value obvious.
- Stage 5 (CI/CD pipelines, ~4 weeks): Project: build a pipeline that tests, builds an image, and deploys on push to main. I documented the full setup in CI/CD with GitHub Actions for Laravel. This is also the stage where a disciplined branching strategy stops being optional, because the pipeline only makes sense if main is always deployable.
- Stage 6 (Infrastructure as code, ~6 weeks): Rebuild Stage 3's hand-clicked AWS environment in Terraform so it is reproducible and reviewable. Project: tear the whole environment down and stand it back up from code alone.
- Stage 7 (Observability + monitoring, ~3 weeks): Metrics, logs, alerts, and dashboards. Project: instrument the deployed app so you know it is down before the client does. My cheap production monitoring setup covers the tools that do not cost a fortune.
- Stage 8 (Security hardening, ongoing): Lock down SSH, tighten firewall rules, move secrets out of files and into a manager, and keep packages patched. Treat it as a checklist you revisit every quarter, not a one-time task.
What does a 'concrete project' actually look like?
The single highest-leverage habit was forcing every stage to end in something I could destroy and rebuild from scratch. The clearest proof you have learned infrastructure is being able to delete it and recreate it from code in minutes. Here is the kind of throwaway script I kept in each project's repo: a one-command rebuild that proved I had not accidentally hand-fixed something I forgot to write down.
#!/usr/bin/env bash
set -euo pipefail
# Stage 6 proof: the whole environment comes from code, nothing by hand.
terraform init -input=false
terraform apply -auto-approve # stand up VPC, EC2, security groups
# Build and push the app image, then deploy.
docker build -t myapp:"$(git rev-parse --short HEAD)" .
./deploy.sh # same script CI runs on main
# If this script fails on a clean slate, the docs are wrong, not the server.
echo "Rebuilt from a clean slate in one command."If that script ran green on a freshly wiped environment, I knew the knowledge was in the repo and not just in my head. That distinction is the whole job. A DevOps engineer who can only fix things by remembering what they clicked last time is a single point of failure, which is exactly the thing the role exists to eliminate.
The moment DevOps clicked for me was when I stopped asking how do I fix this server and started asking how do I make this server reproducible. Fixing is application thinking. Reproducing is infrastructure thinking. That shift is the actual job, not any single tool.
How long did it really take, and was it worth it?
About 14 months from that 2am outage to confidently owning the infrastructure on client projects, working evenings and weekends around paid work. I did not quit freelancing to do it; I folded each stage into real client deploys so the learning paid for itself. The honest catch: there were weeks I made zero progress because a client deadline ate everything, and Stage 3's cert took longer than the four months I planned because I underestimated networking. Nobody hands you a clean runway.
- What I would do again: anchor every stage to a real deploy. Tutorial infrastructure evaporates; client infrastructure you have to keep running teaches you what actually breaks.
- What I would do differently: spend longer on networking earlier. Half my AWS confusion in Stage 3 was really a networking gap I had skipped past.
- What surprised me: how much my existing debugging and automation instincts carried. The new material was a quarter of the work; the rest was reframing skills I already had.
If you are a full-stack developer eyeing this move, the most useful thing I can tell you is that you are not starting over. You are closing a gap, and it is a smaller gap than the job postings make it look. Start with one $5 server you are allowed to break, work the stages in order, and refuse to advance until you have built the project at each step. Fourteen months from now you will read your own logs at 2am and know exactly how to roll it back, which is the whole reason I started.

