Ошибка 1: Неправильный порядок слоёв — каждый раз пересобирается pip install
Симптом:
docker build каждый раз устанавливает зависимости заново, даже если вы изменили только одну строку кода. Сборка занимает несколько минут вместо секунд.
# Dockerfile — НЕПРАВИЛЬНО
FROM python:3.12-slim
WORKDIR /app
COPY . . # копируем ВСЁ сразу
RUN pip install -r requirements.txt # кеш сбрасывается при любом изменении кода!
CMD ["python3", "app.py"]
# Dockerfile — ПРАВИЛЬНО
FROM python:3.12-slim
WORKDIR /app
COPY requirements.txt . # сначала только requirements
RUN pip install --no-cache-dir -r requirements.txt # кешируется!
COPY . . # потом код — меняется часто, слой лёгкий
CMD ["python3", "app.py"]
Почему: Docker кешируется до первого изменения. Если COPY . . раньше RUN pip install, то любое изменение в любом файле проекта сбрасывает кеш pip install.
Ошибка 2: Запуск БД без volume — потеря всех данных
Симптом: остановили или удалили контейнер с базой данных — все таблицы и записи исчезли.
# Терминал — НЕПРАВИЛЬНО
docker run -d --name mydb -e MYSQL_ROOT_PASSWORD=secret mysql:8.0
# Данные хранятся ВНУТРИ контейнера!
# docker rm mydb → все данные потеряны навсегда
# Терминал — ПРАВИЛЬНО
docker run -d \
--name mydb \
-e MYSQL_ROOT_PASSWORD=secret \
-v mysql-data:/var/lib/mysql \ # данные на хосте!
mysql:8.0
# docker rm mydb → данные в volume mysql-data, не теряются
# docker run ... -v mysql-data:/var/lib/mysql mysql:8.0 → данные восстановятся
Ошибка 3: Пароль в Dockerfile
Симптом: секретные данные (пароли, API-ключи) видны через
docker history myimage и docker inspect myimage. Если образ выгружен на Docker Hub — данные утекли.
# Dockerfile — ОПАСНО!
FROM postgres:16-alpine
ENV POSTGRES_PASSWORD=my-super-secret-password
# Теперь ЛЮБОЙ может узнать пароль:
# docker history myimage
# docker inspect myimage
# Dockerfile — ПРАВИЛЬНО: пустой Dockerfile
FROM postgres:16-alpine
EXPOSE 5432
# Паролей нет!
# Терминал — пароль передаём при запуске
docker run -d \
-e POSTGRES_PASSWORD=my-secret-pw \
postgres:16-alpine
# Ещё лучше: использовать .env файл с Docker Compose
# (не хранить пароль даже в истории терминала)
Ошибка 4: Путаница CMD и ENTRYPOINT
Симптом:
docker run myimage bash переопределяет CMD и приложение не запускается, или наоборот — ENTRYPOINT нельзя переопределить без специального флага.
# Dockerfile с CMD — команда при запуске переопределяется
FROM python:3.12-slim
WORKDIR /app
COPY . .
CMD ["python3", "app.py"]
# Результат:
# docker run myimage → python3 app.py (OK)
# docker run myimage bash → bash (CMD заменён — app.py НЕ запустится!)
# docker run myimage python3 other.py → python3 other.py
# Dockerfile с ENTRYPOINT — команда фиксирована
FROM python:3.12-slim
WORKDIR /app
COPY . .
ENTRYPOINT ["python3", "app.py"]
# Результат:
# docker run myimage → python3 app.py (OK)
# docker run myimage --port 8080 → python3 app.py --port 8080 (аргументы добавились!)
# docker run --entrypoint bash myimage → bash (только через --entrypoint)
Правило: используйте ENTRYPOINT, если контейнер — это «утилита» с фиксированной командой. Используйте CMD, если хотите разрешить переопределение команды при запуске.
Ошибка 5: «Cannot find Dockerfile» — неправильная директория или имя
Симптом:
docker build выдаёт ошибку "unable to prepare context: unable to evaluate symlinks in Dockerfile path: ... no such file or directory"
# Терминал — частые причины
# 1. Запуск из неправильной директории
cd C:\projects
docker build -t myapp . # ищет Dockerfile в C:\projects, а он в C:\projects\myapp!
# 2. Опечатка в имени — Dockerfile с маленькой буквы
# (на Linux регистр важен, Windows не чувствителен, но по стандарту — заглавная D)
docker build -t myapp . # ищет ./Dockerfile (заглавная D)
# Терминал — исправление
# 1. Перейти в нужную директорию
cd C:\projects\myapp
docker build -t myapp .
# 2. Или указать путь явно через -f
docker build -t myapp -f ./myapp/Dockerfile ./myapp
Ошибка 6: Большой контекст сборки из-за отсутствия .dockerignore
Симптом:
docker build запускается медленно — сообщение "Sending build context to Docker daemon X.XX MB" с большим числом. В образ попадают .git, node_modules, виртуальные окружения.
# Терминал — без .dockerignore
docker build -t myapp .
# Sending build context to Docker daemon 500MB ← плохо!
# .dockerignore — добавьте этот файл в корень проекта
.git
.gitignore
.env
.env.*
__pycache__
*.pyc
*.pyo
*.log
node_modules
.DS_Store
*.tar.gz
dist/
build/
.venv/
venv/
# Терминал — с .dockerignore
docker build -t myapp .
# Sending build context to Docker daemon 2.048kB ← хорошо!
Ошибка 7: chmod после COPY — не срабатывает из-за отдельного слоя
На практике это иногда встречается при сложных многопользовательских конфигурациях. Права, установленные в отдельном RUN после COPY, всё равно сохраняются в слое — это работает корректно в Docker. Проблема обычно возникает при Bind Mounts: права файлов на хосте могут перекрываться правами монтирования.
# Dockerfile — ПРАВИЛЬНО: chmod в том же RUN что и остальные операции с файлом
COPY scripts/ /usr/local/bin/
RUN chmod +x /usr/local/bin/*.sh