package devopsmodules import ( "fmt" "rubric/utils" ) var DockerModule = Module{ Key: "docker", Aliases: []string{"d", "container", "podman"}, Title: "Docker и контейнеры", Description: "Образы, контейнеры, Dockerfile, Compose, сети, тома, Podman", Run: showDocker, } func showDocker() { utils.Header("DevOps — Docker и контейнеры") utils.Section("Основные понятия") utils.Code(`Image (образ) — неизменяемый шаблон (слои файловой системы) Container — запущенный экземпляр образа (изолированный процесс) Dockerfile — инструкции для сборки образа Registry — хранилище образов (Docker Hub, GHCR, ECR, Harbor) Volume — постоянное хранилище данных вне контейнера Network — виртуальная сеть между контейнерами Изоляция через технологии ядра Linux: - namespaces (PID, net, mnt, uts, ipc, user) - cgroups (ограничение ресурсов) - Union FS (слоистая файловая система)`) utils.Section("Управление образами") utils.Command("docker images", "список образов") utils.Command("docker pull nginx:1.25", "скачать образ") utils.Command("docker pull nginx:latest", "последняя версия") utils.Command("docker push myrepo/myapp:1.0", "отправить в реестр") utils.Command("docker build -t myapp:1.0 .", "собрать образ из Dockerfile") utils.Command("docker build -t myapp:1.0 -f Dockerfile.prod .", "из другого Dockerfile") utils.Command("docker rmi nginx:latest", "удалить образ") utils.Command("docker image prune", "удалить неиспользуемые образы") utils.Command("docker inspect nginx", "подробная информация об образе") utils.Command("docker history nginx", "слои образа") utils.Command("docker save myapp:1.0 | gzip > myapp.tar.gz", "экспорт образа") utils.Command("docker load < myapp.tar.gz", "импорт образа") utils.Section("Управление контейнерами") utils.Command("docker run nginx", "запустить контейнер") utils.Command("docker run -d nginx", "в фоне (detached)") utils.Command("docker run -d -p 8080:80 --name web nginx", "с портом и именем") utils.Command("docker run -it ubuntu bash", "интерактивно с терминалом") utils.Command("docker run --rm alpine echo 'hello'", "удалить после остановки") fmt.Println() utils.Code(`# Часто используемые флаги run: -d — фоновый режим -p 8080:80 — проброс порта (host:container) -P — автоматический проброс всех портов --name web — имя контейнера -e KEY=value — переменная окружения --env-file .env — переменные из файла -v /host:/cont — монтирование тома --network mynet — подключить к сети --restart=always — автоперезапуск --rm — удалить контейнер после остановки --memory=512m — ограничение RAM --cpus=0.5 — ограничение CPU -u 1000:1000 — пользователь`) utils.Println(utils.ColorBold + "Жизненный цикл контейнера:" + utils.ColorReset) utils.Command("docker ps", "запущенные контейнеры") utils.Command("docker ps -a", "все контейнеры включая остановленные") utils.Command("docker stop web", "остановить (SIGTERM)") utils.Command("docker kill web", "принудительно (SIGKILL)") utils.Command("docker start web", "запустить остановленный") utils.Command("docker restart web", "перезапустить") utils.Command("docker rm web", "удалить остановленный") utils.Command("docker rm -f web", "удалить принудительно") utils.Command("docker container prune", "удалить все остановленные") fmt.Println() utils.Println(utils.ColorBold + "Взаимодействие с контейнером:" + utils.ColorReset) utils.Command("docker exec -it web bash", "открыть shell в запущенном") utils.Command("docker exec web ls /etc/nginx", "выполнить команду") utils.Command("docker logs web", "логи контейнера") utils.Command("docker logs -f web", "следить за логами") utils.Command("docker logs --tail 100 web", "последние 100 строк") utils.Command("docker cp web:/etc/nginx/nginx.conf .", "скопировать файл из контейнера") utils.Command("docker cp nginx.conf web:/etc/nginx/", "скопировать в контейнер") utils.Command("docker stats", "использование ресурсов") utils.Command("docker top web", "процессы в контейнере") utils.Section("Dockerfile") utils.Code(`# Dockerfile — инструкции сборки образа: FROM ubuntu:22.04 # базовый образ LABEL maintainer="alice@example.com" # метаданные # Установка зависимостей: RUN apt-get update && \ apt-get install -y python3 python3-pip && \ rm -rf /var/lib/apt/lists/* # очищаем кэш в том же слое WORKDIR /app # рабочая директория COPY requirements.txt . # копировать файлы RUN pip install -r requirements.txt # установить зависимости COPY . . # копировать код ENV APP_ENV=production # переменные окружения EXPOSE 8000 # документировать порт VOLUME ["/app/data"] # объявить том USER 1000:1000 # непривилегированный пользователь CMD ["python3", "-m", "uvicorn", "main:app", "--host", "0.0.0.0"]`) utils.Code(`# Многоэтапная сборка (multi-stage) — уменьшает итоговый размер: FROM golang:1.22 AS builder WORKDIR /build COPY go.mod go.sum ./ RUN go mod download COPY . . RUN CGO_ENABLED=0 go build -o app . FROM alpine:3.19 RUN apk add --no-cache ca-certificates WORKDIR /app COPY --from=builder /build/app . USER 65534:65534 CMD ["./app"]`) utils.Note("COPY requirements.txt и pip install ПЕРЕД COPY . — слои кэшируются, сборка быстрее.") utils.Note("Всегда указывай конкретный тег образа (не latest) для воспроизводимости.") utils.Section("Тома (Volumes)") utils.Code(`Типы хранилища: Volume — управляется Docker (/var/lib/docker/volumes/) Bind mount — директория хоста, монтируется в контейнер tmpfs — только в памяти (временное) # Named volume: docker volume create mydata docker run -v mydata:/app/data nginx docker volume ls docker volume inspect mydata docker volume rm mydata docker volume prune # Bind mount: docker run -v /host/path:/container/path nginx docker run -v $(pwd):/app nginx # текущая директория # tmpfs: docker run --tmpfs /tmp nginx`) utils.Section("Сети (Networks)") utils.Code(`Типы сетей: bridge — виртуальная сеть по умолчанию (контейнеры изолированы от хоста) host — контейнер использует сеть хоста напрямую none — без сети overlay — между несколькими хостами (Docker Swarm) docker network ls docker network create mynet docker network create --subnet=172.20.0.0/16 mynet docker run --network mynet --name db postgres docker run --network mynet --name app myapp # app может обращаться к db по имени! docker network connect mynet container1 docker network disconnect mynet container1 docker network inspect mynet docker network rm mynet`) utils.Section("Docker Compose") utils.Code(`# docker-compose.yml — многоконтейнерное приложение: version: '3.9' services: web: build: . ports: - "8080:8000" environment: - DATABASE_URL=postgresql://user:pass@db:5432/mydb volumes: - ./:/app depends_on: db: condition: service_healthy restart: unless-stopped db: image: postgres:16 environment: POSTGRES_USER: user POSTGRES_PASSWORD: pass POSTGRES_DB: mydb volumes: - pgdata:/var/lib/postgresql/data healthcheck: test: ["CMD-SHELL", "pg_isready -U user"] interval: 5s timeout: 5s retries: 5 redis: image: redis:7-alpine command: redis-server --appendonly yes volumes: - redisdata:/data volumes: pgdata: redisdata: networks: default: name: myapp-network`) utils.Println(utils.ColorBold + "Команды Compose:" + utils.ColorReset) utils.Command("docker compose up -d", "запустить все сервисы в фоне") utils.Command("docker compose up -d --build", "пересобрать образы") utils.Command("docker compose down", "остановить и удалить контейнеры") utils.Command("docker compose down -v", "удалить и тома") utils.Command("docker compose ps", "статус сервисов") utils.Command("docker compose logs -f web", "логи сервиса") utils.Command("docker compose exec web bash", "shell в сервисе") utils.Command("docker compose restart web", "перезапустить сервис") utils.Command("docker compose scale web=3", "масштабировать сервис") utils.Section("Podman — альтернатива без демона") utils.Code(`Podman — daemonless, rootless, совместим с Docker CLI. Используется в RHEL вместо Docker. # Команды идентичны Docker: podman run -d -p 8080:80 nginx podman build -t myapp . podman ps podman images # Rootless-контейнеры (без root): podman run --user 1000 nginx # Podman Compose: podman-compose up -d # Генерация systemd-юнита для контейнера: podman generate systemd --name mycontainer > /etc/systemd/system/mycontainer.service # Podman Pod (группа контейнеров с общей сетью): podman pod create --name mypod -p 8080:80 podman run -d --pod mypod nginx podman pod ps`) utils.Footer() }