Node.js апп containerize хийх
Энэ хичээлд жинхэнэ Express аппликейшнийг Docker-т тохируулна. Development болон production хоёр орчинд ажиллах Dockerfile бичнэ.
Апп бэлдэх
Энгийн Express апп:
myapp/
├── src/
│ └── index.ts
├── package.json
├── tsconfig.json
└── .dockerignore
src/index.ts
import express from "express";
const app = express();
const PORT = process.env.PORT ?? 3000;
app.use(express.json());
app.get("/health", (_req, res) => {
res.json({ status: "ok", timestamp: Date.now() });
});
app.get("/", (_req, res) => {
res.json({ message: "Сайн уу, Docker!" });
});
app.listen(PORT, () => {
console.log(`Сервер ${PORT} порт дээр ажиллаж байна`);
});
package.json
{
"name": "myapp",
"scripts": {
"dev": "ts-node-dev src/index.ts",
"build": "tsc",
"start": "node dist/index.js"
},
"dependencies": {
"express": "^4.18.2"
},
"devDependencies": {
"@types/express": "^4.17.21",
"typescript": "^5.3.3",
"ts-node-dev": "^2.0.0"
}
}
.dockerignore файл
node_modules болон бусад шаардлагагүй файлыг image-д оруулахгүй байхад .dockerignore ашиглана:
node_modules
dist
.git
.gitignore
*.md
.env
.env.*
npm-debug.log*
coverage/
.nyc_output/
.dockerignore байхгүй бол COPY . . тушаал node_modules-ийг хуулж, layer cache буруу болно.
Production Dockerfile
# ── Stage 1: builder ──────────────────────────
FROM node:20-alpine AS builder
WORKDIR /app
# Эхлээд package.json хуулна — layer cache ашиглах
COPY package*.json ./
RUN npm ci
COPY tsconfig.json ./
COPY src/ ./src/
RUN npm run build
# ── Stage 2: production ───────────────────────
FROM node:20-alpine AS production
# Аюулгүй байдал: root биш хэрэглэгчээр ажиллуулна
RUN addgroup -S appgroup && adduser -S appuser -G appgroup
WORKDIR /app
COPY package*.json ./
RUN npm ci --only=production && npm cache clean --force
COPY --from=builder /app/dist ./dist
# Өмчлөгчийг тохируулна
RUN chown -R appuser:appgroup /app
USER appuser
EXPOSE 3000
HEALTHCHECK --interval=30s --timeout=5s --start-period=10s --retries=3 \
CMD wget -qO- http://localhost:3000/health || exit 1
CMD ["node", "dist/index.js"]
Development Dockerfile
Хөгжүүлэлтэд hot reload шаардлагатай. Dockerfile.dev нэртэй тусдаа файл хийнэ:
FROM node:20-alpine
WORKDIR /app
COPY package*.json ./
RUN npm install
COPY . .
EXPOSE 3000
CMD ["npm", "run", "dev"]
# Development container ажиллуулах
docker build -f Dockerfile.dev -t myapp:dev .
docker run -p 3000:3000 -v $(pwd)/src:/app/src myapp:dev
-v $(pwd)/src:/app/src — src фолдерийг mount хийснээр файл өөрчлөгдөхөд container дотор шууд тусгагдана.
docker-compose.yml — development
services:
app:
build:
context: .
dockerfile: Dockerfile.dev
ports:
- "3000:3000"
volumes:
- ./src:/app/src
environment:
- NODE_ENV=development
restart: unless-stopped
docker compose up
Build ба ажиллуулах
# Production image build
docker build -t myapp:latest .
# Container ажиллуулах
docker run -d -p 3000:3000 --name myapp myapp:latest
# Ажиллаж байгаа эсэх шалгах
curl http://localhost:3000/health
node_modules layer оновчлол
Layer cache ажиллахын тулд дараалал чухал:
# ✅ Зөв: package.json өөрчлөгдөхгүй бол npm install дахин ажиллахгүй
COPY package*.json ./
RUN npm ci
COPY . .
# ❌ Буруу: src файл өөрчлөгдөх бүрт npm install дахин ажиллана
COPY . .
RUN npm ci
Environment variable тохируулах
ENV NODE_ENV=production
ENV PORT=3000
Эсвэл container ажиллуулахдаа:
docker run -e NODE_ENV=production -e PORT=8080 -p 8080:8080 myapp
Image хэмжээ шалгах
docker images myapp
# REPOSITORY TAG IMAGE ID SIZE
# myapp latest abc123def456 112MB
node:20-alpine + multi-stage ашигласнаар 100–150MB хүртэл буурна.
Дараагийн хичээлд:
Python аппликейшнийг (FastAPI) Docker-т тохируулна — requirements.txt, virtual env шаардлагагүй болох тухай.