1- # Use an official node runtime as a parent image
2- FROM node:22-slim AS buildnode
1+ # syntax=docker/dockerfile:1
32
4- WORKDIR /app/
5- RUN chown node:root /app
6-
7- ARG FONTAWESOME_PACKAGE_TOKEN
8- ENV FONTAWESOME_PACKAGE_TOKEN=${FONTAWESOME_PACKAGE_TOKEN}
3+ ############################################
4+ # Builder: install deps and build frontend #
5+ ############################################
6+ FROM node:24-alpine AS buildnode
97
10- # Install dependencies
11- COPY ./src/frontend/package.json /app/
12- COPY ./src/frontend/package-lock.json /app/
13- COPY ./src/frontend/.npmrc /app/
14- RUN npm install
8+ WORKDIR /app/
9+ COPY ./src/frontend/package.json ./src/frontend/package-lock.json ./src/frontend/.npmrc ./
1510
16- # Add rest of the client code
17- COPY ./src/frontend /app/
18- RUN chown node:root /app/node_modules
11+ RUN --mount=type=secret,id=FONTAWESOME_PACKAGE_TOKEN \
12+ test -s /run/secrets/FONTAWESOME_PACKAGE_TOKEN || { echo "FONTAWESOME_PACKAGE_TOKEN secret missing"; exit 1; }; \
13+ export FONTAWESOME_PACKAGE_TOKEN="$(cat /run/secrets/FONTAWESOME_PACKAGE_TOKEN)" && \
14+ npm ci
1915
20- # OpenShift runs as node, not as root (while docker runs as root), so need to
21- # ensure running user can write to its home directory--without setting this,
22- # home is /, so node can't create a cache dir
23- ENV HOME /home/node
16+ COPY ./src/frontend/ /app/
2417
2518RUN npm run openshift_build
2619
27- FROM nginx:stable-alpine
20+ ############################################
21+ # Runtime: nginx serving built assets #
22+ ############################################
23+ FROM nginxinc/nginx-unprivileged:stable-alpine
2824
2925EXPOSE 3000
3026
31- RUN touch /run/nginx.pid
32-
33- COPY ./compose/frontend/default.conf /etc/nginx/conf.d
34- COPY ./compose/frontend/default_maintenance.txt /etc/nginx
35- COPY ./compose/frontend/legacy_redirects.conf /etc/nginx
36- COPY ./compose/frontend/security_headers.conf /etc/nginx/conf.d
37- COPY ./compose/frontend/blocked_ips.conf /etc/nginx/conf.d
27+ # Copy built assets
28+ RUN mkdir -p /usr/share/nginx/html
3829COPY --from=buildnode /app/build /usr/share/nginx/html
39- RUN chmod -R 777 /run /var/log/nginx /var/cache/nginx /usr/share/nginx/html/static/js /usr/share/nginx/html/static/css /usr/share/nginx/html/static/media /etc/nginx/conf.d
4030
41- ARG DEBUG_BUILD=false
31+ USER root
32+ RUN mkdir -p /tmp/cache/nginx && \
33+ chgrp -R 0 /tmp/cache && \
34+ chmod -R g=u /tmp/cache
35+ USER nginx
36+
37+ # Nginx config and runtime permissions
38+ COPY ./compose/frontend/default.conf /etc/nginx/conf.d/default.conf
39+ COPY ./compose/frontend/security_headers.conf /etc/nginx/conf.d/security_headers.conf
40+ COPY ./compose/frontend/blocked_ips.conf /etc/nginx/conf.d/blocked_ips.conf
41+ COPY ./compose/frontend/legacy_redirects.conf /etc/nginx/legacy_redirects.conf
4242
43- # Add debugging tools into builds if enabled
44- RUN if [ ${DEBUG_BUILD} = true ]; then \
45- apk update && apk add --no-cache jq vim procps less; \
46- fi
43+ COPY ./compose/frontend/default_maintenance.txt /etc/nginx/default_maintenance.txt
4744
48- COPY ./compose/frontend/entrypoint /docker-entrypoint.d/add_client_env.sh
49- RUN sed -i 's/\r$//g' /docker-entrypoint.d/add_client_env. sh && chmod +x /docker-entrypoint.d/add_client_env .sh
45+ # Runtime env injection hook (This will be run by an initContainer in OpenShift)
46+ COPY --chmod=755 ./compose/frontend/generate-config. sh /tmp/generate-config .sh
0 commit comments