# node:22-alpine as of 2026-02-22 FROM node@sha256:e4bf2a82ad0a4037d28035ae71529873c069b13eb0455466ae0bc13363826e34 AS build WORKDIR /app COPY package.json yarn.lock ./ RUN yarn install --frozen-lockfile RUN apk add --no-cache git make COPY . . # make frontend-check is the frontend half of make check (test + lint + # fmt-check); its test step is the production yarn build, so this both # produces dist/ and gates the image on lint/fmt-check/test regressions. # This node stage has neither Go nor Docker for the other half, which # Dockerfile.backend gates; script/cibuild builds both images. RUN make frontend-check # nginx:stable-alpine as of 2026-02-22 FROM nginx@sha256:15e96e59aa3b0aada3a121296e3bce117721f42d88f5f64217ef4b18f458c6ab RUN rm /etc/nginx/conf.d/default.conf COPY nginx.conf /etc/nginx/conf.d/netwatch.conf COPY --from=build /app/dist /usr/share/nginx/html EXPOSE 8080 CMD ["nginx", "-g", "daemon off;"]