~/projects/wsl-docker-guide

const devEnv = {
  wsl: "Ubuntu",
  runtime: "Docker",
  app: "Node.js"
};

// Complete runbook for containerized Node.js development on Windows

architecture.diagram
đŸĒŸ
Windows Host
// No Node.js installed
🐧
WSL (Ubuntu)
// Linux environment
đŸŗ
Docker Engine
// Container runtime
âŦĸ
Node.js Container
// Isolated runtime + deps

table_of_contents.md

Install and Configure WSL

01
Enable WSL on Windows

Open PowerShell as Administrator and run:

PowerShell
wsl --install

This enables WSL, installs Ubuntu, and sets WSL 2 as default. Reboot if prompted.

02
Launch Ubuntu

From Start Menu → Ubuntu

On first launch, create a non-root user and choose a password. This will be your daily development user.

03
Verify WSL Version
Bash
wsl --status

You should see: Default Version: 2

Install Docker Engine

No Docker Desktop required - we install Docker directly in WSL.

04
Update System
Bash
sudo apt update && sudo apt upgrade -y
05
Install Dependencies
Bash
sudo apt install -y ca-certificates curl gnupg lsb-release
06
Add Docker GPG Key
Bash
sudo mkdir -p /etc/apt/keyrings curl -fsSL https://download.docker.com/linux/ubuntu/gpg \ | sudo gpg --dearmor -o /etc/apt/keyrings/docker.gpg
07
Add Docker Repository
Bash
echo \ "deb [arch=$(dpkg --print-architecture) signed-by=/etc/apt/keyrings/docker.gpg] \ https://download.docker.com/linux/ubuntu \ $(lsb_release -cs) stable" \ | sudo tee /etc/apt/sources.list.d/docker.list > /dev/null
08
Install Docker Engine
Bash
sudo apt update sudo apt install -y docker-ce docker-ce-cli containerd.io docker-compose-plugin
09
Start Docker
Bash
sudo systemctl enable docker sudo systemctl start docker

Verify with: sudo systemctl status docker

Fix Docker Permissions

âš ī¸
Critical Step

This step avoids using sudo for Docker commands in daily work.

10
Add User to Docker Group
Bash
sudo usermod -aG docker $USER
11
Restart WSL

From PowerShell:

PowerShell
wsl --shutdown

Then reopen Ubuntu.

12
Verify Access
Bash
docker ps

Expected: No permission error. Empty list is OK.

Project Directory Setup

đŸšĢ
Important Rule

Never develop inside /mnt/c. Windows filesystems cause permission and performance issues.

13
Create Linux-Native Directory
Bash
mkdir -p ~/projects cd ~/projects

Verify ownership: ls -ld ~/projects

Create Node.js App

14
Project Structure
Bash
mkdir task-manager-apis && cd task-manager-apis mkdir src && touch src/index.js Dockerfile docker-compose.yml package.json .dockerignore
15
package.json
package.json
{ "name": "task-manager-apis", "version": "1.0.0", "main": "src/index.js", "scripts": { "dev": "npx nodemon src/index.js" }, "dependencies": { "express": "^4.18.2" }, "devDependencies": { "nodemon": "^3.1.11" } }
16
src/index.js
src/index.js
import express from "express"; const app = express(); app.use(express.json()); app.get("/health", (_, res) => res.json({ status: "ok" })); app.listen(3333, () => console.log("API running on port 3333"));

Docker Configuration

17
.dockerignore
.dockerignore
node_modules npm-debug.log .git
18
Dockerfile
Dockerfile
FROM node:20-alpine WORKDIR /app COPY package*.json ./ RUN npm install COPY . . EXPOSE 3333 CMD ["npm", "run", "dev"]
19
docker-compose.yml
docker-compose.yml
services: api: build: . container_name: task-manager-api ports: - "3333:3333" volumes: - .:/app - /app/node_modules command: npm run dev
â„šī¸
Volume Strategy

.:/app = source code | /app/node_modules = Docker-managed. Prevents permission issues.

Build and Run

20
Build
Bash
docker compose build --no-cache
21
Start
Bash
docker compose up
22
Test
Bash
curl http://localhost:3333/health

Expected: { "status": "ok" }

NPM Packages

đŸšĢ
Rule

Never run npm install on the host. Always use Docker.

▸
Install Dependency
Bash
docker compose exec api npm install axios
▸
Install Dev Dependency
Bash
docker compose exec api npm install -D eslint

Common Mistakes

✕
Install Node on Windows
✕
Run npm install outside Docker
✕
Develop inside /mnt/c
✕
Mount node_modules from host
✕
Use sudo docker
✕
chmod 777 fixes

Command Cheatsheet

đŸŗ

Docker Service

Check running
docker ps
Daemon status
systemctl status docker
🔨

Build & Run

Clean build
docker compose build --no-cache
Cached build
docker compose build
Start
docker compose up
Background
docker compose up -d
Stop
docker compose down
Stop + volumes
docker compose down -v
đŸ“Ļ

Container Management

List running
docker ps
List all
docker ps -a
Logs
docker compose logs api
Follow logs
docker compose logs -f api
đŸ“Ĩ

NPM (via Docker)

Add dep
docker compose exec api npm install axios
Add dev dep
docker compose exec api npm install -D nodemon
Install all
docker compose exec api npm install
🔄

Reset Everything (90% fix)

Bash
docker compose down -v docker compose build --no-cache docker compose up

🧠 Mental Model

Host
Editor only
→
WSL
Linux shell
→
Docker
Runtime
→
Container
Truth

Final Outcome

🐧
Linux-native dev env
🔄
Reproducible builds
đŸŽ¯
Production parity
🔐
Zero permission issues
🚀
CI/CD ready
â˜ī¸
AWS compatible

// Next Extensions

  • 🍃 MongoDB
  • đŸ“Ļ Multi-stage Dockerfile
  • 🔧 Env variables
  • 💚 Health checks
  • â˜ī¸ AWS deploy