Deployment
Website Rebuild with Express
Chapter 11 · Deployment
server.js is already a plain, standalone Node HTTP server — the identical situation Astro's own Node adapter produced in its Chapter 11. This chapter reuses that exact mechanism deliberately, rather than forcing a sixth distinct deployment story to exist for its own sake.
No Build Step at All
Unlike every framework-based sibling in this series, there's nothing to compile, bundle, or transpile — server.js runs directly, exactly as written.
Secrets: One More Small Explicit Step
A plain .env file — the same simplest secrets story as Next.js, Django, Laravel, and Astro, not Rails' own reversed encrypted-commit approach. Even loading it needs one more explicit step here: dotenv is a separate package, where several sibling frameworks bundle some form of .env loading by convention.
Keeping the Process Alive: PM2, Reused Unchanged
Apache's mod_proxy_http, Reused Unchanged
mod_proxy_http because its Node adapter produces a plain standalone HTTP server on a local port. Express's own server.js is exactly that same thing, with no framework layer in between. There's no genuine reason for a different Apache mechanism here — reusing the identical configuration is the honest answer, not a missed opportunity for a "sixth variant."
No Migration Tooling Either
drizzle-kit migrate equivalent. Chapter 2's own schema.sql is applied directly via the mysql CLI, and any future schema change would need to be written and applied the same way — by hand, with no tracked migration history. A real production project at this scale would likely want a lightweight migration runner; this course doesn't build one, the same honest-scope-note tradition every capstone in this series already follows.
Six Deployment Stories, Compared One Final Time
| Next.js | Django | Laravel | Rails | Astro | Express | |
|---|---|---|---|---|---|---|
| App server process | Node (PM2) | gunicorn | PHP-FPM | Passenger-embedded | Node adapter (PM2) | Plain server.js (PM2) |
| Apache module used | N/A | N/A | mod_proxy_fcgi | mod_passenger | mod_proxy_http | mod_proxy_http — reused unchanged |
| Build step? | Yes | No | Yes (assets) | No | Yes | None at all |
node server.js is genuinely the entire production artifact. Consistent with every other chapter in this course: the least is provided by default, and the least ceremony is required to run it.
Hands-On Exercises
Run the production server directly via node server.js, with no build step, and confirm it serves the full site correctly.
📄 View solutionConfigure PM2 to run the server, simulate a crash by killing the process directly, and confirm PM2 restarts it automatically.
📄 View solutionConfigure the Apache VirtualHost with mod_proxy_http reverse-proxying to the Node server, and confirm the site is reachable through Apache's own domain rather than the raw Node port directly.
📄 View solutionChapter 11 Quick Reference
node server.js— the entire production artifact, no build step at alldotenv— one more explicit package needed, even for the simplest possible secrets story- PM2 and
mod_proxy_http— reused unchanged from Astro's own Chapter 11, the honest answer for the identical situation - No migration tooling — a real, named gap;
schema.sqlapplied by hand - Next chapter: Capstone — A Complete, Working Flexible-Routing Site