Главная / 🐳 DevOps & Docker

🐳 DevOps & Docker

Как Claude Code работает с Docker-контейнерами, WSL2, Caddy reverse proxy и инфраструктурой. Правила безопасности, MCP-инструменты и конфигурация для Windows Server 2025.

🔌 Docker через MCP (не через Bash)

На Windows с WSL2 прямые docker команды из Claude Code часто не работают из-за PATH. Кроме того, Bash hook в настройках блокирует их явно. Правило: всегда использовать mcp__docker__* инструменты.

💡
Почему MCP, а не Bash? MCP docker-инструменты используют Docker SDK напрямую, минуя shell. Это безопаснее, предсказуемее и не зависит от PATH. Bash hook (bash-mcp-guard.cjs) перехватит любой docker exec и предложит альтернативу.
❌ НЕТ Bash команды
docker exec -it backend-1 php artisan route:list docker logs -f backend-1 docker compose ps
✅ ДА MCP инструменты
mcp__docker__docker_exec container: "backend-1" command: "php artisan route:list" mcp__docker__docker_container_logs container: "backend-1" mcp__docker__docker_compose_ps path: "E:/Clients/project"

Полный справочник Docker MCP инструментов

MCP инструментАналог docker командыКогда использовать
docker_execdocker exec -itЗапуск команд внутри контейнера
docker_container_logsdocker logsПросмотр логов контейнера
docker_list_containersdocker ps -aСписок всех контейнеров
docker_inspect_containerdocker inspectДетальная информация о контейнере
docker_container_statsdocker statsCPU/RAM использование
docker_start_containerdocker startЗапустить остановленный контейнер
docker_stop_containerdocker stopОстановить контейнер
docker_restart_containerdocker restartПерезапустить контейнер
docker_compose_psdocker compose psСтатус compose-стека
docker_compose_logsdocker compose logsЛоги всего стека
docker_compose_updocker compose up -dЗапуск стека
docker_compose_downdocker compose downОстановка стека
docker_compose_restartdocker compose restartПерезапуск сервиса в стеке
docker_list_imagesdocker imagesСписок образов
docker_create_networkdocker network createСоздать сеть
docker_list_networksdocker network lsСписок сетей

⚙️ Подключение Docker MCP

Docker MCP добавляется в глобальный settings.local.json (не в per-project .mcp.json, т.к. нужен везде):

// ~/.claude/settings.local.json { "mcpServers": { "docker": { "command": "npx", "args": ["-y", "docker-mcp@latest"] }, "ruflo": { "command": "npx", "args": ["-y", "ruflo@latest"] } } }
⚠️
Требуется Docker Desktop — должен быть запущен с WSL2 backend. MCP подключается через Docker socket. Если получаешь ошибку connection refused — проверь статус Docker Desktop.

🖥️ WSL2 — настройка памяти

На Windows Server 2025 с 47 GB RAM конфигурация WSL2 критична для Docker. OOM убивал PostgreSQL при ETL-операциях — решение зафиксировано.

# C:\Users\Администратор\.wslconfig # Применить: wsl --shutdown (потом перезапустить Docker Desktop) [wsl2] memory=38GB # 80% от 47GB — Windows-хосту остаётся 9GB swap=2GB # Большой swap маскирует OOM и замедляет работу localhostForwarding=true [experimental] hostAddressLoopback=true # Контейнеры видят host.docker.internal
Правило памяти: WSL2 = 80% RAM. Swap = минимальный (2GB). Большой swap создаёт иллюзию достаточности памяти, но приводит к деградации производительности.

🌐 Caddy Reverse Proxy

Все публичные домены проксируются через Caddy. Caddy — единственный сервис, занимающий порты 80/443. Никакой другой контейнер не биндится на эти порты.

Расположение и управление

# Папка прокси E:\Clients\Windows\proxy\ # CLI управление (PowerShell) proxy.cmd list # Текущие маршруты + TLS даты proxy.cmd add site.ru container-name:80 # Добавить домен proxy.cmd connect my-network # Подключить Caddy к сети сайта proxy.cmd backup # Архив + сертификаты LE

Текущая маршрутизация

