Образы, слои и контейнеры

Почему образ пересобирается за секунду и куда исчезают данные.

Образ и контейнер

Образ — неизменяемый набор слоёв файловой системы плюс метаданные о том, что запускать. Контейнер — процесс, запущенный из образа, поверх которого добавлен записываемый слой.

Из одного образа запускается сколько угодно контейнеров, и у каждого свой пустой записываемый слой. Всё, что контейнер туда напишет, исчезает вместе с ним.

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 показывает размер каждого слоя — самый быстрый способ понять, что именно раздуло образ.