Skip to content

Commit d227b4d

Browse files
committed
Harden Docker image: switch to Chainguard static, run as non-root
- Replace gcr.io/distroless/static:latest with cgr.dev/chainguard/static (zero known CVEs, rebuilt nightly, non-root by default) - Pre-create /data directory with non-root ownership (UID 65532) - Add -s -w ldflags to strip debug symbols for smaller binary - Remove unnecessary CGO_ENABLED=0 from go mod download step
1 parent cbbceb5 commit d227b4d

File tree

1 file changed

+17
-14
lines changed

1 file changed

+17
-14
lines changed

Dockerfile

Lines changed: 17 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -12,42 +12,45 @@ WORKDIR /app
1212
COPY go.mod go.sum ./
1313

1414
# Download dependencies. This step is cached if go.mod/go.sum don't change.
15-
# CGO_ENABLED=0 is important for static binaries compatible with distroless/static
16-
RUN CGO_ENABLED=0 go mod download
15+
RUN go mod download
1716

1817
# Copy the source code
1918
COPY . .
2019

21-
# Build the main application binary
22-
# -ldflags to embed version info into the binary
23-
# Output binary to /dxcluster-go-api for easy copying in the next stage
24-
RUN CGO_ENABLED=0 go build -ldflags "-X 'github.com/user00265/dxclustergoapi/version.BuildVersion=${BUILD_VERSION}' \
20+
# Build a fully static binary (CGO_ENABLED=0)
21+
# -ldflags to embed version info and strip debug symbols (-s -w) for smaller binary
22+
RUN CGO_ENABLED=0 go build -ldflags "-s -w \
23+
-X 'github.com/user00265/dxclustergoapi/version.BuildVersion=${BUILD_VERSION}' \
2524
-X 'github.com/user00265/dxclustergoapi/version.GitCommit=${GIT_COMMIT}'" \
2625
-o /dxcluster-go-api ./
2726

28-
# Stage 2: Create the final Distroless image
29-
FROM gcr.io/distroless/static:latest
27+
# Create the /data directory with correct ownership for the non-root user.
28+
# Chainguard static uses UID 65532 (nonroot).
29+
RUN mkdir -p /data && chown 65532:65532 /data
30+
31+
# Stage 2: Hardened runtime image
32+
# Chainguard static: zero known CVEs, rebuilt nightly, non-root by default,
33+
# includes CA certificates for HTTPS. No shell, no package manager.
34+
FROM cgr.dev/chainguard/static:latest
3035

3136
# Set working directory for the application
3237
WORKDIR /app
3338

3439
# Copy the built executable from the builder stage
3540
COPY --from=builder /dxcluster-go-api /app/dxcluster-go-api
3641

42+
# Copy the pre-created /data directory with correct ownership
43+
COPY --from=builder /data /data
44+
3745
# Expose the web port
3846
EXPOSE 8192
3947

4048
# Define the HEALTHCHECK using the binary's subcommand.
41-
# --start-period: gives the container time to initialize without failing the health check.
42-
# --interval: how often to run the check.
43-
# --timeout: how long to wait for the command to return.
44-
# --retries: how many consecutive failures before marking as unhealthy.
4549
HEALTHCHECK --start-period=60s --interval=60s --timeout=5s --retries=3 \
4650
CMD ["/app/dxcluster-go-api", "healthcheck"]
4751

4852
# Set the entry point to run our application
49-
# The entrypoint will always be our main binary.
5053
ENTRYPOINT ["/app/dxcluster-go-api"]
5154

5255
# Default command: run the main 'serve' subcommand.
53-
CMD ["serve"]
56+
CMD ["serve"]

0 commit comments

Comments
 (0)