🐛 Типичные ошибки: Multistage и Docker Compose
⚡ Топ-5 ошибок
- Не именовать стадию (без
AS name) → нельзя использоватьCOPY --from= - depends_on без healthcheck → приложение стартует раньше, чем БД готова принимать подключения
- Ключ
version:в compose-файле → предупреждения, потенциальный конфликт с валидатором - Секреты в environment: в compose-файле → попадают в git-историю; правильно — через
.envфайл - Забыть
--buildприdocker compose up→ запускается старый образ после изменения кода
Ошибка 1: Не именовать стадию в Multistage
Неправильно
# Dockerfile
FROM python:3.12-slim
# Стадия без имени AS
WORKDIR /app
COPY requirements.txt .
RUN pip install --user -r requirements.txt
FROM python:3.12-slim
WORKDIR /app
# Ошибка: нет имени стадии для --from
COPY --from=??? /root/.local /root/.local
Правильно
# Dockerfile
FROM python:3.12-slim AS builder
# Стадия с именем AS builder
WORKDIR /app
COPY requirements.txt .
RUN pip install --user -r requirements.txt
FROM python:3.12-slim
WORKDIR /app
# Ссылаемся по имени
COPY --from=builder /root/.local /root/.local
Симптом: ошибка сборки
invalid --from flag value.
Ошибка 2: depends_on без healthcheck
Неправильно
# docker-compose.yml
services:
app:
build: .
depends_on:
- db # ждёт только START контейнера
db:
image: mysql:8.0
environment:
MYSQL_ROOT_PASSWORD: secret
Правильно
# docker-compose.yml
services:
app:
build: .
depends_on:
db:
condition: service_healthy
db:
image: mysql:8.0
environment:
MYSQL_ROOT_PASSWORD: secret
healthcheck:
test: ["CMD", "mysqladmin", "ping",
"-h", "localhost"]
interval: 10s
timeout: 5s
retries: 5
Симптом: приложение падает с ошибкой подключения к БД через несколько секунд после старта, затем перезапускается и работает. Нестабильный старт.
Ошибка 3: Секреты напрямую в docker-compose.yml
Неправильно
# docker-compose.yml ← НЕ делать так
services:
db:
image: postgres:16
environment:
POSTGRES_PASSWORD: my_super_secret
POSTGRES_USER: admin
Этот файл попадает в git-репозиторий — секрет становится публичным.
Правильно
# .env ← добавить в .gitignore!
POSTGRES_PASSWORD=my_super_secret
POSTGRES_USER=admin
# docker-compose.yml
services:
db:
image: postgres:16
env_file:
- .env
# или через ${VAR} из .env:
environment:
POSTGRES_PASSWORD: ${POSTGRES_PASSWORD}
POSTGRES_USER: ${POSTGRES_USER}
Правило: всегда добавляйте
.env в .gitignore. Коммитьте только .env.example с placeholder-значениями.
Ошибка 4: Запуск без --build после изменения кода
Неправильно
# терминал
# Изменили app.py...
docker compose up -d
# Запускается СТАРЫЙ образ!
# Изменения не применились.
Правильно
# терминал
# После изменения кода — пересобрать:
docker compose up --build -d
# Или явно пересобрать:
docker compose build
docker compose up -d
Симптом: «я изменил код, но в контейнере ничего не поменялось». Docker кеширует образ и не пересобирает его автоматически при
up.
Ошибка 5: Неправильный PATH после --user установки pip
Неправильно
# Dockerfile
FROM python:3.12-slim AS builder
RUN pip install --user -r requirements.txt
COPY app.py .
FROM python:3.12-slim
COPY --from=builder /root/.local /root/.local
COPY --from=builder /app/app.py .
# Забыли добавить /root/.local/bin в PATH!
CMD ["flask", "run"] # Command not found!
Правильно
# Dockerfile
FROM python:3.12-slim AS builder
WORKDIR /app
RUN pip install --user -r requirements.txt
COPY app.py .
FROM python:3.12-slim
WORKDIR /app
COPY --from=builder /root/.local /root/.local
COPY --from=builder /app/app.py .
# Добавляем ~/.local/bin в PATH
ENV PATH=/root/.local/bin:$PATH
CMD ["python", "app.py"]
Симптом:
/bin/sh: flask: command not found или python: can't open file 'app.py' при старте контейнера.
Ошибка 6: Потеря данных БД при docker compose down -v
Опасная команда
# терминал
# ОСТОРОЖНО: -v удаляет тома с данными!
docker compose down -v
# Все данные MySQL/PostgreSQL УДАЛЕНЫ
Безопасная остановка
# терминал
# Остановить без удаления томов (данные сохраняются)
docker compose down
# Остановить только контейнеры, тома не трогать
docker compose stop
Правило: флаг
-v при docker compose down удаляет все именованные тома. Используйте только для полной очистки тестовой среды.