Live Class: 60
Duration: 90 minutes
Difficulty: Intermediate (hands-on)
By the end of this class, you will:
- Initialize an Express + TypeScript project from zero with npm/pnpm.
- Set up TypeScript strict mode with path aliases for clean imports.
- Configure npm scripts (dev, build, start, lint, format).
- Use environment variables safely with
.envand validation (Zod). - Implement structured logging with Pino.
- Build a production-ready folder structure following industry patterns.
- Write a multi-stage Dockerfile for containerization.
- Use docker-compose to run app + MongoDB together.
- Implement graceful shutdown (handle SIGTERM, close connections).
- Deploy a starter project that you'll reuse for all future classes.
- Comfortable with npm/pnpm commands
- Understand Node.js basics
- Completed Class 1 (layered architecture)
- Docker and docker-compose installed
- Terminal/CLI confidence
| Time | Topic | Activity |
|---|---|---|
| 0:00 - 0:10 | Intro & Project Setup | Slides |
| 0:10 - 0:30 | npm init & TypeScript Config | Live coding |
| 0:30 - 0:50 | Folder Structure & npm Scripts | Live demo |
| 0:50 - 1:05 | Environment Variables & Logging | Code walkthrough |
| 1:05 - 1:20 | Docker & docker-compose | Live Docker build |
| 1:20 - 1:30 | Q&A & Homework Preview | Discussion |
- Speaker Outline
- 01: Project Scaffolding
- 02: Configuration & Environment
- 03: Docker & Deployment
- Demo: Production Express Starter
cd code/demo-express-starter
pnpm install
pnpm devVisit http://localhost:3000/health and http://localhost:3000/api/docs (when ready).
##Package Scripts
{
"scripts": {
"dev": "tsx watch src/main.js", // Development (auto-reload)
"build": "tsc", // Compile TypeScript
"start": "node dist/main.js", // Run compiled app
"lint": "tsc --noEmit", // Check types
"format": "prettier --write src/**/*" // Format code
}
}##Environment Variables
// .env
NODE_ENV=development
PORT=3000
DATABASE_URL=mongodb://localhost:27017/taskdb
LOG_LEVEL=debugValidate with Zod:
const envSchema = z.object({
NODE_ENV: z.enum(['development', 'production']),
PORT: z.coerce.number().default(3000),
DATABASE_URL: z.string().url(),
LOG_LEVEL: z.enum(['debug', 'info', 'warn', 'error'])
});
const env = envSchema.parse(process.env);FROM node:20-alpine
WORKDIR /app
COPY package*.json .
RUN npm install
COPY . .
EXPOSE 3000
CMD ["npm", "run", "dev"]
# For production
# CMD ["npm", "start"]src/
├── main.js ← Entry point
├── config.js ← Environment config
├── logger.js ← Structured logging
# Build image
docker build -t taskapp:latest .
# Run container
docker run -p 3000:3000 -e NODE_ENV=development taskapp:latest
# Using docker-compose
docker-compose up
# Build fresh
docker-compose up --build- Forgetting
.env→ App crashes on startup (env vars undefined). - Not using
tsxfor dev → Slow development cycle. - Shipping
node_modulesin Docker → Bloated image. - Not validating environment → Silent bugs from typos.
- Forgetting graceful shutdown → Requests lost on deploy.
- ✅
pnpm devworks - ✅
pnpm buildproduces dist/ - ✅
pnpm startruns production build - ✅
docker buildsucceeds - ✅
docker-compose upbrings app + DB online - ✅
curl localhost:3000/healthreturns{ "status": "ok" }
- Why use a multi-stage Dockerfile? — Reduces image size by excluding build tools.
- How do you validate environment variables? — Schema validation (Zod, Joi) before app starts.
- What's graceful shutdown? — Stop accepting requests, finish in-flight ones, then exit.
- Why use
tsxin dev? — Fast dev cycle; auto-compiles and reloads.
| Term | Banglish | Explanation |
|---|---|---|
| Environment Variables | পরিবেশ ভেরিয়েবল | অ্যাপ চালানোর জন্য সেটিংস (উদাঃ পোর্ট, ডাটাবেস URL) |
| Docker Image | ডকার ইমেজ | আপনার অ্যাপের ব্লুপ্রিন্ট (রান করার জন্য প্রস্তুত) |
| Container | কন্টেইনার | চলমান ডকার ইমেজ (জিনিসের বাস্তব উদাহরণ) |
| docker-compose | ডকার-কম্পোজ | একাধিক সেবা একসাথে চালানোর টুল |
| Graceful Shutdown | সুন্দর বন্ধ | অ্যাপ চলমান কাজ শেষ করে নিরাপদে বন্ধ করা |
- Demo won't run? Check Node 20 (
node -v), runpnpm install. - Docker errors? Ensure Docker daemon is running (
docker ps). - Environment validation fails? Check
.envfile exists and is in repo root.
**Now let's build something production-grade. Let's go! **