Files
Xor290 919c807004
ci-api / test (push) Failing after 8m7s
ci-web / test (push) Failing after 5m5s
chore: build
2026-09-20 12:18:33 +02:00

51 lines
1.8 KiB
Docker

# syntax=docker/dockerfile:1
# --- Build stage -------------------------------------------------------
# golang:1.26 matches the "go 1.26.0" directive in go.mod (GOTOOLCHAIN=auto
# would otherwise re-download the right toolchain anyway, but pinning here
# keeps builds hermetic and fast).
FROM golang:1.26-alpine AS builder
WORKDIR /src
# Cache deps in their own layer.
COPY go.mod go.sum ./
RUN --mount=type=cache,target=/go/pkg/mod \
go mod download
COPY . .
# CGO disabled -> static binary, runs on the scratch-ish alpine base below
# with no libc surprises. Both entrypoints are built from the same module:
# cmd/api is the long-running server, cmd/seed is the one-shot admin
# bootstrap job (see charts/backend/templates/seed-job.yaml).
RUN --mount=type=cache,target=/go/pkg/mod \
--mount=type=cache,target=/root/.cache/go-build \
CGO_ENABLED=0 GOOS=linux go build -trimpath -ldflags="-s -w" -o /out/api ./cmd/api && \
CGO_ENABLED=0 GOOS=linux go build -trimpath -ldflags="-s -w" -o /out/seed ./cmd/seed
# --- Runtime stage -------------------------------------------------------
FROM alpine:3.20
RUN apk add --no-cache ca-certificates tzdata && \
addgroup -S app && adduser -S app -G app
WORKDIR /app
COPY --from=builder /out/api /out/seed ./
# Migrations are baked into the image so the migration Job (see
# charts/backend/templates/migration-job.yaml) always runs the set that
# matches the running server, without needing a separate artifact.
COPY --from=builder /src/migrations ./migrations
# Local-disk media storage (MEDIA_STORAGE_DRIVER=local) writes here; the
# chart mounts a PVC at this path when persistence is enabled. Owned by the
# non-root "app" user created above.
RUN mkdir -p /app/uploads /app/verification-uploads && \
chown -R app:app /app
USER app
EXPOSE 8080
ENTRYPOINT ["/app/api"]