ДоменUpstream
phone.rosveb.ruphone-rosveb-ru-frontend-1:3000
/api/* → phone-rosveb-ru-backend-1:8000
massage.rosveb.ruproject-nginx-1:80
dev.gulaev.rugulaev-nginx:80
notal.rosveb.runotal-nginx:80
gis.rosveb.rucatalog_nginx:80

Добавление нового сайта — чек-лист

# 1. Подключить Caddy к сети сайта proxy connect <имя-docker-сети> # 2. Добавить маршрутизацию proxy add new-site.example.ru container-name:80 # 3. Адаптация приложения под reverse proxy: # Laravel — в AppServiceProvider или bootstrap/app.php: URL::forceScheme(request()->isSecure() ? 'https' : 'http'); # + TrustProxies middleware с указанием Caddy IP # Next.js / Nuxt: NEXT_PUBLIC_SITE_URL=https://new-site.example.ru # FastAPI: uvicorn main:app --proxy-headers --forwarded-allow-ips='*'
🚫
НЕ публиковать порты 80/443 в docker-compose.yml для своих сервисов — они заняты Caddy. Dev-доступ — только через свободные порты из PORTS.md (например :8011).

📋 Docker Compose — лучшие практики

Шаблон compose для Laravel-проекта

# docker-compose.yml services: backend: build: . container_name: my-project-backend-1 networks: - internal - proxy # Caddy видит этот контейнер environment: - APP_ENV=production depends_on: db: condition: service_healthy db: image: postgres:16 container_name: my-project-db-1 volumes: - pg_data:/var/lib/postgresql/data networks: - internal # ТОЛЬКО внутренняя сеть, не proxy! healthcheck: test: ["CMD-SHELL", "pg_isready -U postgres"] interval: 10s timeout: 5s retries: 5 networks: internal: proxy: external: true # Создана через proxy connect volumes: pg_data:
💡
Именование контейнеров: используй паттерн <проект>-<сервис>-1. Это совпадает с автоматическим именованием Compose и важно для Caddy, который обращается по имени через embedded DNS.

⚡ Выполнение команд внутри контейнеров

Laravel Artisan через Docker MCP

// Вместо: docker exec -it backend-1 php artisan migrate // Использовать MCP инструмент: mcp__docker__docker_exec({ container: "phone-rosveb-ru-backend-1", command: "php artisan migrate --force" }) // Очередь (queue worker) — проверить статус: mcp__docker__docker_exec({ container: "phone-rosveb-ru-backend-1", command: "php artisan queue:work --once" })
⚠️
laravel-boost MCP предоставляет специализированные инструменты для Laravel: роуты, модели, события — напрямую через MCP без docker exec. Предпочитать его для Laravel-специфичных операций.

Python / FastAPI команды

mcp__docker__docker_exec({ container: "python-etl-app-1", command: "alembic upgrade head" // Миграции }) mcp__docker__docker_exec({ container: "python-etl-app-1", command: "python -m pytest tests/ -v" // Тесты })

❤️ Health Checks и мониторинг

// Проверить здоровье всех контейнеров: mcp__docker__docker_container_health_check({ container: "backend-1" }) // CPU/RAM статистика: mcp__docker__docker_container_stats({ container: "backend-1" }) // Inspect — сети, порты, env (без secrets): mcp__docker__docker_inspect_container({ container: "backend-1" })

Признаки OOM и решение

СимптомДиагнозРешение
Контейнер перезапускается самOOM killerУменьшить shared_buffers в PG, увеличить WSL2 memory
Exit code 137SIGKILL от OOMСнизить max_parallel_workers в PG
Медленные запросы при ETLSwap активенСнизить work_mem, добавить батчинг
PG не стартуетshared_buffers > 25% WSL2ALTER SYSTEM SET shared_buffers = '4GB'

🔒 Безопасность контейнеров

# Никогда не делать в docker-compose: ports: - "5432:5432" # PostgreSQL напрямую в интернет! - "6379:6379" # Redis без аутентификации! # Правильно — только внутренние сети: networks: - internal # Только для межсервисного общения # БД не имеет секции ports вообще
🚫
critical-files-guard.cjs блокирует изменение docker-compose.production.yml. Для редактирования — установить переменную CONFIRM_CRITICAL=yes или изменить вручную.