Skip to content
Draft
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 1 addition & 0 deletions .dockerignore
Original file line number Diff line number Diff line change
Expand Up @@ -3,5 +3,6 @@
*Dockerfile*
# Ignore node_modules to prevent issues with wrong binaries (e.g. sentry cli)
node_modules
app/node_modules
.DS_Store
*.log
90 changes: 70 additions & 20 deletions Dockerfile
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
Comment on lines +95 to +101
Copy link
Contributor

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).


# Let's not run as root
USER node

EXPOSE 3000

# Instead of running npm start; handle signals (SIGINT/SIGTERM) properly
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Newer versions of Next.js require ENV HOSTNAME=0.0.0.0. Might be worth adding it today to not get any surprises when you upgrade Next.js in the future.

See official Docker example: https://github.com/vercel/next.js/blob/62ac6d040183d48a5d83d2b197826c0c471caa62/examples/with-docker/Dockerfile#L65

CMD ["node", "app/server.cjs"]
Loading