Project — Cloud Deployment

Project Build this yourself, to the spec and rubric below — the module's standard. You build it on your own dataset, alongside the lessons.

Deploy your Adult / Census Income scorer publicly, built to survive contact with the real world. A stranger on another machine reaches your /predict over https:// on a real domain and gets a prediction back, backed by dev-to-prod digest promotion, an auto-renewing TLS cert, one-step rollback, and a stated cost ceiling. This is real cloud work on your own account (docker push, a host, DNS, a TLS cert, a rollback), not a browser exercise.

Dataset Adult / Census Income — the same dataset and repo you carry through every module’s project (the lessons harden a Lending Club scorer; here you take your service to the open internet)
Start from Fork dutchengineer-org/phase2-starter — ships train.py and the frozen package (run python train.py to produce the model), so the model is never the blocker. Already forked it in an earlier ship module? Keep building in that fork
Aim for The package matches the ml-pipeline-starter reference — you push the image your M5/M6 work built, and you do not change the package. No version bump: shipping the same code to a new place is a deployment event, not a code change — the library is byte-identical, so there is nothing to version
Done when It passes every line of the rubric below, then you push to GitHub
Project Build this yourself, to the spec and rubric below — the module's standard. You build it on your own dataset, alongside the lessons.

Deploy your Adult / Census Income scorer publicly, built to survive contact with the real world. A stranger on another machine reaches your /predict over https:// on a real domain and gets a prediction back, backed by dev-to-prod digest promotion, an auto-renewing TLS cert, one-step rollback, and a stated cost ceiling. This is real cloud work on your own account (docker push, a host, DNS, a TLS cert, a rollback), not a browser exercise.

Dataset Adult / Census Income — the same dataset and repo you carry through every module’s project (the lessons harden a Lending Club scorer; here you take your service to the open internet)
Start from Fork dutchengineer-org/phase2-starter — ships train.py and the frozen package (run python train.py to produce the model), so the model is never the blocker. Already forked it in an earlier ship module? Keep building in that fork
Aim for The package matches the ml-pipeline-starter reference — you push the image your M5/M6 work built, and you do not change the package. No version bump: shipping the same code to a new place is a deployment event, not a code change — the library is byte-identical, so there is nothing to version
Done when It passes every line of the rubric below, then you push to GitHub

Start here

  1. Continue in your Phase 2 forkdutchengineer-org/phase2-starter (or keep building in the one you already forked); bring a cloud account and a domain you control
  2. Work the tasks below in order — each maps to a lesson you just finished, and each runs against your own cloud account and the container your Phase 2 fork builds
  3. Check yourself against the rubric, then push and submit

The proof is not a screenshot. It is a live URL a grader can curl, a deploy config in your repo, and a rollback you can demonstrate in one command.

The tasks

Do these in order; each maps to a lesson you just finished. Each runs against your own cloud account and the container your Phase 2 fork builds, not in a browser.

1. Get the service live on the internet (from Lesson 1)

  • Tag and docker push the Phase 2 starter’s /predict image to a registry, then deploy it to a container host (Cloud Run / Fly / Render-style).
  • curl https://<your-service-url>/health from a second device returns {"status":"ok"}, and curl -X POST https://<your-service-url>/predict with one Adult/Census record returns a prediction, proving a stranger off your machine can reach and use it.

2. Promote, do not just push (from Lesson 2)

  • Stand up a dev deployment with its own URL alongside prod, and deploy changes to dev first.
  • Promote the exact image digest that passed dev to prod: no per-environment rebuild. Confirm dev and prod report the same digest, not just the same latest tag.

3. Put it on a real domain over HTTPS (from Lesson 3)

  • Point a subdomain you control (e.g. predict.yourdomain.com) at the live service via a DNS record, and enable a managed TLS certificate.
  • curl -v https://predict.yourdomain.com/health shows a valid cert chain. Read the cert’s expiry from the output and confirm auto-renewal is configured so it does not lapse weeks later.

4. Build a one-step rollback (from Lesson 4)

  • Configure your release so a bad version is survivable: deploy a deliberately broken build to prod, then roll back to the previous known-good digest in a single step.
  • Confirm /predict is healthy again and note how long the rollback took. The previous artifact must already exist (Task 2’s promoted digests): rollback is repointing, not rebuilding.

5. Bound the cost (from Lesson 5)

  • Set a max-instances cap and a budget alert on the deployment, and list every attached resource (load balancer, static IP, egress) that bills independently of the main instance.
  • State the expected monthly cost and the capped worst case in one sentence each, written into your repo’s README.
Hints
  • Set a low DNS TTL before you create or change the record, not after: it shrinks the window where one network resolves the name and another still serves a cached miss. DNS must resolve before the TLS cert can issue; a cert error on a fresh domain is usually “not provisioned yet,” not “misconfigured”; wait the clock out before re-pushing.
  • Promote digests, not latest. Record which digest is live (in your README or a deploy log) so rollback is a known target. If you ship from latest or rebuild per environment, you will not have a one-step rollback when you need it.
  • The headline instance price is not the bill. Find the attached resources before the invoice does: a reserved static IP and a load balancer bill 24/7 even at zero traffic.

Rubric — your project is done when

This is the standard the module holds you to (each bar maps to the lesson that taught it):

  • A stranger can use it at a URL/predict returns a prediction over a public URL from a machine that is not yours. (Lesson 1)
  • Promoted, not rebuilt — prod runs the same image digest validated in dev; no per-environment rebuild. (Lesson 2)
  • TLS on, on a real domain — the service serves over https:// on a domain you control with a valid, auto-renewing certificate. (Lesson 3)
  • One-step rollback — you can repoint prod at the previous known-good digest in a single step and restore correct behavior fast. (Lesson 4)
  • Cost bounded and stated — a max-instances cap and a budget alert are configured, and you can state the expected and worst-case monthly figure. (Lesson 5)

Run the self-audit from the Module Summary against your own deploy before you submit: for each rubric line, confirm it holds against the live service, and if one fails, name which lesson’s failure mode (a public broken build, a per-environment rebuild, an unprovisioned cert, a rebuild-from-source rollback, an uncapped autoscaler) you reintroduced.

Submit

Use the branch workflow from the M1 git lesson, not commits straight to main. Branch off main (git checkout -b m8-cloud-deploy), build this module’s piece there, and open a pull request to merge it back once it meets the rubric. main stays the last-good version of the product you carry forward, so a half-finished module never breaks what later modules build on.

When your deploy meets every rubric line, merge your branch to main, push the deploy config to GitHub, and submit the repository URL and the live https:// URL a grader can hit here. (Submission coming soon.)

Coming soon

This lesson is not published yet. Join the waitlist to hear when it ships.

Coming soon