-
Notifications
You must be signed in to change notification settings - Fork 2
Expand file tree
/
Copy pathDockerfile.web
More file actions
83 lines (72 loc) Β· 4.23 KB
/
Copy pathDockerfile.web
File metadata and controls
83 lines (72 loc) Β· 4.23 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
FROM node:20-alpine AS builder
WORKDIR /app
COPY web/package.json web/package-lock.json* ./
RUN if [ -f package-lock.json ]; then npm ci --legacy-peer-deps; else npm install --legacy-peer-deps; fi
COPY web/ .
# buildChangelog.mjs (prebuild) reads <repo-root>/CHANGELOG.md; place it where
# the script's REPO_ROOT (resolve(__dirname, '..', '..')) β '/' resolves it.
COPY CHANGELOG.md /CHANGELOG.md
# Observability build args β Vite reads VITE_* at build time, so these MUST
# be ARG-declared (not just ENV-defaulted) for `docker compose build` to
# thread them through. Empty values disable the browser RUM gracefully
# (see web/src/observability/rum.ts).
ARG VITE_OTLP_HTTP_ENDPOINT=""
ARG VITE_OTEL_SERVICE_NAME="teslasync-web"
ARG VITE_OTEL_DEPLOY_ENV="dev-compose"
# ββ Build identity βββββββββββββββββββββββββββββββββββββββββββββββββββββββββββ
# Both args are REQUIRED for a release build and are threaded by
# `.github/workflows/release.yml` in the single build-scan/export step, so the
# exact archive that is scanned and promoted carries them.
#
# VITE_APP_VERSION canonical release version (e.g. 2.1.0). Blank means an
# UNVERSIONED build: vite.config.ts then reports
# `dev-<package version>`, which the PWA handshake's
# `parseVersion` deliberately cannot read. That matters β
# a bare `2.0.0` here would look OLDER than a v2.1 API and
# pin an undismissible "update required" prompt forever,
# which reloading could never clear.
# VITE_GIT_SHA immutable per-build commit id. There is no `.git` in this
# context, so `git rev-parse` inside the container always
# fails and the value falls back to `dev`. BUILD_ID is
# `<version>+<sha>` and suffixes every versioned Cache
# Storage bucket, so without this arg every deploy reused
# the same buckets and stale chunks survived `activate()`.
# VITE_RELEASE_BUILD set to `1` ONLY by the release workflow. It asserts
# "this image is going to be published", which makes a
# half-configured identity (version without SHA) a hard
# failure instead of a safe degradation. Without it, a
# version supplied with no resolvable SHA degrades to the
# unversioned identity β so an operator who sets a version
# for their own build gets a harmless image, not a build
# that refuses to complete.
#
# `web/scripts/check-release-build-identity.mjs` fails the release gate when
# any of the three is missing from this file or from the workflow; ordinary
# local and compose builds stay green because they are unversioned by design.
ARG VITE_APP_VERSION=""
ARG VITE_GIT_SHA=""
ARG VITE_RELEASE_BUILD=""
ENV VITE_OTLP_HTTP_ENDPOINT=$VITE_OTLP_HTTP_ENDPOINT \
VITE_OTEL_SERVICE_NAME=$VITE_OTEL_SERVICE_NAME \
VITE_OTEL_DEPLOY_ENV=$VITE_OTEL_DEPLOY_ENV \
VITE_APP_VERSION=$VITE_APP_VERSION \
VITE_GIT_SHA=$VITE_GIT_SHA \
VITE_RELEASE_BUILD=$VITE_RELEASE_BUILD
RUN npm run build
# CLEAN-04 β the runtime stage below copies `dist/` straight into the nginx
# document root, so anything left here is public. `vite.config.ts` already
# defaults `build.sourcemap` to false (maps are only emitted under
# VITE_SOURCEMAP_MODE=private, which this image never sets), but this prune is
# the belt-and-braces guarantee that a future config regression cannot publish
# a byte-exact copy of the frontend source tree. `nginx.conf` additionally
# refuses `.map` requests, and `web/scripts/check-source-maps.mjs` gates all
# three layers.
RUN find dist -name '*.map' -delete
# Serve with a supported, digest-pinned nginx runtime.
FROM nginx:1.30.4-alpine3.24@sha256:97d490c12ba55b4946b01546d1c3ed324e8d41ab1c9fcb2a616aa470620e5b46
RUN apk upgrade --no-cache
COPY --from=builder /app/dist /usr/share/nginx/html
COPY web/nginx.conf /etc/nginx/conf.d/default.conf
EXPOSE 80
HEALTHCHECK --interval=30s --timeout=5s --retries=3 \
CMD wget -qO- http://127.0.0.1:80/ || exit 1