Back to path
ExpertInvoiceDesk · Project 12 of 12 ~12h· 6 milestones

Ship it to production and keep it up

Continues from the last build: It is tested, observable, cached, and safe. It has never left your laptop.

Rung 11 gave you eyes: structured logs, Sentry catching the errors, timings on every route.

Render blueprintsZero-downtime migrationsSecrets management by environmentBackup and restore drillsSecurity headers and cookie hardeningOWASP threat modelingStripe live mode checklistUptime monitoring

What you'll build

InvoiceDesk is live on a real domain with TLS, deployed from a versioned render.yaml that stands up the web service, worker, managed Postgres, and managed Redis together. Secrets are split by environment with nothing sensitive in the repo. You have performed a real zero-downtime column rename using expand and contract, and a real backup and restore drill against a scratch database. Security headers, cookie flags, and a written threat model are in place, mapped to the OWASP issues you already built defenses for. Stripe is in live mode, an uptime monitor is watching the health check, and the README carries the final architecture diagram plus a 90 second demo script ready for an interview.

See how we teach, before you sign up

You don't just get code dumped on you. Every starter file and every solution is explained line-by-line, in plain English. Here's one real file from this project:

render.yamlyaml
services:
  - type: web
    name: invoicedesk-web
    runtime: node
    plan: starter
    buildCommand: pnpm install && pnpm build
    startCommand: pnpm start
    healthCheckPath: /api/health
    preDeployCommand: pnpm drizzle-kit migrate
    envVars:
      - key: DATABASE_URL
        fromDatabase:
          name: invoicedesk-db
          property: connectionString
  - type: worker
    name: invoicedesk-worker
    runtime: node
    plan: starter
    buildCommand: pnpm install && pnpm build
    startCommand: pnpm worker
databases:
  - name: invoicedesk-db
    plan: starter
    postgresMajorVersion: 16

Reading this file

  • preDeployCommand: pnpm drizzle-kit migrateMigrations run and finish before the new instance takes traffic, which is what makes expand/contract deploys safe.
  • healthCheckPath: /api/healthRender withholds traffic from the new instance until this returns 200.
  • startCommand: pnpm workerThe worker is its own service, its own process, never bundled into the web build.

Starter file for this rung.

That's 1 of 9 explained code blocks in this single project.

The build, milestone by milestone

  1. 1

    Wire the production deploy with a Render blueprint

    6 guided steps

    A blueprint means the whole production topology is reviewable in a pull request instead of clicked together in a dashboard nobody else can see. It also means you can spin up a second environment (staging) by pointing the same file at a new branch.

  2. 2

    Split secrets and env by environment

    5 guided steps

    A staging Stripe key leaking is embarrassing. A production Stripe secret key or AUTH_SECRET leaking is how a freelancer's client data or a payment webhook gets forged. Separating env by environment means a compromised staging credential can never touch a real payment.

  3. 3

    Ship a zero-downtime column rename with expand and contract

    6 guided steps

    A plain ALTER TABLE RENAME COLUMN deployed at the same moment as new code that expects the new name will always have a window where either old code hits a missing column or new code hits a missing column, because Render runs your migration and boots your new instance as two separate steps, not one atomic one.

  4. 4

    Run the backup and restore drill

    5 guided steps

    A backup that has never been restored is a guess, not a safety net. The only way to know RPO (how much data you could lose) and RTO (how long recovery takes) are acceptable is to actually time a restore.

  5. 5

    Run the security pass before launch

    5 guided steps

    By this rung most of the real security work is already done: rung 3 fixed IDOR with ownership checks, Drizzle's parameterized queries already prevent SQL injection, and rung 9 already rate limits. This pass closes the remaining gaps (headers, cookies, dependencies) and forces you to write down what you're actually defending against, which is the part interviewers ask about.

  6. 6

    Write the launch checklist and the portfolio writeup

    5 guided steps

    This is the rung a hiring manager actually sees. A live URL, a clear README with the final diagram, and a tight demo script turn twelve rungs of work into something that reads as a real, small, production product in under two minutes.

What's inside when you start

3 starter files, ready to clone
6 guided milestones
6 full reference solutions
9 code blocks explained line-by-line
6 "is it working?" checks
6 interview questions it prepares you for

You'll walk away with

render.yaml deployed and live, web plus worker plus managed Postgres plus managed Redis, health check green
Staging and production env groups with no secret values committed, .env.example kept as the contract
A completed expand and contract column rename, verified with zero rows left on the old-only path
A restore drill: a manual pg_dump restored into a scratch database with row counts matching production
Security headers, secure cookie flags, a clean pnpm audit, and a written 10-line threat model
Live-mode Stripe, a custom domain with TLS, an uptime monitor, and a README with the final diagram and demo script

This is portfolio-grade. Build it free.

Sign up to unlock every milestone step-by-step, the code skeletons, full reference solutions, and checkable tasks, with your progress saved as you build.

Start building