Чем образ отличается от контейнера? Как устроены слои Docker?
Образ (image) — неизменяемый шаблон: файловая система приложения и метаданные (команда запуска, переменные, порты). Контейнер — запущенный экземпляр образа с собственным тонким слоем для записи. Аналогия: образ — класс, контейнер — объект.
Слои. Каждая инструкция Dockerfile, меняющая файловую систему (RUN, COPY, ADD), создаёт слой. Слои неизменяемы, кешируются и переиспользуются между образами. Контейнер добавляет сверху слой для записи; при удалении контейнера он пропадает.
Как это влияет на Dockerfile:
FROM node:24-slim
WORKDIR /app
COPY package*.json ./ # сначала только зависимости
RUN npm ci --omit=dev # слой кешируется, пока зависимости не менялись
COPY . . # код меняется часто — копируем последним
USER node # не запускаем от root
CMD ["node", "server.js"]Если скопировать весь код до установки зависимостей, любое изменение кода будет сбрасывать кеш и переустанавливать пакеты.
Ещё практики: минимальный базовый образ (slim, alpine, distroless), многоступенчатая сборка — компилятор в первой стадии, в финальный образ только артефакт; .dockerignore; никаких секретов в образе — они остаются в слоях навсегда, даже если удалить файл следующей инструкцией.
Контейнер не виртуальная машина: он использует ядро хоста и изолируется механизмами ядра Linux — namespaces (что процесс видит) и cgroups (сколько ресурсов может потребить).
- Что такое namespaces и cgroups?
- Чем CMD отличается от ENTRYPOINT?