Docker image layers

Docker/OCI image — стек tar.gz слоёв. Overlayfs объединяет их в единый rootfs. Каждая инструкция Dockerfile создаёт новый слой. Кеш работает на уровне слоёв.

Что создаёт слой

Что НЕ создаёт

ENV, WORKDIR, USER, EXPOSE, LABEL, ARG, CMD, ENTRYPOINT — только в config, не в слой.

Overlayfs

lowerdir=layer1:layer2:layer3    # read-only
upperdir=container-writable      # изменения контейнера
merged=/                         # то что видит процесс

Удаление файла в контейнере? Overlayfs создаёт whiteout в upperdir. Файл существует ниже, но "не виден".

Порядок в Dockerfile

# ПЛОХО — код меняется часто, deps пере-инсталлится
COPY . /app
RUN cd /app && npm install

# ХОРОШО — deps кешируются, код отдельно
COPY package.json package-lock.json /app/
RUN cd /app && npm install
COPY . /app

Уменьшение размера

1. Объединяй RUN

# -100 МБ apt cache
RUN apt update && apt install -y curl && rm -rf /var/lib/apt/lists/*

2. Multi-stage builds

FROM golang:1.22 AS build
COPY . /src
RUN cd /src && go build -o /app

FROM alpine:3.19
COPY --from=build /app /usr/local/bin/app
CMD ["/usr/local/bin/app"]

3. distroless / scratch

FROM scratch
COPY --from=build /app /app
ENTRYPOINT ["/app"]

scratch = 0 байт. Для static binary. distroless — только glibc + сертификаты.

Что НЕ удалить

Файл удалённый в следующем слое — всё равно в образе!

RUN wget big.tar
RUN tar xf big.tar
RUN rm big.tar   ← в отдельном слое: файл остался!

Правильно — && в одном RUN.

Inspect

docker history nginx:alpine
docker inspect nginx:alpine
dive nginx:alpine   # interactive TUI (best)

См. также

← на главную