-
-
Notifications
You must be signed in to change notification settings - Fork 0
Expand file tree
/
Copy pathDockerfile
More file actions
137 lines (109 loc) · 3.75 KB
/
Dockerfile
File metadata and controls
137 lines (109 loc) · 3.75 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
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
# syntax=docker/dockerfile:1
# ===============================
# 0. Global deterministic settings
# ===============================
ARG NODE_IMAGE=node:20.19.0-alpine3.20
ARG SOURCE_DATE_EPOCH=1767225600
# ===============================
# 1. Dependencies layer
# ===============================
FROM ${NODE_IMAGE} AS deps
ARG SOURCE_DATE_EPOCH
ENV SOURCE_DATE_EPOCH=${SOURCE_DATE_EPOCH}
ENV TZ=UTC
# Install only required native dependencies
RUN apk add --no-cache \
libc6-compat \
&& rm -rf /var/cache/apk/*
WORKDIR /app
ARG APP_COMMIT_SHA
ENV APP_COMMIT_SHA=${APP_COMMIT_SHA}
COPY package.json package-lock.json ./
# Use npm ci for clean install
RUN npm ci \
--no-audit \
--no-fund \
--prefer-offline \
--ignore-scripts
# ===============================
# 2. Build layer
# ===============================
FROM ${NODE_IMAGE} AS builder
ARG SOURCE_DATE_EPOCH
ARG APP_COMMIT_SHA
ARG BUILD_ID
ARG AUDIT_STATUS
ARG SIGNATURE_STATUS
ARG NEXT_PUBLIC_SITE_URL
ARG NEXT_PUBLIC_ANALYTICS_ENABLED
ARG GITHUB_REPOSITORY
ARG GITHUB_RUN_ID
ENV SOURCE_DATE_EPOCH=${SOURCE_DATE_EPOCH}
ENV APP_COMMIT_SHA=${APP_COMMIT_SHA}
ENV BUILD_ID=${BUILD_ID}
ENV GITHUB_SHA=${APP_COMMIT_SHA}
ENV GITHUB_RUN_NUMBER=${BUILD_ID}
ENV AUDIT_STATUS=${AUDIT_STATUS}
ENV SIGNATURE_STATUS=${SIGNATURE_STATUS}
ENV NEXT_PUBLIC_SITE_URL=${NEXT_PUBLIC_SITE_URL}
ENV NEXT_PUBLIC_ANALYTICS_ENABLED=${NEXT_PUBLIC_ANALYTICS_ENABLED}
ENV GITHUB_REPOSITORY=${GITHUB_REPOSITORY}
ENV GITHUB_RUN_ID=${GITHUB_RUN_ID}
ENV TZ=UTC
ENV NODE_ENV=production
ENV NEXT_TELEMETRY_DISABLED=1
WORKDIR /app
COPY --from=deps /app/node_modules ./node_modules
COPY --link . .
# Validate required build args
RUN set -e; \
: "${APP_COMMIT_SHA:?APP_COMMIT_SHA is required}"; \
: "${BUILD_ID:?BUILD_ID is required}";
# Build with minimal resources and clean cache
RUN npm run build && \
rm -rf .next/cache
# Normalize timestamps for reproducible builds
RUN find .next -exec touch -d "@${SOURCE_DATE_EPOCH}" {} +
# Normalize absolute paths in standalone server
RUN sed -i 's|/app/|/|g' .next/standalone/server.js
# ===============================
# 3. Runtime layer
# ===============================
FROM ${NODE_IMAGE} AS runner
ARG SOURCE_DATE_EPOCH
ARG APP_COMMIT_SHA
ENV SOURCE_DATE_EPOCH=${SOURCE_DATE_EPOCH}
ENV APP_COMMIT_SHA=${APP_COMMIT_SHA}
ENV NODE_ENV=production
ENV NEXT_TELEMETRY_DISABLED=1
ENV PORT=3000
ENV HOSTNAME=0.0.0.0
# Note: GA_API_SECRET and GA_MEASUREMENT_ID are required at runtime for analytics.
# Do NOT bake secrets or environment-specific configuration into the image at build time.
# Instead, provide GA_API_SECRET and GA_MEASUREMENT_ID as runtime environment variables via:
# - docker run -e GA_API_SECRET=your_secret_here -e GA_MEASUREMENT_ID=your_measurement_id_here
# - Orchestration platform secrets/config management (Kubernetes, Docker Swarm, etc.)
# - Cloud provider environment variable configuration (AWS ECS, Azure Container Apps, etc.)
# While GA_MEASUREMENT_ID is less sensitive than GA_API_SECRET, providing both at runtime
# offers flexibility to change configuration without rebuilding the image.
WORKDIR /app
RUN addgroup --system --gid 1001 nodejs && \
adduser --system --uid 1001 nextjs && \
apk add --no-cache wget
# Core Next.js output
COPY --from=builder --chown=nextjs:nodejs /app/.next/standalone ./
COPY --from=builder --chown=nextjs:nodejs /app/.next/static ./.next/static
COPY --from=builder --chown=nextjs:nodejs /app/public ./public
# Clean up
RUN rm -rf \
/usr/share/man/* \
/usr/share/doc/* \
/var/cache/apk/* \
/tmp/* \
/root/.npm \
/root/.cache
USER nextjs
EXPOSE 3000
HEALTHCHECK --interval=30s --timeout=10s --start-period=40s --retries=3 \
CMD wget --no-verbose --tries=1 --spider http://127.0.0.1:3000/ || exit 1
CMD ["node", "server.js"]