-
Notifications
You must be signed in to change notification settings - Fork 210
Expand file tree
/
Copy pathDockerfile
More file actions
122 lines (93 loc) · 3.89 KB
/
Copy pathDockerfile
File metadata and controls
122 lines (93 loc) · 3.89 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
# syntax=docker/dockerfile:1.7
# Pin the complete multi-platform image digest so builds cannot silently pick up
# a different base image. Renovate/Dependabot can update the tag and digest
# together when a patched Node image is published.
ARG NODE_IMAGE=node:24.18.0-alpine3.23@sha256:595398b0081eacda8e1c4c5b97b76cd1020e4d58a8ebcb4843b9bca1e79e7436
ARG NODE_BUILD_IMAGE=node:24.18.0-alpine3.23@sha256:595398b0081eacda8e1c4c5b97b76cd1020e4d58a8ebcb4843b9bca1e79e7436
FROM ${NODE_BUILD_IMAGE} AS development-dependencies
WORKDIR /opt/app
# Native build tools stay isolated in the disposable builder stages. The
# Alpine runtime stage below never receives them.
RUN apk add --no-cache git python3 make g++ \
&& git config --global url."https://github.com/".insteadOf "git://github.com/"
COPY package.json package-lock.json .npmrc ./
COPY vendor ./vendor
RUN npm ci
FROM development-dependencies AS test
ENV CI=true
COPY . .
RUN npm test
FROM test AS build
ARG CDN_URL
ARG NODE_CONFIG_ENV=production
ENV BABEL_ENV=production \
CDN_URL=${CDN_URL} \
NODE_CONFIG_ENV=${NODE_CONFIG_ENV} \
NODE_ENV=production
# The browser bundle is built as before. Server/shared sources are then
# precompiled so the runtime does not need Babel or the Webpack toolchain.
RUN npm run build \
&& ./node_modules/.bin/babel src \
--out-dir /opt/runtime-src \
--copy-files \
--extensions ".js,.jsx" \
&& rm -rf \
/opt/runtime-src/client \
/opt/runtime-src/styles \
/opt/runtime-src/test \
&& find /opt/runtime-src -type f \
! -name "*.js" \
! -name "*.json" \
-delete \
&& install --directory /opt/runtime-src/assets/images \
&& install --mode=0644 \
src/assets/images/favicon.ico \
/opt/runtime-src/assets/images/favicon.ico
FROM development-dependencies AS production-dependencies
ENV NODE_ENV=production
RUN npm prune --omit=dev --ignore-scripts \
&& npm cache clean --force
FROM ${NODE_IMAGE} AS runtime
LABEL org.opencontainers.image.title="Topcoder Community App" \
org.opencontainers.image.description="Topcoder Community App web server"
ARG CDN_URL
ARG NODE_CONFIG_ENV=production
ENV BABEL_ENV=production \
CDN_URL=${CDN_URL} \
NODE_CONFIG_ENV=${NODE_CONFIG_ENV} \
NODE_ENV=production \
PORT=3000
WORKDIR /opt/app
# The application starts Node directly, so package-manager executables and
# their dependency trees are unnecessary attack surface in production.
RUN rm -rf \
/opt/yarn-* \
/usr/local/lib/node_modules/corepack \
/usr/local/lib/node_modules/npm \
&& rm -f \
/usr/local/bin/corepack \
/usr/local/bin/npm \
/usr/local/bin/npx \
/usr/local/bin/yarn \
/usr/local/bin/yarnpkg
COPY --from=production-dependencies --chown=node:node /opt/app/vendor ./vendor
COPY --from=production-dependencies --chown=node:node /opt/app/node_modules ./node_modules
COPY --from=build --chown=node:node /opt/app/build ./build
COPY --from=build --chown=node:node /opt/app/.build-info ./.build-info
COPY --from=build --chown=node:node /opt/runtime-src ./src
COPY --from=build --chown=node:node \
/opt/app/config/custom-environment-variables.js \
/opt/app/config/default.js \
/opt/app/config/development.js \
/opt/app/config/production.js \
/opt/app/config/qa.js \
./config/
COPY --from=build --chown=node:node /opt/app/config/contentful ./config/contentful
COPY --chown=node:node package.json ./package.json
COPY --chown=node:node bin/runtime.js ./bin/runtime.js
USER node
EXPOSE 3000
HEALTHCHECK --interval=30s --timeout=5s --start-period=30s --retries=3 \
CMD ["node", "-e", "const http=require('http');const req=http.get({host:'127.0.0.1',port:process.env.PORT||3000,path:'/api/cdn/public/ping',timeout:3000},res=>{res.resume();process.exit(res.statusCode===200?0:1);});req.on('timeout',()=>{req.destroy();process.exit(1);});req.on('error',()=>process.exit(1));"]
STOPSIGNAL SIGTERM
CMD ["node", "--max-old-space-size=8192", "bin/runtime.js"]