In the previous article on hosting a Next.js app on a VPS, I'd left the deployment pipeline as a rough sketch: four lines to say "it ships to production on its own when you push." That's the piece I want to open up here, because it's what separates a VPS you fuss over by hand from infrastructure you can forget about.

There's a stubborn myth that CI/CD is a big-company thing, with a dedicated DevOps team and six-figure tooling. Not true. The pipeline that deploys this portfolio fits in two YAML files, you can read it in five minutes, and it gives me back exactly the comfort I liked about Vercel: I push to master, I go grab a coffee, the app is live when I'm back. The one thing I gained along the way is knowing precisely what happens between the git push and the running container.

Four steps, in this order

Deployment is a chain. On every push to master, GitHub Actions runs lint, security scan, image build, and deploy. What matters is the needs: as long as a step fails, the following ones don't start. A critical vulnerability caught by the scan, and the image never gets built. At all.

jobs: