Repository navigation
Expand file tree
/
Copy pathDockerfile
More file actions
executable file
·58 lines (55 loc) · 2.75 KB
/
Copy pathDockerfile
File metadata and controls
executable file
·58 lines (55 loc) · 2.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
# Base image pinned by digest so a rebuild can't silently pull a different
# toolchain under the same tag. Bump deliberately: resolve the new digest with
# `docker buildx imagetools inspect node:22-trixie-slim` and replace all four.
FROM node:22-trixie-slim@sha256:c5849ff9c9ebcd66615412f0b548ca5b8ecaef84003dc9ac2e077ebe46aaa3f6 AS deps
WORKDIR /app
COPY package.json package-lock.json* ./
# better-sqlite3 may not have a prebuilt binary for every Node and CPU
# combination, so provide node-gyp's native build requirements in this stage.
RUN apt-get update \
&& apt-get install -y --no-install-recommends python3 make g++ \
&& rm -rf /var/lib/apt/lists/*
RUN npm ci
FROM node:22-trixie-slim@sha256:c5849ff9c9ebcd66615412f0b548ca5b8ecaef84003dc9ac2e077ebe46aaa3f6 AS build
WORKDIR /app
COPY --from=deps /app/node_modules ./node_modules
COPY . .
RUN npm run build
FROM node:22-trixie-slim@sha256:c5849ff9c9ebcd66615412f0b548ca5b8ecaef84003dc9ac2e077ebe46aaa3f6 AS production-deps
WORKDIR /app
COPY package.json package-lock.json* ./
RUN apt-get update \
&& apt-get install -y --no-install-recommends python3 make g++ \
&& rm -rf /var/lib/apt/lists/*
RUN npm ci --omit=dev
FROM node:22-trixie-slim@sha256:c5849ff9c9ebcd66615412f0b548ca5b8ecaef84003dc9ac2e077ebe46aaa3f6 AS runtime
WORKDIR /app
ENV NODE_ENV=production
ENV PORT=9302
ENV DATA_DIR=/config
# Build metadata — overridden by CI workflows via --build-arg
ARG BUILD_CHANNEL=custom
ARG COMMIT_SHA=local
ENV BUILD_CHANNEL=$BUILD_CHANNEL
ENV COMMIT_SHA=$COMMIT_SHA
RUN apt-get update \
&& apt-get install -y --no-install-recommends fontconfig fonts-dejavu-core gosu python3 \
&& rm -rf /var/lib/apt/lists/*
# The production image starts Node directly. Remove build-time package managers
# to reduce the runtime attack surface; the Yarn directory includes its version.
RUN rm -rf /usr/local/lib/node_modules/npm /usr/local/lib/node_modules/corepack /opt/yarn-v* \
&& rm -f /usr/local/bin/npm /usr/local/bin/npx /usr/local/bin/corepack /usr/local/bin/yarn /usr/local/bin/yarnpkg
COPY --from=build /app/package.json ./package.json
COPY --from=production-deps /app/node_modules ./node_modules
COPY --from=build /app/dist ./dist
COPY docker-entrypoint.sh /entrypoint.sh
COPY docker-ownership-repair.py /ownership-repair.py
RUN chmod 755 /entrypoint.sh
RUN mkdir -p /config && chown node:node /config
ENTRYPOINT ["/entrypoint.sh"]
EXPOSE 9302
# Uses Node's built-in fetch so the check needs no curl/wget and survives npm's
# removal above. Follows a custom PORT; /api/health is unauthenticated.
HEALTHCHECK --interval=30s --timeout=5s --start-period=30s --retries=3 \
CMD node -e "fetch('http://127.0.0.1:'+(process.env.PORT||9302)+'/api/health').then(r=>process.exit(r.ok?0:1)).catch(()=>process.exit(1))"
CMD ["node", "dist/server/server/index.js"]