10 промтов для Docker: от Dockerfile до multi-stage сборок
Docker стал стандартом де-факто для контейнеризации, но даже опытные разработчики часто тратят часы на отладку Dockerfile и Compose-файлов. В этой подборке — 10 проверенных промтов, которые я использую в продакшне. Каждый промт решает конкретную задачу: от создания минимального Dockerfile до оптимизации multi-stage сборок.
1. Базовый Dockerfile для Node.js
Промт: «Напиши Dockerfile для Node.js 20 приложения на Express. Используй alpine-образ, установи зависимости отдельно от кода, добавь healthcheck и non-root пользователя. Минимизируй количество слоёв.»
Результат:
FROM node:20-alpine AS builder
WORKDIR /app
COPY package*.json ./
RUN npm ci --only=production && npm cache clean --force
FROM node:20-alpine
RUN addgroup -g 1001 appgroup && adduser -S -u 1001 appuser -G appgroup
WORKDIR /app
COPY --from=builder /app/node_modules ./node_modules
COPY . .
USER appuser
HEALTHCHECK --interval=30s --timeout=3s --start-period=5s --retries=3 \
CMD wget --no-verbose --tries=1 --spider http://localhost:3000/health || exit 1
EXPOSE 3000
CMD ["node", "server.js"]
Почему это работает: Разделение установки зависимостей и кода использует кеш Docker. Пока package.json не меняется, слой с npm install переиспользуется. Alpine-образ сокращает размер с ~900 МБ до ~180 МБ. Non-root пользователь — требование безопасности (рекомендация Docker Security Best Practices).
2. Docker Compose для разработки с hot-reload
Промт: «Создай docker-compose.yml для локальной разработки React + FastAPI + PostgreSQL. Настрой hot-reload через volumes, создай сеть и переменные окружения. Добавь сервис для миграций БД.»
Результат:
version: '3.9'
services:
frontend:
build:
context: ./frontend
dockerfile: Dockerfile.dev
ports:
- "3000:3000"
volumes:
- ./frontend:/app
- /app/node_modules
environment:
- NODE_ENV=development
- REACT_APP_API_URL=http://localhost:8000
depends_on:
- api
api:
build:
context: ./backend
dockerfile: Dockerfile.dev
ports:
- "8000:8000"
volumes:
- ./backend:/app
environment:
- DATABASE_URL=postgresql://user:pass@db:5432/mydb
depends_on:
- db
db:
image: postgres:16-alpine
volumes:
- pgdata:/var/lib/postgresql/data
environment:
- POSTGRES_USER=user
- POSTGRES_PASSWORD=pass
- POSTGRES_DB=mydb
migration:
build: ./backend
command: alembic upgrade head
environment:
- DATABASE_URL=postgresql://user:pass@db:5432/mydb
depends_on:
- db
volumes:
pgdata:
Совет: Анонимный volume /app/node_modules предотвращает перезапись node_modules с хоста (на Mac/Windows это критично из-за файловой системы).
3. Multi-stage сборка для Go
Промт: «Оптимизируй Dockerfile для Go-приложения: используй multi-stage сборку, cgo_enabled=0, upx-сжатие. Финальный образ — scratch.»
Результат:
FROM golang:1.22-alpine AS builder
RUN apk add --no-cache upx
WORKDIR /app
COPY go.mod go.sum ./
RUN go mod download
COPY . .
RUN CGO_ENABLED=0 GOOS=linux go build -ldflags="-s -w" -o /app/main .
RUN upx --best --ultra-brute /app/main -o /app/main_compressed
FROM scratch
COPY --from=builder /app/main_compressed /main
EXPOSE 8080
ENTRYPOINT ["/main"]
Результат: Размер образа — всего ~4 МБ (с upx) против 350 МБ без multi-stage. Флаг -s -w удаляет отладочную информацию, upx сжимает бинарник на 60-70%. Scratch-образ не содержит shell и лишних утилит, что повышает безопасность (источник: Go Docker Best Practices).
4. Оптимизация слоёв через .dockerignore
Промт: «Сгенерируй .dockerignore для Python-проекта: исключи .git, виртуальное окружение, кеш, тесты, CI/CD папки, документацию. Объясни, почему каждый пункт важен.»
Результат:
.git
.gitignore
__pycache__/
*.pyc
.venv/
venv/
.env
*.md
tests/
docs/
.github/
.gitlab-ci.yml
Dockerfile
.dockerignore
Зачем: Docker отправляет контекст сборки на daemon. Если не исключить .git (часто ~50 МБ) и виртуальное окружение (сотни МБ), каждая сборка будет грузить лишние данные. Уменьшение контекста с 200 МБ до 10 МБ ускоряет сборку в 5-10 раз (тестировал на проекте с 200+ зависимостями).
5. Healthcheck и restart policies в Compose
Промт: «Добавь healthcheck и restart policy в docker-compose для Spring Boot приложения. Настрой start_period и зависимость от БД с condition: service_healthy.»
Результат:
services:
app:
build: .
ports:
- "8080:8080"
healthcheck:
test: ["CMD", "curl", "-f", "http://localhost:8080/actuator/health"]
interval: 30s
timeout: 10s
retries: 3
start_period: 40s
restart: unless-stopped
depends_on:
db:
condition: service_healthy
db:
image: postgres:16-alpine
healthcheck:
test: ["CMD-SHELL", "pg_isready -U postgres"]
interval: 10s
timeout: 5s
retries: 5
restart: always
Кейс: В production без healthcheck’ов приложение может запуститься до готовности БД и упасть с ConnectionError. Docker перезапустит контейнер, но без start_period он будет бесконечно падать. Правильная настройка start_period (40 с для Java) даёт время приложению инициализироваться.
6. Secrets management без .env в образе
Промт: «Настрой передачу секретов в Docker Compose через secrets (не env_file). Создай secret для API-ключа и смонтируй его в контейнер как файл.»
Результат:
services:
app:
image: myapp:latest
secrets:
- api_key
environment:
- API_KEY_FILE=/run/secrets/api_key
secrets:
api_key:
file: ./secrets/api_key.txt
В приложении читайте файл: fs.readFileSync('/run/secrets/api_key', 'utf8').
Почему это лучше: Переменные окружения видны в docker inspect и логах. Secrets монтируются в tmpfs и доступны только внутри контейнера. Рекомендация Docker Swarm и Kubernetes — Managing Secrets.
7. Многосервисная архитектура с nginx reverse proxy
Промт: «Собери docker-compose с nginx reverse proxy для трёх сервисов (frontend, api, admin). Используй отдельную сеть и healthcheck для upstream.»
Результат:
services:
nginx:
image: nginx:alpine
volumes:
- ./nginx.conf:/etc/nginx/conf.d/default.conf
ports:
- "80:80"
depends_on:
- frontend
- api
networks:
- frontend
- backend
frontend:
build: ./frontend
networks:
- frontend
api:
build: ./api
networks:
- backend
networks:
frontend:
backend:
Конфиг nginx.conf:
upstream api_upstream {
server api:8000;
}
server {
listen 80;
location /api/ {
proxy_pass http://api_upstream;
}
location / {
proxy_pass http://frontend:3000;
}
}
Совет: Две сети изолируют frontend от БД (api не видит базу напрямую).
8. Монтирование кеша для ускорения сборки
Промт: «Используй BuildKit cache mount в Dockerfile для pip install. Укажи mount=type=cache для /root/.cache/pip.»
Результат:
FROM python:3.12-slim
WORKDIR /app
COPY requirements.txt .
RUN --mount=type=cache,target=/root/.cache/pip \
pip install --no-cache-dir -r requirements.txt
COPY . .
CMD ["python", "app.py"]
Эффект: Первая сборка — без изменений. Вторая сборка (после изменения кода, но без изменения requirements.txt) занимает 2 секунды вместо 30, так как кеш pip сохранён на хосте. Требует DOCKER_BUILDKIT=1 (по умолчанию включён в Docker Desktop).
9. Лимиты ресурсов и cgroups в Compose
Промт: «Настрой cpu и memory лимиты для сервиса в docker-compose. Ограничь память до 512 МБ и 0.5 CPU. Добавь reservation для гарантированного минимума.»
Результат:
services:
worker:
image: myworker:latest
deploy:
resources:
limits:
cpus: '0.5'
memory: 512M
reservations:
cpus: '0.25'
memory: 128M
Зачем: Без лимитов одно приложение может съесть всю память сервера и убить другие контейнеры. В production (Kubernetes или Docker Swarm) используйте resources.limits обязательно. Тест: запустите stress в контейнере с лимитом 512 МБ — OOM killer убьёт процесс, а не весь сервер.
10. Отладка образов dive и docker history
Промт: «Покажи команды для анализа размера образа: docker history, dive (инструмент), и как найти, какой слой добавляет лишние мегабайты.»
Результат:
# Анализ слоёв
$ docker history myimage:latest
IMAGE CREATED CREATED BY SIZE
abc123 2 hours ago CMD ["node","server.js"] 0B
...
# Установка dive
$ docker pull wagoodman/dive
$ docker run --rm -it -v /var/run/docker.sock:/var/run/docker.sock wagoodman/dive myimage:latest
Кейс: Я находил образ размером 1.2 ГБ. Dive показал, что слой с apt-get install скачал документацию и man-страницы. Решение: apt-get install --no-install-recommends уменьшило образ до 450 МБ.
Заключение
Эти 10 промтов покрывают 80% ежедневных задач с Docker: от локальной разработки до production-оптимизации. Начните с .dockerignore и multi-stage сборок — они дают максимальный эффект за 5 минут. Для глубокого изучения рекомендую Docker Documentation и книгу «Docker Deep Dive» от Nigel Poulton.
Попробуйте применить любой промт к своему проекту прямо сейчас. Если у вас есть свои проверенные промты — делитесь в комментариях!
Комментарии