-
Notifications
You must be signed in to change notification settings - Fork 3
Expand file tree
/
Copy pathDockerfile
More file actions
82 lines (66 loc) · 3.03 KB
/
Dockerfile
File metadata and controls
82 lines (66 loc) · 3.03 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
# =============================================================================
# Stage 1: Build
# =============================================================================
FROM --platform=$BUILDPLATFORM golang:1.26.1-alpine AS builder
WORKDIR /matcher-app
COPY go.mod go.sum ./
RUN go mod download
COPY . .
RUN go mod vendor
ARG TARGETARCH
ARG VERSION=dev
ARG BUILD_TIME
# Build the main application binary (vendor mode — no network needed)
RUN CGO_ENABLED=0 GOOS=linux GOARCH=${TARGETARCH} go build \
-mod=vendor \
-tags netgo \
-ldflags '-s -w -extldflags "-static"' \
-o /app ./cmd/matcher/main.go
# Build a minimal health-probe binary for distroless healthchecks.
# Distroless images have no shell, curl, or wget — this tiny static binary
# performs an HTTP GET against /health and returns exit code 0 or 1.
RUN CGO_ENABLED=0 GOOS=linux GOARCH=${TARGETARCH} go build \
-mod=vendor \
-tags netgo \
-ldflags '-s -w -extldflags "-static"' \
-o /health-probe ./cmd/health-probe/main.go
# =============================================================================
# Stage 2: Runtime
# =============================================================================
FROM gcr.io/distroless/static-debian12:nonroot
# Labels for container metadata
LABEL org.opencontainers.image.title="Matcher" \
org.opencontainers.image.description="Lerian Studio Reconciliation Engine" \
org.opencontainers.image.vendor="Lerian Studio" \
org.opencontainers.image.source="https://github.com/LerianStudio/matcher" \
org.opencontainers.image.version="${VERSION}" \
org.opencontainers.image.created="${BUILD_TIME}"
COPY --from=builder /app /app
COPY --from=builder /health-probe /health-probe
# Copy migrations to both paths:
# - /migrations for the app's RunMigrationsWithLogger call
# - /components/matcher/migrations for lib-commons PostgresConnection
COPY --from=builder /matcher-app/migrations /migrations
COPY --from=builder /matcher-app/migrations /components/matcher/migrations
USER nonroot:nonroot
EXPOSE 4018
# Go runtime memory hint. Not set in the image. Recommended explicit setting is
# approximately 85% of the container memory limit (e.g., GOMEMLIMIT=425MiB for
# a 500MiB pod), matching bootstrap guidance in
# internal/bootstrap/gomemlimit_warn.go.
# Note: when Fetcher is enabled, bootstrap auto-applies ~85% of the cgroup
# memory limit if GOMEMLIMIT is unset (see internal/bootstrap/init_fetcher_bridge.go);
# explicit operator values still take precedence. Example Kubernetes env:
# env:
# - name: GOMEMLIMIT
# valueFrom:
# resourceFieldRef:
# resource: limits.memory
# divisor: "1"
# Go 1.26 auto-detects cgroup CPU via GOMAXPROCS but does NOT auto-detect
# cgroup memory; setting GOMEMLIMIT avoids OOM-kills from uncapped Go heap.
# Health probe defaults to http://localhost:4018/health.
# Override at runtime via HEALTH_PROBE_URL env var for non-default ports.
HEALTHCHECK --interval=30s --timeout=5s --retries=3 --start-period=10s \
CMD ["/health-probe"]
ENTRYPOINT ["/app"]