table_of_contents.md
Install and Configure WSL
Open PowerShell as Administrator and run:
wsl --installThis enables WSL, installs Ubuntu, and sets WSL 2 as default. Reboot if prompted.
From Start Menu â Ubuntu
On first launch, create a non-root user and choose a password. This will be your daily development user.
wsl --statusYou should see: Default Version: 2
Install Docker Engine
No Docker Desktop required - we install Docker directly in WSL.
sudo apt update && sudo apt upgrade -ysudo apt install -y ca-certificates curl gnupg lsb-releasesudo mkdir -p /etc/apt/keyrings
curl -fsSL https://download.docker.com/linux/ubuntu/gpg \
| sudo gpg --dearmor -o /etc/apt/keyrings/docker.gpgecho \
"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/nullsudo apt update
sudo apt install -y docker-ce docker-ce-cli containerd.io docker-compose-pluginsudo systemctl enable docker
sudo systemctl start dockerVerify with: sudo systemctl status docker
Fix Docker Permissions
This step avoids using sudo for Docker commands in daily work.
sudo usermod -aG docker $USERFrom PowerShell:
wsl --shutdownThen reopen Ubuntu.
docker psExpected: No permission error. Empty list is OK.
Project Directory Setup
Never develop inside /mnt/c. Windows filesystems cause permission and performance issues.
mkdir -p ~/projects
cd ~/projectsVerify ownership: ls -ld ~/projects
Create Node.js App
mkdir task-manager-apis && cd task-manager-apis
mkdir src && touch src/index.js Dockerfile docker-compose.yml package.json .dockerignore{
"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" }
}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
node_modules
npm-debug.log
.gitFROM node:20-alpine
WORKDIR /app
COPY package*.json ./
RUN npm install
COPY . .
EXPOSE 3333
CMD ["npm", "run", "dev"]services:
api:
build: .
container_name: task-manager-api
ports:
- "3333:3333"
volumes:
- .:/app
- /app/node_modules
command: npm run dev.:/app = source code | /app/node_modules = Docker-managed. Prevents permission issues.
Build and Run
docker compose build --no-cachedocker compose upcurl http://localhost:3333/healthExpected: { "status": "ok" }
NPM Packages
Never run npm install on the host. Always use Docker.
docker compose exec api npm install axiosdocker compose exec api npm install -D eslintCommon Mistakes
npm install outside Docker/mnt/cnode_modules from hostsudo dockerchmod 777 fixesCommand Cheatsheet
Docker Service
docker pssystemctl status dockerBuild & Run
docker compose build --no-cachedocker compose builddocker compose updocker compose up -ddocker compose downdocker compose down -vContainer Management
docker psdocker ps -adocker compose logs apidocker compose logs -f apiNPM (via Docker)
docker compose exec api npm install axiosdocker compose exec api npm install -D nodemondocker compose exec api npm installReset Everything (90% fix)
docker compose down -v
docker compose build --no-cache
docker compose up