⇦ Back

WDX-180

Web Development X

Deployment, Production & Launching Your CMS

Shipping Software To The Real World

Building software is only half the job.

Getting it into production is the other half.

And sometimes the scarier half.

During this module we’ve been building:

  CRUD

  SQLite

  Express

  EJS

  Authentication

  Authorization

  Uploads

  Validation

  Testing

Everything works.

On your laptop.

Unfortunately:

  Your laptop ≠ The Internet

Today we solve that problem.

This lesson is about turning a local project into a real application that other people can access.

Learning Objectives

By the end of this lesson, students will be able to:

Part 1 — Development vs Production

Development:

  localhost

  Debugging

  Console Logs

  Experimental

Production:

  Real Users

  Real Data

  Real Traffic

  Real Problems

A surprising number of bugs only appear in production.

Which is software’s version of:

  "It worked yesterday."

Part 2 — Environment Variables

Hardcoded:

  const secret = 'super-secret';

Bad.

Hardcoded:

  const database = './db.sqlite';

Also bad.

Use environment variables.

Example:

.env:

  PORT=3000

  SESSION_SECRET=abc123

  DATABASE_PATH=db.sqlite

Access:

  const { loadEnvFile } = require('node:process');
  // Loads environment variables from the default .env file
  loadEnvFile();

  process.env.PORT

Benefits:

Part 3 — Using dotenv

Install:

dotenv

  npm install dotenv

Load:

  require('dotenv').config();

Now:

  process.env

contains values from:

  .env

Never commit:

  .env

to Git.

Ever.

Add:

  .env

immediately.

Part 4 — Production Configuration

Current:

  app.listen(3000);

Better:

  app.listen(process.env.PORT);

Hosting providers assign ports dynamically.

Hardcoding eventually breaks.

Part 5 — Understanding Reverse Proxies

Users think:

  Internet

  ↓

  Your App

Reality:

  Internet

  ↓

  Reverse Proxy

  ↓

  Node.js

Common reverse proxies:

Responsibilities:

  HTTPS

  Load Balancing

  Caching

  Compression

Node focuses on application logic.

Learn more about Reverse Proxies.

Part 6 — HTTPS Matters

Without HTTPS:

  Passwords

  Cookies

  Sessions

travel unencrypted.

Very bad.

HTTPS provides:

  Encryption

between browser and server.

Today there is little reason not to use HTTPS everywhere.

Certificates commonly come from:

Let's Encrypt

Part 7 — Session Security

Development:

  cookie: { secure: false }

Production:

  cookie: {
      secure: true,
      httpOnly: true
  }

Benefits:

  Better Session Protection

A small change.

A huge security improvement.

Part 8 — Logging Properly

Development:

  console.log('User created');

Production:

Need more.

Questions:

  Who logged in?

  When?

  Which route failed?

  What crashed?

Logs answer these questions.

Example:

  logger.info('User login',
      {
          userId: 1
      }
  );

Structured logs become invaluable later.

Here’s how you can implement logging with Morgan:

Install:

  npm install morgan

Use:

  const morgan = require('morgan');
  app.use(morgan('combined'));

Learn more about the Morgan Middleware.

Part 9 — Monitoring

Question:

  Is the server healthy?

Question:

  Is memory usage growing?

Question:

  Are users seeing errors?

Monitoring answers these.

Without monitoring:

  You discover outages from angry users.

Not ideal.

Part 10 — Handling Application Crashes

Node process crashes.

Question:

  What restarts it?

Common answer:

PM2

Install:

  npm install -g pm2

Run:

  pm2 start app.js

Benefits:

  Restart

  Monitoring

  Logs

A production staple.

Part 11 — Database Considerations

Current:

  SQLite

SQLite is fantastic.

But eventually:

  Multiple Servers

becomes difficult.

Common upgrade path:

PostgreSQL

Benefits:

  Scalability

  Concurrency

  Advanced Features

Many production systems use PostgreSQL.

Part 12 — Deployment Options

Small Projects:

Container-Based:

Cloud Providers:

For beginners:

  Render

  Railway

provide the fastest path to deployment.

Part 13 — Deployment Checklist

Before launch:

Security

  HTTPS

  Session Security

  Password Hashing

Configuration

  Environment Variables

  No Hardcoded Secrets

Reliability

  Logging

  Monitoring

  Error Handling

Data

  Database Backups

Testing

  All Tests Passing

  Decent coverage

This checklist prevents many disasters.

Not all disasters.

But many.

Part 14 — The CMS Architecture Review

Let’s review what we have built.

Presentation Layer:

  EJS

Application Layer:

  Express Routes

  Middleware

  Validation

Security Layer:

  Authentication

  Authorization

Persistence Layer:

  SQLite

Testing Layer:

  Vitest

  SuperTest

Infrastructure Layer:

  Deployment

  Environment Variables

  Monitoring

This resembles the architecture of many professional applications.

Part 15 — What We Would Build Next

If this were a larger course, the next topics would likely be:

Search

Using: SQLite FTS5

Categories & Tags

Content organization.

Rich Text Editing

Using:

TinyMCE

or

CKEditor

APIs

Building:

  JSON APIs

alongside EJS pages.

Background Jobs

Using:

BullMQ

Caching

Using: Redis

Docker

Containerized deployment.

CI/CD

Automated deployments.

Part 16 — The Most Important Lesson

The biggest takeaway from this course isn't:

```text 
Express

SQLite

EJS
```

Those tools will change.

The important lesson is understanding:

```text 
Requests

Responses

Routing

Persistence

Security

Testing

Deployment
```

Frameworks come and go.

Principles endure.

A developer who understands these fundamentals can learn:

* Express
* NestJS
* Fastify
* Laravel
* Django
* Spring Boot

far more easily than someone who only memorized framework APIs.

Common Beginner Mistakes

Committing Secrets

Never commit:

  .env

No Backups

Every database eventually needs recovery.

No Monitoring

Problems should be discovered before users report them.

Running Without HTTPS

Protect user data.

Always.

Deploying Untested Code

Hope is not a deployment strategy.

Course Retrospective

Over 15 modules you learned:

Foundations

Data

Views

Security

Reliability

Operations

Final Key Takeaways

A web application is ultimately a pipeline:

  Request

  ↓

  Validation

  ↓

  Authentication

  ↓

  Authorization

  ↓

  Business Logic

  ↓

  Database

  ↓

  Response

Master this flow and you can understand nearly every modern web framework.

Congratulations.

You haven’t just built a CMS.

You’ve built a complete mental model for how server-side web applications work. And unlike frameworks, that knowledge doesn’t go out of date every six months because someone renamed a configuration file and called it innovation. 🚀


⚠️ A large part of the content of this module was created using Generative AI (ChatGPT). The synthetic (AI-generated) content was reviewed and curated by Kostas Minaidis.


Project maintained by in-tech-gration Hosted on GitHub Pages — Theme by mattgraham