Irbisa · Шпаргалка
Docker и контейнеры
Образы, слои и кэш сборки, multi-stage Dockerfile для Go, scratch и distroless, Compose для локальной разработки, тома и сети, сигналы и PID 1, безопасность образа, multi-arch сборки
Что такое контейнер, чем он отличается от виртуальной машины и что дают ему namespaces и cgroups?
Чем отличаются образ, контейнер и реестр (registry), и что такое слой образа?
# one layer per build step that changed files; ENTRYPOINT only sets config$ docker image history --format 'table {{.CreatedBy}}\t{{.Size}}' registry.example.com/api:1.4.0CREATED BY SIZEENTRYPOINT ["/api"] 0BCOPY /out/api /api # buildkit 10.7MBbazel build //common:cacerts_deb... 319kB…Что делают
RUN,CMDиENTRYPOINTв Dockerfile, и почему важна exec-форма["/api"]?# syntax=docker/dockerfile:1FROM golang:1.25 AS buildWORKDIR /srcCOPY go.mod go.sum ./# RUN: executed at build time; its file changes are saved as a layerRUN go mod download…Чем
EXPOSEотличается от-p 8080:8080, и почему Go-сервер, который слушает127.0.0.1:8080, недоступен через опубликованный порт?package main import ( "log" "net/http")…Чем named volume отличается от bind mount, где Postgres должен хранить данные в Compose и что удаляет
docker compose down -v?services: postgres: image: postgres:17-alpine environment: {POSTGRES_USER: app, POSTGRES_PASSWORD: app, POSTGRES_DB: app} volumes: # named volume: managed by Docker, survives down, removed by down -v…Как написать production-Dockerfile для Go-сервиса и что ломается, когда бинарник запускается на
scratch?# syntax=docker/dockerfile:1FROM golang:1.25 AS buildWORKDIR /srcCOPY go.mod go.sum ./RUN go mod download # cached until go.mod/go.sum changeCOPY . .…Найдите баг: после правки одной строки в хендлере
docker buildзаново скачивает все модули и перекомпилирует всё дерево зависимостей.# syntax=docker/dockerfile:1FROM golang:1.25 AS buildWORKDIR /srcCOPY . .RUN go mod downloadRUN CGO_ENABLED=0 go build -o /out/api ./cmd/api FROM gcr.io/distroless/static-debian12:nonrootCOPY --from=build /out/api /apiENTRYPOINT ["/api"]Что такое контекст сборки Docker и что ломается, если в Go-репозитории нет
.dockerignore?# .dockerignore at the root of the build context, allowlist style:# exclude everything...*# ...then re-include only what the Go build reads!go.mod!go.sum…Образ, собранный на Mac с Apple Silicon, падает на amd64-сервере с
exec /api: exec format error. Почему, и как собрать один образ под обе архитектуры?# syntax=docker/dockerfile:1# The build stage runs natively on the builder's own platform: no emulation.FROM --platform=$BUILDPLATFORM golang:1.25 AS buildWORKDIR /srcCOPY go.mod go.sum ./RUN go mod download…Почему деплоить
:latestплохо, и чем тег образа отличается от digest?# syntax=docker/dockerfile:1# wrong: a moving tag, a different image after every Go patch or Debian update# FROM golang:1.25 AS build# right: the tag is for humans; the digest decides what is pulledFROM golang:1.25.14@sha256:699337d620559a59b4a2bb298ad59611e535d2ee755a34cf2d2a98f37578dc80 AS buildWORKDIR /src…Контейнер на базе Alpine стартует через
entrypoint.sh, который читает секрет и запускает/app/server. Теперь поды останавливаются все 30 с и не пишут лог shutdown. Почему?#!/bin/sh# entrypoint.shset -euDB_PASSWORD="$(cat /run/secrets/db-password)"export DB_PASSWORD…Почему Go-контейнер должен работать не от root и как это настроить на
scratchили distroless?# Dockerfile: USER 65532:65532 (numeric, so runAsNonRoot can verify it)spec: securityContext: runAsNonRoot: true runAsUser: 65532 runAsGroup: 65532…Почему секреты нельзя зашивать в образ контейнера и как Go-сервис должен получать их вместо этого: при сборке и в рантайме?
# syntax=docker/dockerfile:1FROM golang:1.25 AS buildWORKDIR /srcENV GOPRIVATE=github.com/acme/*COPY go.mod go.sum ./# wrong: ARG GITHUB_TOKEN, then RUN git config ... $GITHUB_TOKEN…Как настроить локальную разработку Go-сервиса с Postgres и Redis в Docker Compose, и как заставить сервис ждать готовности базы?
services: api: build: . ports: ["8080:8080"] environment: DATABASE_URL: postgres://app:app@postgres:5432/app?sslmode=disable…Найдите баг: API подключается к Postgres при запуске через
go run, а в Compose падает сdial tcp 127.0.0.1:5432: connect: connection refused.services: api: build: . ports: - "8080:8080" environment: DATABASE_URL: postgres://app:app@localhost:5432/app?sslmode=disable depends_on: postgres: condition: service_healthy postgres: image: postgres:17-alpine environment: {POSTGRES_USER: app, POSTGRES_PASSWORD: app, POSTGRES_DB: app} ports: - "5432:5432" healthcheck: test: ["CMD-SHELL", "pg_isready -U app -d app"] interval: 2sКак защитить образ Go-сервиса помимо запуска не от root: сканирование, SBOM, подпись и ограничения в рантайме?
# 1. scan: OS packages plus the Go modules and stdlib recorded in the binary$ trivy image --severity HIGH,CRITICAL --ignore-unfixed --exit-code 1 \ registry.example.com/api:1.4.0 # 2. Go-aware triage: which vulnerable functions are linked into the binary# (needs symbols: scan a build made without -ldflags=-s)…Сервис работает на distroless, поэтому
docker exec -it api shпадает сexecutable file not found. Как отлаживать запущенный контейнер?$ docker exec -it api shOCI runtime exec failed: exec failed: unable to start container process:exec: "sh": executable file not found in $PATH # Docker: a toolbox container in the same PID and network namespaces$ docker run --rm -it --pid=container:api --network=container:api \…Чем отличаются Docker, containerd, runc и Podman, и что изменилось для ваших образов, когда Kubernetes удалил dockershim в 1.24?