- Added comprehensive course structure with 11 modules - Included theoretical content, practical examples, and tasks - Multi-language code examples (Java, Rust, Node.js, Python) - Detailed analysis of architectural approaches and trade-offs - Complete caching strategies documentation - Architecture examples from real-world systems (Twitter, Netflix, Uber) - Structured navigation and learning path - Ready for educational use
370 lines
9.8 KiB
Markdown
370 lines
9.8 KiB
Markdown
# Docker
|
|
|
|
## Навигация
|
|
- [🏠 Главная страница курса](../../../README.md)
|
|
- [📚 Модуль 3](../README.md)
|
|
|
|
---
|
|
|
|
## Основы Docker
|
|
|
|
**Docker** — платформа для разработки, доставки и запуска приложений в контейнерах.
|
|
|
|
## Архитектура Docker
|
|
|
|
```
|
|
┌─────────────────────────────────────┐
|
|
│ Docker Client │
|
|
├─────────────────────────────────────┤
|
|
│ Docker Daemon │
|
|
│ ┌─────────────┐ ┌─────────────────┐ │
|
|
│ │ Images │ │ Containers │ │
|
|
│ └─────────────┘ └─────────────────┘ │
|
|
├─────────────────────────────────────┤
|
|
│ Container Runtime │
|
|
└─────────────────────────────────────┘
|
|
```
|
|
|
|
## Dockerfile
|
|
|
|
**Dockerfile** — текстовый файл с инструкциями для создания образа.
|
|
|
|
### Технический пример - Dockerfile для Spring Boot приложения:
|
|
|
|
```dockerfile
|
|
# Многоэтапная сборка для оптимизации размера образа
|
|
# Этап 1: Сборка приложения
|
|
FROM maven:3.8.6-openjdk-17-slim AS build
|
|
|
|
# Установка рабочей директории
|
|
WORKDIR /app
|
|
|
|
# Копирование файлов pom.xml для кэширования зависимостей
|
|
COPY pom.xml .
|
|
COPY src ./src
|
|
|
|
# Сборка приложения
|
|
RUN mvn clean package -DskipTests
|
|
|
|
# Этап 2: Создание финального образа
|
|
FROM openjdk:17-jre-slim
|
|
|
|
# Установка рабочей директории
|
|
WORKDIR /app
|
|
|
|
# Создание пользователя для безопасности
|
|
RUN groupadd -r appuser && useradd -r -g appuser appuser
|
|
|
|
# Копирование собранного JAR файла
|
|
COPY --from=build /app/target/*.jar app.jar
|
|
|
|
# Изменение владельца файлов
|
|
RUN chown -R appuser:appuser /app
|
|
USER appuser
|
|
|
|
# Открытие порта
|
|
EXPOSE 8080
|
|
|
|
# Переменные окружения
|
|
ENV JAVA_OPTS="-Xmx512m -Xms256m"
|
|
ENV SPRING_PROFILES_ACTIVE=production
|
|
|
|
# Health check
|
|
HEALTHCHECK --interval=30s --timeout=3s --start-period=5s --retries=3 \
|
|
CMD curl -f http://localhost:8080/actuator/health || exit 1
|
|
|
|
# Запуск приложения
|
|
ENTRYPOINT ["sh", "-c", "java $JAVA_OPTS -jar app.jar"]
|
|
```
|
|
|
|
### Dockerfile для микросервиса на Node.js:
|
|
|
|
```dockerfile
|
|
# Базовый образ Node.js
|
|
FROM node:18-alpine AS base
|
|
|
|
# Установка рабочей директории
|
|
WORKDIR /app
|
|
|
|
# Установка системных зависимостей
|
|
RUN apk add --no-cache \
|
|
dumb-init \
|
|
curl
|
|
|
|
# Создание пользователя для безопасности
|
|
RUN addgroup -g 1001 -S nodejs && \
|
|
adduser -S nextjs -u 1001
|
|
|
|
# Этап установки зависимостей
|
|
FROM base AS deps
|
|
COPY package*.json ./
|
|
RUN npm ci --only=production && npm cache clean --force
|
|
|
|
# Этап сборки
|
|
FROM base AS builder
|
|
COPY package*.json ./
|
|
RUN npm ci
|
|
COPY . .
|
|
RUN npm run build
|
|
|
|
# Финальный этап
|
|
FROM base AS runner
|
|
ENV NODE_ENV=production
|
|
|
|
# Копирование зависимостей
|
|
COPY --from=deps /app/node_modules ./node_modules
|
|
COPY --from=builder /app/dist ./dist
|
|
COPY --from=builder /app/public ./public
|
|
|
|
# Копирование конфигурационных файлов
|
|
COPY --from=builder /app/package.json ./package.json
|
|
|
|
# Изменение владельца файлов
|
|
RUN chown -R nextjs:nodejs /app
|
|
USER nextjs
|
|
|
|
# Открытие порта
|
|
EXPOSE 3000
|
|
|
|
# Health check
|
|
HEALTHCHECK --interval=30s --timeout=3s --start-period=5s --retries=3 \
|
|
CMD curl -f http://localhost:3000/health || exit 1
|
|
|
|
# Запуск приложения
|
|
ENTRYPOINT ["dumb-init", "--"]
|
|
CMD ["node", "dist/index.js"]
|
|
```
|
|
|
|
## Docker Compose
|
|
|
|
**Docker Compose** — инструмент для определения и запуска многоконтейнерных приложений.
|
|
|
|
### Docker Compose для микросервисной архитектуры:
|
|
|
|
```yaml
|
|
version: '3.8'
|
|
|
|
services:
|
|
# API Gateway
|
|
api-gateway:
|
|
build:
|
|
context: ./api-gateway
|
|
dockerfile: Dockerfile
|
|
ports:
|
|
- "8080:8080"
|
|
environment:
|
|
- SPRING_PROFILES_ACTIVE=docker
|
|
- EUREKA_CLIENT_SERVICE_URL_DEFAULTZONE=http://eureka:8761/eureka/
|
|
depends_on:
|
|
- eureka
|
|
- user-service
|
|
- order-service
|
|
- payment-service
|
|
networks:
|
|
- microservices-network
|
|
healthcheck:
|
|
test: ["CMD", "curl", "-f", "http://localhost:8080/actuator/health"]
|
|
interval: 30s
|
|
timeout: 10s
|
|
retries: 3
|
|
|
|
# Service Discovery
|
|
eureka:
|
|
image: steeltoeoss/eureka-server:latest
|
|
ports:
|
|
- "8761:8761"
|
|
environment:
|
|
- EUREKA_CLIENT_REGISTER_WITH_EUREKA=false
|
|
- EUREKA_CLIENT_FETCH_REGISTRY=false
|
|
networks:
|
|
- microservices-network
|
|
|
|
# User Service
|
|
user-service:
|
|
build:
|
|
context: ./user-service
|
|
dockerfile: Dockerfile
|
|
ports:
|
|
- "8081:8080"
|
|
environment:
|
|
- SPRING_PROFILES_ACTIVE=docker
|
|
- SPRING_DATASOURCE_URL=jdbc:postgresql://user-db:5432/userdb
|
|
- SPRING_DATASOURCE_USERNAME=user
|
|
- SPRING_DATASOURCE_PASSWORD=password
|
|
- EUREKA_CLIENT_SERVICE_URL_DEFAULTZONE=http://eureka:8761/eureka/
|
|
depends_on:
|
|
- user-db
|
|
- eureka
|
|
networks:
|
|
- microservices-network
|
|
healthcheck:
|
|
test: ["CMD", "curl", "-f", "http://localhost:8080/actuator/health"]
|
|
interval: 30s
|
|
timeout: 10s
|
|
retries: 3
|
|
|
|
# Databases
|
|
user-db:
|
|
image: postgres:15-alpine
|
|
environment:
|
|
- POSTGRES_DB=userdb
|
|
- POSTGRES_USER=user
|
|
- POSTGRES_PASSWORD=password
|
|
volumes:
|
|
- user_data:/var/lib/postgresql/data
|
|
- ./init-scripts/user-db-init.sql:/docker-entrypoint-initdb.d/init.sql
|
|
networks:
|
|
- microservices-network
|
|
healthcheck:
|
|
test: ["CMD-SHELL", "pg_isready -U user -d userdb"]
|
|
interval: 10s
|
|
timeout: 5s
|
|
retries: 5
|
|
|
|
# Message Queue
|
|
rabbitmq:
|
|
image: rabbitmq:3.11-management-alpine
|
|
ports:
|
|
- "5672:5672"
|
|
- "15672:15672"
|
|
environment:
|
|
- RABBITMQ_DEFAULT_USER=admin
|
|
- RABBITMQ_DEFAULT_PASS=admin
|
|
volumes:
|
|
- rabbitmq_data:/var/lib/rabbitmq
|
|
networks:
|
|
- microservices-network
|
|
healthcheck:
|
|
test: ["CMD", "rabbitmq-diagnostics", "ping"]
|
|
interval: 30s
|
|
timeout: 10s
|
|
retries: 3
|
|
|
|
# Monitoring
|
|
prometheus:
|
|
image: prom/prometheus:latest
|
|
ports:
|
|
- "9090:9090"
|
|
volumes:
|
|
- ./monitoring/prometheus.yml:/etc/prometheus/prometheus.yml
|
|
- prometheus_data:/prometheus
|
|
command:
|
|
- '--config.file=/etc/prometheus/prometheus.yml'
|
|
- '--storage.tsdb.path=/prometheus'
|
|
- '--web.console.libraries=/etc/prometheus/console_libraries'
|
|
- '--web.console.templates=/etc/prometheus/consoles'
|
|
- '--storage.tsdb.retention.time=200h'
|
|
- '--web.enable-lifecycle'
|
|
networks:
|
|
- microservices-network
|
|
|
|
grafana:
|
|
image: grafana/grafana:latest
|
|
ports:
|
|
- "3000:3000"
|
|
environment:
|
|
- GF_SECURITY_ADMIN_PASSWORD=admin
|
|
volumes:
|
|
- grafana_data:/var/lib/grafana
|
|
- ./monitoring/grafana/dashboards:/etc/grafana/provisioning/dashboards
|
|
- ./monitoring/grafana/datasources:/etc/grafana/provisioning/datasources
|
|
networks:
|
|
- microservices-network
|
|
|
|
volumes:
|
|
user_data:
|
|
rabbitmq_data:
|
|
prometheus_data:
|
|
grafana_data:
|
|
|
|
networks:
|
|
microservices-network:
|
|
driver: bridge
|
|
```
|
|
|
|
## Команды Docker
|
|
|
|
### Основные команды:
|
|
```bash
|
|
# Сборка образа
|
|
docker build -t myapp:latest .
|
|
|
|
# Запуск контейнера
|
|
docker run -p 3000:3000 myapp:latest
|
|
|
|
# Просмотр запущенных контейнеров
|
|
docker ps
|
|
|
|
# Просмотр всех контейнеров
|
|
docker ps -a
|
|
|
|
# Остановка контейнера
|
|
docker stop <container_id>
|
|
|
|
# Удаление контейнера
|
|
docker rm <container_id>
|
|
|
|
# Просмотр образов
|
|
docker images
|
|
|
|
# Удаление образа
|
|
docker rmi <image_id>
|
|
```
|
|
|
|
### Продвинутые команды:
|
|
```bash
|
|
# Запуск в фоновом режиме
|
|
docker run -d -p 3000:3000 myapp:latest
|
|
|
|
# Подключение к контейнеру
|
|
docker exec -it <container_id> /bin/bash
|
|
|
|
# Просмотр логов
|
|
docker logs <container_id>
|
|
|
|
# Мониторинг ресурсов
|
|
docker stats <container_id>
|
|
```
|
|
|
|
## Лучшие практики Docker
|
|
|
|
### 1. Оптимизация размера образа
|
|
```dockerfile
|
|
# Используйте многоэтапную сборку
|
|
FROM node:18-alpine AS builder
|
|
WORKDIR /app
|
|
COPY package*.json ./
|
|
RUN npm ci
|
|
COPY . .
|
|
RUN npm run build
|
|
|
|
FROM node:18-alpine AS production
|
|
WORKDIR /app
|
|
COPY package*.json ./
|
|
RUN npm ci --only=production
|
|
COPY --from=builder /app/dist ./dist
|
|
CMD ["npm", "start"]
|
|
```
|
|
|
|
### 2. Безопасность
|
|
```dockerfile
|
|
# Создайте пользователя без root прав
|
|
RUN addgroup -g 1001 -S nodejs
|
|
RUN adduser -S nextjs -u 1001
|
|
USER nextjs
|
|
```
|
|
|
|
### 3. Кэширование слоев
|
|
```dockerfile
|
|
# Копируйте package.json перед исходным кодом
|
|
COPY package*.json ./
|
|
RUN npm ci
|
|
COPY . .
|
|
```
|
|
|
|
### 4. Health Checks
|
|
```dockerfile
|
|
HEALTHCHECK --interval=30s --timeout=3s --start-period=5s --retries=3 \
|
|
CMD curl -f http://localhost:3000/health || exit 1
|
|
```
|