12-day curriculum
A hands-on training course for people who already know frontend or backend programming: you can write code and use the terminal reasonably well, but you have never taken a project through its whole life, from an idea to something running for real users. Over 12 days you set up your own server, point a domain, turn on HTTPS, build an app with both frontend and backend, package it with Docker and learn to run it. By Day 12 you understand the full journey, from the moment a user types an address into the browser, through the server, to the database behind it.
Five principles running through the 12 days
01Understand the whole journey, start to finish
The heart of the course is the whole journey: idea → terminal → server → domain → nginx → HTTPS → backend → Docker → live. You must be able to retell every step, so we come back to a single diagram again and again until it becomes second nature.
02Do it by hand first, use tools after
You start by doing things directly: install nginx with apt, run the backend with systemd, edit config files yourself, so you see what really happens. Then we bring in Docker to package everything and run it the same way anywhere. A tool you do not understand is hard to fix when it breaks.
03AI writes fast, you stay responsible
You will use AI to write a lot of code, frontend and backend. But you must read, review, adjust and ship whatever the AI writes. The skills you practise: asking AI clearly, checking the result, deploying it and taking responsibility for your product.
04One layer a day, always testable
Each day you add one layer and finish with something running for real that you can open on your phone: first by IP address → then by domain → with HTTPS → with real data → packaged in Docker.
05Hands-on every single day
Every day has a lab that produces a real product. There is no day of just sitting and watching videos.
One diagram that runs through the whole course
USER'S BROWSER (types https://app.example.com)
|
| (1) DNS: what's the IP of app.example.com? -> 203.0.113.10
v
(2) TCP connect to 203.0.113.10:443
(3) TLS handshake -> encrypted channel (HTTPS)
|
v
+---------------------- THE VPS ----------------------+
| firewall (ufw) allows 22, 80, 443 |
| (4) HTTP request lands on port 443 |
| | |
| v |
| NGINX (reverse proxy + static file server) |
| | | |
| | / (frontend) | /api/* |
| v v |
| [ STATIC FILES ] [ APP: Flask / FastAPI ] |
| HTML / CSS / JS (in Docker, port 8000) |
| | |
| v |
| [ SQLITE DB (a file) ] |
+-----------------------------------------------------+
|
v
Response (JSON / HTML) streams back over TLS -> browser renders.
- You can write basic JavaScript and at least one backend language (Python is ideal).
- You can use the terminal at the level of
cd,lsandgrep. - You have a computer with a terminal and a browser, plus about 30–50 USD for one month of a server (VPS) and a domain name.
- You are ready to break things and fix them. You will hit errors, and that is exactly how you learn.
| Server (VPS) | Hetzner, DigitalOcean or Linode: any plan around 5 USD a month will do |
| Operating system | Ubuntu 24.04 LTS |
| SSH access | ssh and an ed25519 key |
| Web server | nginx |
| HTTPS | certbot (Let's Encrypt) |
| Backend | Python 3 and Flask (FastAPI is a more modern option) |
| Database | SQLite |
| Containers | Docker Engine and Docker Compose |
| Domain (DNS) | The control panel of where you bought the domain, or Cloudflare (free) |
The 12-day path
Each day you finish something that works. Click any day to see its full content.
Getting started with the terminal
Type commands, manage files and permissions, and connect to a server over SSH.
Open Day 1 →Building the web interface
Write HTML, CSS and JS and use AI to build a responsive page that runs online.
Open Day 2 →Python programming
Write scripts, debug when they break, and build a small command-line tool.
Open Day 3 →Backend and database
Learn HTTP, build an API with Flask and store data in SQLite.
Open Day 4 →Managing code with Git
Keep history, work with branches, undo mistakes, and isolate the environment of each project.
Open Day 5 →Docker and nginx
Package the whole system with Docker and put it behind nginx so it runs the same on any machine.
Open Day 6 →Domain name and HTTPS
Point your own domain, turn on HTTPS and make the service restart itself when the machine boots.
Open Day 7 →Security, email and payments
Set up a firewall, store passwords safely, block SQL injection, send email and try a test payment.
Open Day 8 →AI and system monitoring
Add an AI feature to your site and set up alerts for when it goes down.
Open Day 9 →Where to go next
Get to know CDN, Kubernetes, CI/CD, file storage and queues, so you know what to learn next.
Open Day 10 →Planning your final project
Choose what to build (web, game or app) and scope it so you can finish.
Open Day 11 →Final project demo
Build a complete product on your own and present it to mentors and software engineers with many years of experience.
Open Day 12 →Three kinds of material, one set of content
Slide deck
Slides that walk through the course day by day. Press the arrow keys or Space to move on — present it or study on your own.
Open the slides →PDF document
A summary of the whole course: who it's for, the 12-day path and the final project. Download it to read offline or print.
Download the PDF ↓Flat page
The whole course on one page, with a table of contents beside it. Good for reading from start to finish in one go.
Read the flat page →How you are assessed
Every day
Each lab must produce something that really runs: a link that opens, a service that keeps running after a reboot, an HTTPS certificate that renews itself. If it does not run or cannot be tested, the day is not finished.
Explain it out loud (Days 4, 6, 12)
You retell the big-picture diagram and walk through a real request, out loud. You should be able to explain why nginx sits where it does, where the data lives, and what would break if one layer were removed.
Final project (Day 12)
You build a new product on your own, from start to finish. You pass when a stranger on the internet can open it, it has HTTPS and the data is kept.
What to learn next
Quick reference
The request, in order: DNS (name→IP) → TCP connect → TLS handshake (HTTPS) → HTTP request → nginx (static file or reverse-proxy) → app (Flask) → SQLite → response back over TLS.
| Task | Command |
|---|---|
| Is the box reachable? | ping <ip> · curl -I https://<domain> |
| What's listening? | ss -tlnp |
| DNS check | dig +short <domain> A · nslookup <domain> |
| Service status / logs | systemctl status <svc> · journalctl -u <svc> -f |
| nginx test / reload | sudo nginx -t · sudo systemctl reload nginx |
| certbot renew (test) | sudo certbot renew --dry-run |
| Docker up / down | docker compose up -d · docker compose down |
| Docker logs | docker compose logs -f |
| Public IP | curl ifconfig.me |
| Firewall | sudo ufw status · sudo ufw allow 443 |
- Allow SSH (22) in the firewall before enabling it.
- Keep a second SSH session open when editing
sshd_config. - Test new SSH settings from the second session before closing the first.
- Bind the app to
127.0.0.1, not0.0.0.0— nginx is the only front door. - Put SQLite on a volume before you ever
docker compose down.