Node.jsМодуль 7: Тестирование и деплой
Docker
Dockerfile, docker-compose, контейнеризация
Цель урока
В этом уроке ты научишься:
- Создавать Dockerfile для Node.js
- Использовать docker-compose
- Оптимизировать образы
Dockerfile
Базовый Dockerfile
# Dockerfile
FROM node:20-alpine
WORKDIR /app
COPY package*.json ./
RUN npm ci --only=production
COPY . .
EXPOSE 3000
CMD ["node", "src/index.js"]Оптимизированный Dockerfile
# Build stage
FROM node:20-alpine AS builder
WORKDIR /app
COPY package*.json ./
RUN npm ci
COPY . .
RUN npm run build
# Production stage
FROM node:20-alpine
WORKDIR /app
COPY package*.json ./
RUN npm ci --only=production && npm cache clean --force
COPY --from=builder /app/dist ./dist
USER node
EXPOSE 3000
CMD ["node", "dist/index.js"].dockerignore
node_modules
npm-debug.log
.git
.gitignore
.env
.env.*
Dockerfile
docker-compose.yml
coverage
.nyc_output
logs
*.logdocker-compose
Базовый
# docker-compose.yml
version: '3.8'
services:
app:
build: .
ports:
- "3000:3000"
environment:
- NODE_ENV=production
- DATABASE_URL=mongodb://mongo:27017/myapp
depends_on:
- mongo
restart: unless-stopped
mongo:
image: mongo:7
volumes:
- mongo_data:/data/db
restart: unless-stopped
volumes:
mongo_data:С Redis и PostgreSQL
version: '3.8'
services:
app:
build: .
ports:
- "3000:3000"
environment:
- NODE_ENV=production
- DATABASE_URL=postgresql://user:pass@postgres:5432/myapp
- REDIS_URL=redis://redis:6379
depends_on:
- postgres
- redis
restart: unless-stopped
postgres:
image: postgres:16-alpine
environment:
- POSTGRES_USER=user
- POSTGRES_PASSWORD=pass
- POSTGRES_DB=myapp
volumes:
- postgres_data:/var/lib/postgresql/data
restart: unless-stopped
redis:
image: redis:7-alpine
restart: unless-stopped
volumes:
postgres_data:Команды Docker
# Сборка образа
docker build -t my-app .
# Запуск контейнера
docker run -p 3000:3000 my-app
# С переменными окружения
docker run -p 3000:3000 -e NODE_ENV=production my-app
# docker-compose
docker-compose up -d # Запуск
docker-compose down # Остановка
docker-compose logs -f app # Логи
docker-compose exec app sh # Войти в контейнер
docker-compose build # ПересборкаDevelopment с Docker
# docker-compose.dev.yml
version: '3.8'
services:
app:
build:
context: .
dockerfile: Dockerfile.dev
ports:
- "3000:3000"
volumes:
- .:/app
- /app/node_modules
environment:
- NODE_ENV=development
command: npm run dev# Dockerfile.dev
FROM node:20-alpine
WORKDIR /app
COPY package*.json ./
RUN npm install
COPY . .
CMD ["npm", "run", "dev"]docker-compose -f docker-compose.dev.yml upHealth Check
HEALTHCHECK --interval=30s --timeout=3s --start-period=5s --retries=3 \
CMD wget --no-verbose --tries=1 --spider http://localhost:3000/health || exit 1// Endpoint для health check
app.get('/health', (req, res) => {
res.json({ status: 'ok', timestamp: new Date() });
});Практика
Задание: Docker для API
Задача: Создай Docker конфигурацию для API с MongoDB.
Решение:
# Dockerfile
FROM node:20-alpine
WORKDIR /app
COPY package*.json ./
RUN npm ci --only=production
COPY . .
EXPOSE 3000
CMD ["node", "src/index.js"]# docker-compose.yml
version: '3.8'
services:
api:
build: .
ports:
- "3000:3000"
environment:
- DATABASE_URL=mongodb://mongo:27017/api
depends_on:
- mongo
mongo:
image: mongo:7
volumes:
- mongo_data:/data/db
volumes:
mongo_data:Проверь себя
- Зачем нужен multi-stage build?
- Что делает .dockerignore?
- Как передать переменные окружения?