Learn DevOps
A course for application developers who can build software but not ship it.
Read this first: this is not documentation for MotorPH. It is a course that uses MotorPH as its worked example. You will build a complete deployment pipeline from an empty folder — your own Dockerfile, your own compose file, your own GitHub Actions workflow, your own deploy script — and only then read the real ones. Everything runs on your laptop. You do not need to rent a server, and you will not be asked to spend a peso.
If you want reference material instead — "what does this flag do, what is already configured" — you want DevOps, not this. The two are complements: this course builds the mental models, those pages are what you consult once you have them.
Who this is for
You are comfortable in application code. You have shipped features. But the terminal still feels like guesswork, YAML breaks for reasons you can't predict, and when a build goes red you scroll the log hoping something jumps out. You have gotten this far by pasting errors into a chatbot, and you have noticed that this is not the same thing as knowing.
The goal of this course is narrow and testable: by the end you can build and repair a deployment pipeline with no AI assistance and no copy-paste from a tutorial.
No prior Linux, Docker, YAML or CI knowledge is assumed. The first lesson starts at "what is a shell".
How each lesson works
Every lesson has the same five beats, and they are load-bearing:
- Predict — before you run anything, you write down what you think will happen. This feels silly and it is the single highest-value part of the course. A wrong prediction is the only reliable signal that a model in your head is broken.
- Run — you type the command. Not copy-paste. Typing is slower on purpose.
- Read — real output, annotated line by line. Every log in this course was produced by actually running the command, not written from memory.
- Break it — you deliberately introduce the failure that this topic is famous for, and read the error it produces. The point is that when you meet that error in eighteen months, you will recognise it instead of googling it.
- Fix it — you repair what you broke, and the lesson says what you should now be able to do unaided.
Each lesson ends by pointing at where the same idea appears in the real MotorPH pipeline, so the abstraction always lands somewhere concrete.
The two tracks
Track A — Labs (01–19, plus optional 29–30). You build. Start at lesson 01 and go in order; each one assumes the previous. This is the track that changes what you can do, and it ends with a capstone where you build a complete pipeline from an empty repository and then deliberately break it.
Track B — MotorPH decoded (20–26). Annotated tours of the real files in this repository — the workflows, the deploy script, the compose stacks, the edge proxy. Read these after the matching lab. They are also the answer to "why is it written like that", because most of those lines exist because something broke once — and chapter 26 tells those stories directly.
Reference (27–28). A glossary and a set of cheat-sheets. Use them from day one; they are not a reward for finishing.
What you need
- Docker and Docker Compose.
docker --versionshould print something. - A GitHub account.
- A terminal. That's it.
You do not need Java, Maven or Node installed. The toy app is a Spring Boot API and a React frontend — the same three tiers as MotorPH itself — but everything compiles inside containers, which is rather the point.
Everything else — including the "server" you will deploy to — you build in lesson 10 as a container on your own machine. It costs nothing, and you can destroy and recreate it in about five seconds, which is exactly what makes it a good place to learn.
Honest limits
The lab server is a container pretending to be a VPS. It is genuinely a Linux box you SSH into, and almost everything transfers. Four things do not, and they get read-only tours in Track B instead of labs:
- Real DNS. Nothing on your laptop has a public name.
- Real TLS certificates. Let's Encrypt has to reach you from the internet to issue one.
- A real public IP, and therefore real hostile traffic.
- Full systemd. Containers don't boot an init system the way a real host does.
Where a lesson is working with a simplification, it says so in the lesson. A course that pretends the toy is the real thing produces exactly the false confidence this one is trying to fix.
The lessons
Track A — Labs
| # | Lesson | You will be able to |
|---|---|---|
| 01 | Shell survival | Move around a filesystem, chain commands, read an exit code |
| 02 | Your first script | Write and run a .sh file that takes arguments |
| 03 | Scripts that fail safely | Explain every letter of set -euo pipefail |
| 04 | Reading someone else's bash | Work through deploy.sh instead of bouncing off it |
| 05 | Containers 101 | Say precisely what an image is and what a container is |
| 06 | Your first Dockerfile | Containerise a Spring Boot app and explain the layer cache |
| 07 | Multi-stage builds | Ship a JRE image instead of a JDK-plus-Maven one |
| 08 | Compose | Run frontend + API + database with real health gates |
| 09 | Env vars and secrets | Explain why a $ in an env file silently truncates a secret |
| 10 | Your fake VPS | SSH with keys, run remote commands, diagnose "Permission denied" |
| 11 | Users and permissions | Read any ls -l, use umask 077, explain why docker is root |
| 12 | Processes, ports, logs, disk | Triage a broken box in under a minute |
| 13 | Firewalls | Reproduce and fix the DOCKER-USER rule that killed container egress |
| 14 | YAML without tears | Read and write YAML without guessing |
| 15 | Your first workflow | Write a GitHub Actions workflow and debug a red X |
| 16 | Actions and the registry | Build an image in CI and push it to GHCR |
| 17 | Jobs that depend on jobs | Build a job graph, pass values, understand environment: |
| 18 | Deploying from CI | SSH from a runner and pass secrets without pasting them into a script |
| 19 | Capstone | Build the whole pipeline yourself, then break it on purpose |
Work through 01–19 in order — each lesson assumes the one before. The capstone is the end of the required path.
Optional, once one server is not enough:
| # | Lesson | You will be able to |
|---|---|---|
| 29 | Splitting the stack across servers | Say what actually breaks when the database moves to its own machine |
| 30 | Traefik and Caddy | Choose between a configured proxy and a discovered one, and defend the choice |
Track B — MotorPH decoded
Annotated tours of the real files in this repository. Read each after the lab that earns it, when the syntax has stopped being noise. All code is quoted inline, so you can read these anywhere.
| # | Chapter | Decodes | Read after |
|---|---|---|---|
| 20 | The big picture | What happens between git push and the site being live | 15 |
| 21 | deploy.yml decoded | The 253-line deployment workflow | 18 |
| 22 | The gates decoded | Tests, Playwright, CodeQL, gitleaks, the docs leak scan | 17 |
| 23 | deploy.sh decoded | The 439-line deploy runner | 19 |
| 24 | preflight and bootstrap | The two scripts you run by hand | 13 |
| 25 | Compose stacks and the edge | Four projects, one network, one Caddy — plus DNS and TLS | 9 |
| 26 | When it breaks | Six real incidents, symptom first | all of Track A |
Reference
| # | Page | Contents |
|---|---|---|
| 27 | Glossary | Every term this course uses, with the lesson it appears in |
| 28 | Cheat-sheets | One page each for bash, Linux triage, Docker/Compose, Actions |
Start with lesson 01. It takes about thirty minutes and it starts from nothing.