1+ # 🔒 Secure Multi-stage Dockerfile for Export Trakt 4 Letterboxd
2+ # This Dockerfile implements security best practices as specified in Issue #18
3+
4+ # Build stage with security hardening
5+ FROM golang:1.23-alpine AS builder
6+
7+ # Security: Install only necessary build dependencies
8+ RUN apk add --no-cache \
9+ git \
10+ gcc \
11+ musl-dev \
12+ ca-certificates \
13+ && update-ca-certificates
14+
15+ # Security: Create non-root user for build process
16+ RUN addgroup -g 1001 buildgroup && \
17+ adduser -D -u 1001 -G buildgroup builduser
18+
19+ # Set build arguments with security metadata
20+ ARG VERSION=dev
21+ ARG COMMIT_SHA=unknown
22+ ARG BUILD_DATE=unknown
23+
24+ # Set working directory with secure permissions
25+ WORKDIR /app
26+ RUN chown builduser:buildgroup /app
27+
28+ # Switch to non-root user for build
29+ USER builduser
30+
31+ # Copy go module files and download dependencies
32+ COPY --chown=builduser:buildgroup go.mod go.sum ./
33+ RUN go mod download && go mod verify
34+
35+ # Copy source code with proper ownership
36+ COPY --chown=builduser:buildgroup . .
37+
38+ # Security: Build with security flags and minimal binary
39+ RUN CGO_ENABLED=0 GOOS=linux GOARCH=amd64 go build \
40+ -a -installsuffix cgo \
41+ -ldflags "-s -w -extldflags '-static' \
42+ -X github.com/JohanDevl/Export_Trakt_4_Letterboxd/pkg/version.Version=${VERSION} \
43+ -X github.com/JohanDevl/Export_Trakt_4_Letterboxd/pkg/version.CommitSHA=${COMMIT_SHA} \
44+ -X github.com/JohanDevl/Export_Trakt_4_Letterboxd/pkg/version.BuildDate=${BUILD_DATE}" \
45+ -trimpath \
46+ -buildmode=exe \
47+ -o export-trakt ./cmd/export_trakt
48+
49+ # Verify the binary
50+ RUN file export-trakt && ldd export-trakt || true
51+
52+ # Create directory structure in builder stage
53+ USER root
54+ RUN mkdir -p /app/runtime/config /app/runtime/logs /app/runtime/exports /app/runtime/tmp && \
55+ chown -R 65532:65532 /app/runtime && \
56+ chmod 755 /app/runtime && \
57+ chmod 700 /app/runtime/config /app/runtime/logs && \
58+ chmod 755 /app/runtime/exports && \
59+ chmod 700 /app/runtime/tmp
60+
61+ # 🛡️ Runtime stage - Distroless for maximum security
62+ FROM gcr.io/distroless/static-debian11:nonroot
63+
64+ # Security: Set secure working directory
65+ WORKDIR /app
66+
67+ # Copy pre-created directory structure with correct ownership
68+ COPY --from=builder --chown=65532:65532 /app/runtime /app
69+
70+ # Copy binary with secure permissions
71+ COPY --from=builder --chown=65532:65532 /app/export-trakt /app/export-trakt
72+
73+ # Copy locales with secure permissions
74+ COPY --from=builder --chown=65532:65532 /app/locales /app/locales
75+
76+ # Copy security configuration template
77+ COPY --from=builder --chown=65532:65532 /app/config/config.example.toml /app/config/
78+
79+ # Security: User is already set to 65532:65532 in the distroless base image
80+
81+ # Security: Set secure environment variables
82+ ENV EXPORT_TRAKT_EXPORT_OUTPUT_DIR=/app/exports \
83+ EXPORT_TRAKT_LOGGING_FILE=/app/logs/export.log \
84+ EXPORT_TRAKT_CONFIG_FILE=/app/config/config.toml \
85+ EXPORT_TRAKT_SECURITY_ENABLED=true \
86+ EXPORT_TRAKT_SECURITY_KEYRING_BACKEND=env \
87+ EXPORT_TRAKT_SECURITY_AUDIT_LOGGING=true \
88+ EXPORT_TRAKT_SECURITY_REQUIRE_HTTPS=true \
89+ TMPDIR=/app/tmp
90+
91+ # Security: Create secure volumes for persistent data
92+ VOLUME ["/app/config", "/app/logs", "/app/exports"]
93+
94+ # Security: Use exact path to avoid PATH injection
95+ ENTRYPOINT ["/app/export-trakt"]
96+
97+ # Default secure command
98+ CMD ["--help"]
99+
100+ # 🏷️ Enhanced security metadata
101+ LABEL org.opencontainers.image.title="Export Trakt for Letterboxd (Secure)" \
102+ org.opencontainers.image.description="Secure tool to export Trakt.tv data for Letterboxd import with enhanced security features" \
103+ org.opencontainers.image.authors="JohanDevl" \
104+ org.opencontainers.image.url="https://github.com/JohanDevl/Export_Trakt_4_Letterboxd" \
105+ org.opencontainers.image.source="https://github.com/JohanDevl/Export_Trakt_4_Letterboxd" \
106+ org.opencontainers.image.version="${VERSION}" \
107+ org.opencontainers.image.created="${BUILD_DATE}" \
108+ org.opencontainers.image.revision="${COMMIT_SHA}" \
109+ org.opencontainers.image.licenses="MIT" \
110+ org.opencontainers.image.vendor="JohanDevl" \
111+ security.features="non-root,distroless,encrypted-credentials,audit-logging" \
112+ security.scan.policy="required" \
113+ security.compliance="enhanced"
114+
115+ # 🔒 Security Hardening Summary:
116+ # ✅ Multi-stage build to minimize attack surface
117+ # ✅ Distroless base image (no shell, minimal packages)
118+ # ✅ Non-root user (UID 65532)
119+ # ✅ Minimal file permissions (700/755)
120+ # ✅ Static binary with security flags
121+ # ✅ Environment-based credential management
122+ # ✅ Audit logging enabled by default
123+ # ✅ HTTPS enforcement
124+ # ✅ Secure temporary directory
125+ # ✅ Volume security for persistent data
126+ # ✅ Comprehensive security metadata
0 commit comments