/
Dockerfile
248 lines (195 loc) · 8.04 KB
/
Dockerfile
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
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
###################################################################
# Stage 1: Install all workspaces (dev)dependencies #
# and generates node_modules folder(s) #
# ----------------------------------------------------------------#
# Notes: #
# 1. this stage relies on buildkit features #
# 2. depend on .dockerignore, you must at least #
# ignore: all **/node_modules folders and .yarn/cache #
###################################################################
ARG BUILDER_FROM_IMAGE=registry.access.redhat.com/ubi9/nodejs-20
FROM registry.access.redhat.com/ubi9/nodejs-20 AS deps
USER root
# install yarn
RUN curl --silent --location https://dl.yarnpkg.com/rpm/yarn.repo | tee /etc/yum.repos.d/yarn.repo
RUN yum -y install yarn
# install rsync (to fetch cached files)
RUN yum update -y && \
yum install -y rsync
WORKDIR /workspace-install
COPY --chown=default:root yarn.lock .yarnrc.yml ./
COPY --chown=default:root .yarn/ ./.yarn/
# Specific to monerepo's as docker COPY command is pretty limited
# we use buidkit to prepare all files that are necessary for install
# and that will be used to invalidate docker cache.
#
# Files are copied with rsync:
#
# - All package.json present in the host (root, apps/*, packages/*)
#
# Copy all files
WORKDIR /docker-context
COPY --chown=default:root . /docker-context
# mount type bind is not supported on current version (4.10.35) of OpenShift build
# RUN --mount=type=bind,source=./,target=/docker-context \
RUN rsync -amv \
--chown=default:root \
--exclude='node_modules' \
--exclude='*/node_modules' \
--include='package.json' \
--include='*/' --exclude='*' \
/docker-context/ /workspace-install/;
RUN chown -R default:root .
# remove rsync, unused dependencies, and clean yum cache
RUN yum remove -y rsync && \
yum autoremove -y && \
yum clean all && \
rm -rf /var/cache/yum
#
# To speed up installations, we override the default yarn cache folder
# and mount it as a buildkit cache mount (builkit will rotate it if needed)
# This strategy allows to exclude the yarn cache in subsequent docker
# layers (size benefit) and reduce packages fetches.
#
# PS:
# 1. Cache mounts can be used in CI (github actions)
# 2. To manually clear the cache
# > docker builder prune --filter type=exec.cachemount
#
# Does not play well with buildkit on CI
# https://github.com/moby/buildkit/issues/1673
# mount type cache is not supported on current version (4.10.35) of OpenShift build
#RUN --mount=type=cache,target=/root/.yarn3-cache,id=yarn3-cache \
# YARN_CACHE_FOLDER=/root/.yarn3-cache \
# yarn install --immutable --inline-builds
###################################################################
# Stage 2: Build the app #
###################################################################
FROM ${BUILDER_FROM_IMAGE} AS builder
# Build ARGS
ARG PROJECT
ARG CMS_ORIGIN
ARG SKIP_BUILD_STATIC_GENERATION
ARG FEDERATION_ROUTER_ENDPOINT
ARG LINKEDEVENTS_EVENT_ENDPOINT
ARG NEXT_PUBLIC_APP_ORIGIN
ARG NEXT_PUBLIC_MATOMO_URL_BASE
ARG NEXT_PUBLIC_MATOMO_SITE_ID
ARG NEXT_PUBLIC_MATOMO_SRC_URL
ARG NEXT_PUBLIC_MATOMO_TRACKER_URL
ARG NEXT_PUBLIC_MATOMO_ENABLED
ARG NEXT_PUBLIC_ASKEM_API_KEY_FI
ARG NEXT_PUBLIC_ASKEM_API_KEY_EN
ARG NEXT_PUBLIC_ASKEM_API_KEY_SV
ARG NEXT_PUBLIC_ASKEM_ENABLED
ARG NEXT_PUBLIC_ALLOW_UNAUTHORIZED_REQUESTS
ARG NEXT_PUBLIC_SENTRY_ENVIRONMENT
ARG NEXT_PUBLIC_SENTRY_DSN
ARG NEXT_PUBLIC_SENTRY_TRACE_SAMPLE_RATE
ARG NEXT_PUBLIC_SENTRY_REPLAY_SESSION_SAMPLE_RATE
ARG NEXT_PUBLIC_SENTRY_REPLAY_ON_ERROR_SAMPLE_RATE
ARG SENTRY_AUTH_TOKEN
ARG NEXT_PUBLIC_DEBUG
ARG NEXTJS_DISABLE_SENTRY
ARG NEXT_PUBLIC_IMAGE_PROXY_URL
ARG NEXT_PUBLIC_DEFAULT_ISR_REVALIDATE_SECONDS
ARG NEXT_PUBLIC_CMS_HEADER_MENU_NAME_FI
ARG NEXT_PUBLIC_CMS_HEADER_MENU_NAME_EN
ARG NEXT_PUBLIC_CMS_HEADER_MENU_NAME_SV
ARG NEXT_PUBLIC_CMS_HEADER_UNIVERSAL_BAR_MENU_NAME_FI
ARG NEXT_PUBLIC_CMS_HEADER_UNIVERSAL_BAR_MENU_NAME_EN
ARG NEXT_PUBLIC_CMS_HEADER_UNIVERSAL_BAR_MENU_NAME_SV
ARG NEXT_PUBLIC_CMS_FOOTER_MENU_NAME_FI
ARG NEXT_PUBLIC_CMS_FOOTER_MENU_NAME_EN
ARG NEXT_PUBLIC_CMS_FOOTER_MENU_NAME_SV
ARG NEXT_PUBLIC_CMS_ARTICLES_CONTEXT_PATH
ARG NEXT_PUBLIC_CMS_PAGES_CONTEXT_PATH
ARG NEXT_PUBLIC_RELEASE
ARG NEXT_PUBLIC_COMMITHASH
WORKDIR /app
USER root
COPY --chown=default:root . .
COPY --from=deps --chown=default:root /workspace-install ./
# Optional: if the app depends on global /static shared assets like images, locales...
RUN curl --silent --location https://dl.yarnpkg.com/rpm/yarn.repo | tee /etc/yum.repos.d/yarn.repo
RUN yum -y install yarn
USER default
RUN yarn install --immutable --inline-builds
RUN yarn workspace ${PROJECT} share-static-hardlink
RUN yarn workspace ${PROJECT} build
# Does not play well with buildkit on CI
# https://github.com/moby/buildkit/issues/1673
# mount type cache is not supported on current version (4.10.35) of OpenShift build
#RUN --mount=type=cache,target=/root/.yarn3-cache,id=yarn3-cache \
# SKIP_POSTINSTALL=1 \
# YARN_CACHE_FOLDER=/root/.yarn3-cache \
# yarn workspaces focus ${PROJECT} --production
CMD ["sh", "-c", "echo ${PROJECT}"]
###################################################################
# Optional: develop locally #
# NOTE: "In multi-stage builds, #
# last stage should be the production build." #
###################################################################
FROM registry.access.redhat.com/ubi9/nodejs-20 AS develop
# Use non-root user
USER default
# Build ARGS
ARG PROJECT
ARG APP_PORT
ENV NODE_ENV=development
WORKDIR /app
COPY --from=deps --chown=default:root /workspace-install ./
ENV PORT ${APP_PORT:-3000}
# Expose port
EXPOSE $PORT
ENV DEV_START "yarn dev -p ${PORT}"
WORKDIR /app/apps/$PROJECT
CMD ["sh", "-c", "${DEV_START}"]
###################################################################
# Stage 3: Extract a minimal image from the build #
###################################################################
FROM registry.access.redhat.com/ubi9/nodejs-20 AS runner
# Use non-root user
USER default
# Build ARGS
ARG PROJECT
ARG APP_PORT
WORKDIR /app
ENV PATH $PATH:/app/node_modules/.bin
ENV NODE_ENV production
# Copy the configuration files to the apps/project root
COPY --from=builder --chown=default:root /app/apps/${PROJECT}/next.config.js \
/app/apps/${PROJECT}/i18nRoutes.config.js \
/app/apps/${PROJECT}/next-i18next.config.js \
/app/apps/${PROJECT}/package.json \
./apps/${PROJECT}/
# Copy common-i18n to share localization files after build
COPY --from=builder --chown=default:root /app/packages/common-i18n/src/locales \
./packages/common-i18n/src/locales
# Automatically leverage output traces to reduce image size
# https://nextjs.org/docs/advanced-features/output-file-tracing
# copy only the necessary files for a production deployment including select files in node_modules.
COPY --from=builder --chown=default:root /app/apps/${PROJECT}/.next/standalone .
COPY --from=builder --chown=default:root /app/apps/${PROJECT}/.next/static ./apps/${PROJECT}/.next/static
COPY --from=builder --chown=default:root /app/apps/${PROJECT}/public ./apps/${PROJECT}/public
COPY --from=builder --chown=default:root /app/next.base.config.js .
RUN cp -r /app/apps/${PROJECT}/.next/ /app/.next_orig/
# OpenShift write access to Next cache folder
USER root
RUN chgrp -R 0 /app/apps/${PROJECT}/.next/server/pages && chmod g+w -R /app/apps/${PROJECT}/.next/server/pages
USER default
ENV NEXT_TELEMETRY_DISABLED 1
ENV PORT ${APP_PORT:-3000}
# Expose port
EXPOSE $PORT
USER root
# install diffutils (to fetch cached files)
RUN yum update -y && \
yum install -y diffutils
COPY --chown=default:root run_node.sh /app/run_node.sh
RUN chgrp 0 /app/run_node.sh && chmod +x /app/run_node.sh
USER default
# ENV PROD_START "./node_modules/.bin/next start apps/${PROJECT}/ -p ${PORT}"
# ENV PROD_START "node ./apps/${PROJECT}/server.js"
ENV PROJECT ${PROJECT}
CMD ["sh", "-c", "/app/run_node.sh"]