# Прод-образ API. Сборка: docker build -t building-mgmt-api:latest . # # Две стадии: в builder — полный golang-образ со всеми инструментами, # в рантайме — только альпайн с бинарниками и ca-certificates # (нужен для TLS к S3, SMTP и Telegram). Миграции НЕ исключаются из # контекста: они эмбедятся в бинарь через //go:embed. FROM golang:1.27-alpine AS builder WORKDIR /src # Слой зависимостей отдельно: правка кода не сбрасывает кэш модулей. COPY go.mod go.sum ./ RUN go mod download COPY . . # -trimpath убирает пути сборки из бинарней, -s -w — таблицы символов # и DWARF: минус несколько мегабайт, отладка в проде идёт по логам. # Три бинарника в одном образе: api — сервер, migrate и seed — # разовые инструменты (seed заблокирован при APP_ENV=production). RUN CGO_ENABLED=0 go build -trimpath -ldflags="-s -w" -o /out/api ./cmd/api && \ CGO_ENABLED=0 go build -trimpath -ldflags="-s -w" -o /out/migrate ./cmd/migrate && \ CGO_ENABLED=0 go build -trimpath -ldflags="-s -w" -o /out/seed ./cmd/seed FROM alpine:3.22 RUN apk add --no-cache ca-certificates && \ addgroup -S app && adduser -S -G app app COPY --from=builder /out/ /usr/local/bin/ # От root'а не отдаём ни запросов, ни файловой системы контейнера. USER app EXPOSE 8080 # busybox wget входит в альпайн; /ping — открытый хеллер без авторизации. HEALTHCHECK --interval=30s --timeout=3s --start-period=10s \ CMD wget -qO- http://127.0.0.1:8080/ping || exit 1 CMD ["api"]