Created
March 9, 2023 18:37
-
-
Save Addono/1ca9b570491c6d461fd7e27ca4d7a8b1 to your computer and use it in GitHub Desktop.
Turborepo multi-stage Dockerfile
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
############################################################## | |
##### Full dependencies ##### | |
############################################################## | |
FROM docker.io/library/node:18.14.2-alpine3.16@sha256:72c0b366821377f04d816cd0287360e372cc55782d045e557e2640cb8040d3ea as fulldeps | |
# Install additional packages | |
# - libc6-compat for Turbo >1.5.5. See https://github.com/vercel/turbo/issues/2198 | |
# - rsync for efficiently copying a subset of our files into this container | |
RUN apk add --no-cache libc6-compat rsync | |
WORKDIR /workspace-install | |
COPY package-lock.json turbo.json ./ | |
# Copying files using rsync, as the COPY command in Dockerfiles | |
# have no support for copying files using wildcard-patterns while | |
# preserving the original folder structure. | |
# | |
# 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/*) | |
# | |
RUN --mount=type=bind,target=/docker-context \ | |
rsync -amv --delete \ | |
--exclude='node_modules' \ | |
--exclude='*/node_modules' \ | |
--include='package.json' \ | |
--include='.npmrc' \ | |
--include='*/' \ | |
--exclude='*' \ | |
/docker-context/ /workspace-install/; | |
# Install all dependencies | |
# | |
# 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 | |
RUN npm ci | |
############################################################## | |
##### Build the application ##### | |
############################################################## | |
FROM docker.io/library/node:18.14.2@sha256:b7483c70b94e9fbb68e91d64456ee147d120488f876d69efeae815ba164e8b54 as builder | |
ENV NODE_ENV production | |
WORKDIR /app | |
# Include all source code and dependencies | |
COPY . . | |
COPY --from=fulldeps /workspace-install ./ | |
RUN npm run build | |
############################################################## | |
##### Optimize our builder artifacts for production ##### | |
############################################################## | |
FROM builder as builder-production | |
# Remove all dev dependencies | |
RUN npm ci --production | |
############################################################## | |
##### Create base layer with all packages in production ##### | |
############################################################## | |
FROM docker.io/library/node:18.14.2-alpine3.16@sha256:72c0b366821377f04d816cd0287360e372cc55782d045e557e2640cb8040d3ea as runner | |
WORKDIR /app | |
ENV NODE_ENV production | |
# Add required source-code and build-artifacts | |
COPY package.json ./ | |
COPY --from=builder-production /app/node_modules/ ./node_modules/ | |
COPY --from=builder-production /app/packages/ ./packages/ | |
# Expose the same port for all applications, as it will at least | |
# be used for reporting ready and liveness status. | |
ARG PORT | |
ENV PORT=${PORT:-4000} | |
EXPOSE $PORT | |
############################################################## | |
##### Create layer to run web app ##### | |
############################################################## | |
FROM runner as web | |
RUN addgroup --system --gid 1001 nodejs && adduser --system --uid 1001 app | |
## Apps | |
### web | |
COPY ./apps/web/package.json ./apps/web/ | |
COPY --from=builder-production --chown=app:nodejs /app/apps/web/.next/ ./apps/web/.next/ | |
USER app | |
# Set the CMD to our handler | |
ENTRYPOINT ["npm", "run", "--workspace", "web"] | |
CMD ["start"] | |
############################################################## | |
##### Create layer to run docs app ##### | |
############################################################## | |
FROM runner as docs | |
RUN addgroup --system --gid 1001 nodejs && adduser --system --uid 1001 app | |
## Apps | |
### docs | |
COPY ./apps/docs/package.json ./apps/docs/ | |
COPY --from=builder-production --chown=app:nodejs /app/apps/docs/.next/ ./apps/docs/.next/ | |
USER app | |
# Set the CMD to our handler | |
ENTRYPOINT ["npm", "run", "--workspace", "docs"] | |
CMD ["start"] | |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment