Dockerfile
Rama main · réplica de lectura del repositorio original.
# syntax=docker/dockerfile:1
# ---------- Build stage ----------
# Exakt die Go-Version, gegen die CI testet (go.mod toolchain, setup-go in allen
# Workflows). Das offizielle Image setzt GOTOOLCHAIN=local, ein schwebendes
# "1.27-alpine" baute also mit einem Compiler, gegen den kein Test lief.
# scripts/check-go-version.cjs hält alle Stellen gleich; ein Update ändert sie
# gemeinsam in einem Commit.
FROM golang:1.27.3-alpine3.24@sha256:d200d2dd76b03a99b52651fd1325aff7dcd35422c35c01bac56571b0507f3deb AS build
WORKDIR /src
# Build tools for module resolution.
RUN apk add --no-cache git ca-certificates
# Resolve dependencies first for better layer caching. No `|| true`: a failed
# module download must fail the build, not silently proceed with an incomplete
# graph (finding CONT-02).
COPY go.mod ./
COPY go.sum* ./
RUN go mod download
# Copy the rest of the source. The build uses the committed go.mod/go.sum as-is —
# no `go mod tidy` here: it would mutate dependency resolution at build time and
# make the image non-reproducible. An inconsistent module graph should fail the
# build (and CI) rather than be silently rewritten (finding CONT-02).
COPY . .
# Build a static binary. Version can be injected at build time.
ARG VERSION=dev
RUN CGO_ENABLED=0 GOOS=linux go build \
-trimpath \
-ldflags="-s -w -X github.com/preining/parkrr/internal/server.Version=${VERSION}" \
-o /out/parkrr ./cmd/parkrr
# ---------- Runtime stage ----------
# Alpine (not distroless) so pg_dump/pg_restore are available for the encrypted
# backup feature; pinned to major 16 to match the postgres:16 server. Runs as a
# dedicated non-root user.
FROM alpine:3.24@sha256:be2656061b536c1883c4034790e21d0a09c5aaaf51968b89368a3c0371ea2c9a
# `apk upgrade` first: `apk add` never lifts an already-satisfied base-image
# package, so libcrypto3/libssl3, busybox etc. would otherwise stay on the
# base tag's (older) -rN even when the repo has a patched build. Upgrading all
# base packages before adding the extras keeps the runtime image patch-fresh.
RUN apk upgrade --no-cache \
&& apk add --no-cache postgresql16-client ca-certificates tzdata \
&& adduser -D -H -u 10001 parkrr \
# Default backup directory, owned by the app user so a named volume mounted
# here (docker-compose) inherits writable ownership for the non-root process.
&& mkdir -p /backups && chown parkrr /backups
WORKDIR /app
COPY --from=build /out/parkrr /app/parkrr
EXPOSE 8080
USER parkrr
# The binary probes itself (no curl needed).
HEALTHCHECK --interval=30s --timeout=5s --start-period=20s --retries=3 \
CMD ["/app/parkrr", "healthcheck"]
ENTRYPOINT ["/app/parkrr"]