-
Notifications
You must be signed in to change notification settings - Fork 4
perf: Multistage Docker build #2200
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
base: main
Are you sure you want to change the base?
Changes from all commits
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -1,59 +1,109 @@ | ||
FROM node:20 | ||
# ----------- Base ----------- | ||
FROM node:20-slim AS base | ||
RUN apt-get update -y && apt-get install -y openssl && apt-get install ca-certificates -y | ||
|
||
RUN mkdir -p /usr/src/app | ||
# ----------- Deps ----------- | ||
# Install deps and build the app | ||
FROM base AS deps | ||
WORKDIR /usr/src/app | ||
|
||
# build with | ||
# docker build . \ | ||
# --build-arg PREVENT_SEARCH_BOTS=<true/false> \ | ||
# --build-arg COMMIT=$(git rev-parse HEAD) \ | ||
# --build-arg VECTOR_TILE_URL=<url of the vector service> \ | ||
# --build-arg MAPTILER_STYLE_KEY=<maptiler style key> \ | ||
# docker build --no-cache . \ | ||
# --build-arg ADFS_ID=<adfs client id> \ | ||
# --build-arg ADFS_ISSUER=<adfs issuer> \ | ||
# --build-arg ADFS_PROFILE_URL=<adfs profile url> \ | ||
# --build-arg COMMIT=$(git rev-parse HEAD) \ | ||
# --build-arg MAPTILER_STYLE_KEY=<maptiler style key> \ | ||
# --build-arg NEXTAUTH_SECRET=<nextauth secret> \ | ||
# --build-arg NEXTAUTH_URL=<nextauth url> | ||
# --build-arg NEXTAUTH_URL=<nextauth url> \ | ||
# --build-arg PREVENT_SEARCH_BOTS=<true/false> \ | ||
# --build-arg SENTRY_ORG=<sentry org> \ | ||
# --build-arg SENTRY_PROJECT=<sentry project> \ | ||
# --build-arg VECTOR_TILE_URL=<url of the vector service> | ||
|
||
# Supplied by build pipeline | ||
ARG PREVENT_SEARCH_BOTS | ||
ARG COMMIT | ||
ARG VECTOR_TILE_URL | ||
ARG MAPTILER_STYLE_KEY | ||
ARG ADFS_ID | ||
ARG ADFS_ISSUER | ||
ARG ADFS_PROFILE_URL | ||
ARG COMMIT | ||
ARG MAPTILER_STYLE_KEY | ||
ARG NEXTAUTH_SECRET | ||
ARG NEXTAUTH_URL | ||
ARG PREVENT_SEARCH_BOTS | ||
ARG SENTRY_ORG | ||
ARG SENTRY_PROJECT | ||
ARG VECTOR_TILE_URL | ||
|
||
# Sentry args optional | ||
# ARG SENTRY_DSN | ||
# ARG SENTRY_AUTH_TOKEN | ||
|
||
# Build app | ||
COPY package.json yarn.lock ./ | ||
COPY app/package.json ./app/ | ||
|
||
# Yarn will find all files linked in the workspace and not | ||
# generate a new lock file | ||
RUN yarn install --frozen-lockfile | ||
|
||
ENV NODE_ENV production | ||
ENV NODE_OPTIONS="--max-http-header-size=65536 --max_old_space_size=2048" | ||
ENV NEXT_TELEMETRY_DISABLED=1 | ||
ENV STORYBOOK_DISABLE_TELEMETRY=1 | ||
ENV PORT 3000 | ||
|
||
ENV PREVENT_SEARCH_BOTS=$PREVENT_SEARCH_BOTS | ||
ENV NEXT_PUBLIC_COMMIT=$COMMIT | ||
ENV NEXT_PUBLIC_BASE_VECTOR_TILE_URL=$VECTOR_TILE_URL | ||
ENV NEXT_PUBLIC_MAPTILER_STYLE_KEY=$MAPTILER_STYLE_KEY | ||
# Build-time vars, will be inlined into the app | ||
ENV ADFS_ID=$ADFS_ID | ||
ENV ADFS_ISSUER=$ADFS_ISSUER | ||
ENV ADFS_PROFILE_URL=$ADFS_PROFILE_URL | ||
ENV NEXT_PUBLIC_COMMIT=$COMMIT | ||
ENV NEXT_PUBLIC_MAPTILER_STYLE_KEY=$MAPTILER_STYLE_KEY | ||
ENV NEXTAUTH_SECRET=$NEXTAUTH_SECRET | ||
ENV NEXTAUTH_URL=$NEXTAUTH_URL | ||
ENV PREVENT_SEARCH_BOTS=$PREVENT_SEARCH_BOTS | ||
ENV SENTRY_ORG=$SENTRY_ORG | ||
ENV SENTRY_PROJECT=$SENTRY_PROJECT | ||
ENV NEXT_PUBLIC_BASE_VECTOR_TILE_URL=$VECTOR_TILE_URL | ||
|
||
# ENV SENTRY_DSN=$SENTRY_DSN | ||
# ENV SENTRY_AUTH_TOKEN | ||
|
||
# ENV GLOBAL_AGENT_ENVIRONMENT_VARIABLE_NAMESPACE= | ||
# ENV NO_PROXY='localhost,127.0.0.1' | ||
|
||
COPY ./ ./ | ||
|
||
RUN yarn prisma generate | ||
RUN yarn build | ||
|
||
# Install only prod dependencies and start app | ||
# Install only prod dependencies and clean cache | ||
RUN yarn install --frozen-lockfile --production && yarn cache clean | ||
CMD yarn start | ||
|
||
EXPOSE 3000 | ||
# ----------- Runner ----------- | ||
# Production image, copy necessary files and run next | ||
FROM base AS runner | ||
WORKDIR /usr/src/app | ||
|
||
ENV NODE_ENV production | ||
ENV NODE_OPTIONS="--max-http-header-size=65536 --max_old_space_size=2048" | ||
|
||
# Copy Next app standalone output | ||
# https://nextjs.org/docs/pages/api-reference/next-config-js/output | ||
COPY --from=deps --chown=node:node /usr/src/app/app/.next/standalone ./ | ||
COPY --from=deps --chown=node:node /usr/src/app/app/.next/static ./app/.next/static | ||
COPY --from=deps --chown=node:node /usr/src/app/app/public ./app/public | ||
|
||
# The file that Next.js generates is CommonJS, but the frontend folder has a | ||
# package.json with type:module, so node expects ESM when files have a .js | ||
# extension. | ||
# | ||
# This should eventually be fixed in Next.js, but for the time being adjusting | ||
# the extension seems to be the easiest path forward (thanks @wereHamster!) | ||
RUN mv ./app/server.js ./app/server.cjs | ||
|
||
# Let's not run as root | ||
USER node | ||
|
||
EXPOSE 3000 | ||
|
||
# Instead of running npm start; handle signals (SIGINT/SIGTERM) properly | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Newer versions of Next.js require ENV See official Docker example: https://github.com/vercel/next.js/blob/62ac6d040183d48a5d83d2b197826c0c471caa62/examples/with-docker/Dockerfile#L65 |
||
CMD ["node", "app/server.cjs"] |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This project does not use type:module, so renaming the file to add the .cjs extension is not necessary. And I believe the latest Next.js works without this workaround (if you ever decide to switch to type:module).