Образы, слои и контейнеры
Почему образ пересобирается за секунду и куда исчезают данные.
Образ и контейнер
Образ — неизменяемый набор слоёв файловой системы плюс метаданные о том, что запускать. Контейнер — процесс, запущенный из образа, поверх которого добавлен записываемый слой.
Из одного образа запускается сколько угодно контейнеров, и у каждого свой пустой записываемый слой. Всё, что контейнер туда напишет, исчезает вместе с ним.
docker run --rm alpine sh -c 'echo hi > /tmp/file; cat /tmp/file'
docker run --rm alpine cat /tmp/file # No such file
Именно поэтому данные выносят в volume — иначе база данных теряет всё при первом же перезапуске.
Слои
Каждая инструкция Dockerfile создаёт слой. Слои кешируются и переиспользуются между сборками и образами.
FROM node:20-alpine
WORKDIR /app
COPY package*.json ./
RUN npm ci
COPY . .
CMD ["node", "server.js"]
Порядок здесь не случаен. package.json копируется до остального кода, поэтому слой с npm ci переиспользуется, пока зависимости не изменились. Поменяйте местами — и каждая правка в коде будет заново скачивать все зависимости.
Слои только добавляются
Ключевое свойство: удаление файла в следующем слое не освобождает место. Файл остаётся в предыдущем слое, просто становится не виден.
RUN apt-get update && apt-get install -y curl
RUN rm -rf /var/lib/apt/lists/* # образ не уменьшится
Правильно — в одной инструкции:
RUN apt-get update \
&& apt-get install -y --no-install-recommends curl \
&& rm -rf /var/lib/apt/lists/*
Многостадийная сборка
Самый действенный способ уменьшить образ. Компилятор и зависимости для сборки нужны при сборке, но не в рантайме:
FROM golang:1.22 AS build
WORKDIR /src
COPY . .
RUN go build -o /app ./cmd/server
FROM gcr.io/distroless/static
COPY --from=build /app /app
ENTRYPOINT ["/app"]
В финальный образ попадает один бинарник. Разница обычно в десятки раз: сотни мегабайт против единиц.
Посмотреть, из чего состоит образ
docker history --no-trunc myimage
docker image inspect myimage
history показывает размер каждого слоя — самый быстрый способ понять, что именно раздуло образ.