# Build stage
FROM node:20-alpine AS builder
WORKDIR /app
COPY package*.json ./
RUN npm ci --only=production
COPY . .
RUN npm run build
# Runtime stage
FROM node:20-alpine
WORKDIR /app
COPY --from=builder /app/dist ./dist
COPY --from=builder \
/app/node_modules ./node_modules
COPY --from=builder \
/app/package.json ./
ENV NODE_ENV=production
EXPOSE 3001
CMD ["node", "dist/server.js"]
version: '3.8'
services:
frontend:
build: ./frontend
ports:
- "5173:5173"
environment:
- VITE_API_URL=
http://localhost:3001
backend:
build: ./backend
ports:
- "3001:3001"
environment:
- DATABASE_URL=
mongodb://mongo:27017/pixelcraft
- REDIS_URL=redis://redis:6379
- JWT_SECRET=
dev-secret-change-in-prod
depends_on:
- mongo
- redis
mongo:
image: mongo:7
ports:
- "27017:27017"
volumes:
- mongo-data:/data/db
redis:
image: redis:7-alpine
ports:
- "6379:6379"
volumes:
mongo-data:
docker-compose up --build
# → Building frontend... ✅
# → Building backend... ✅
# → Pulling mongo:7... ✅
# → Pulling redis:7... ✅
# → Starting mongo... ✅
# → Starting redis... ✅
# → Starting backend... ✅
# → Starting frontend... ✅
# Open localhost:5173
# Everything is running.
# .dockerignore
node_modules
dist
.git
.env
.env.local
*.md
playwright-report
coverage
# Same idea as .gitignore:
# don't COPY unnecessary files
# into the Docker build context.
# node_modules alone saves 500MB+
# of build time.
# On a COMPLETELY fresh machine:
git clone git@github.com:you/pixelcraft.git
cd pixelcraft
docker-compose up --build
# That's it.
# No "install Node 20"
# No "install MongoDB"
# No "install Redis"
# No "configure environment"
# Just: clone → compose up → done.
git switch -c devops/PIXELCRAFT-084-docker
git add Dockerfile docker-compose.yml .dockerignore
git commit -m "Containerize PixelCraft with Docker (PIXELCRAFT-084)"
git push origin devops/PIXELCRAFT-084-docker
# PR → Review → Merge → Close ticket ✅
Containerization solves the environment problem.
A container packages code + runtime + dependencies + configuration into a single artifact that runs identically everywhere.
docker-compose up → entire PixelCraft stack running. New developer setup: clone → compose up → done. No "install this, configure that, pray it works." This is DevOps.