Skip to content

Instantly share code, notes, and snippets.

@gamedevsam
Created October 22, 2023 18:02
Show Gist options
  • Save gamedevsam/30ceafa0a81ef705e4b8b980643091ef to your computer and use it in GitHub Desktop.
Save gamedevsam/30ceafa0a81ef705e4b8b980643091ef to your computer and use it in GitHub Desktop.
Deploy node@18 in Docker with pnpm
#
# Setup
#
# Use FROM node:lts-alpine for minimum file size
# Use FROM node:lts-slim for maximum compatibility
# More info:
# https://snyk.io/blog/choosing-the-best-node-js-docker-image/
# https://www.specfy.io/blog/1-efficient-dockerfile-nodejs-in-7-steps
#
# To print commands and debug building dockerfile use:
#
# RUN pwd && ls -a
#
# To see full docker logs run the following command:
#
# docker build . --progress=plain
FROM node:18-alpine AS base
# Ensure Node has plenty of RAM allocated for building
ENV NODE_OPTIONS="--max_old_space_size=3072"
# Don't generate the client on dependency install, as we'll do it later
# https://github.com/prisma/prisma/issues/11791#issuecomment-1038796638
ENV PRISMA_SKIP_POSTINSTALL_GENERATE=true
# This allows the dashboard to be embedded within the client bundle.
ENV PUBLIC_URL=/dashboard
# Install & activate pnpm
RUN corepack enable && corepack prepare pnpm@latest --activate
RUN pnpm config set store-dir /tmp/cache/pnpm
# Install utilities
RUN apk add bash
#RUN apk add ncdu
#
# Prepare to install dependencies
#
FROM base AS package_json
WORKDIR /tmp
# Copy all the package.json
COPY /package.json ./package.json
COPY /src/client/package.json ./src/client/package.json
COPY /src/server/package.json ./src/server/package.json
COPY /src/dashboard/package.json ./src/dashboard/package.json
COPY /pnpm-lock.yaml ./
#
# Install dependencies
#
FROM base AS deps
WORKDIR /tmp
# Copy and install dependencies separately from the app's code
# To leverage Docker's cache when no dependency has changed
COPY --from=package_json /tmp ./
COPY /pnpm-workspace.yaml ./
# Copy packages folder which contains workspace dependencies
COPY /infrastructure/packages ./infrastructure/packages
# Install dependencies, including devDependencies
RUN --mount=type=cache,id=pnpm-store,target=/tmp/cache/pnpm\
pnpm install --frozen-lockfile --unsafe-perm
#
# Build
#
FROM base AS build
WORKDIR /build
# Copy the application source code
COPY . .
# Copy the dependencies
COPY --from=deps /tmp ./
# Re-install dev-deps to get pnpm workspaces working properly
RUN --mount=type=cache,id=pnpm-store,target=/tmp/cache/pnpm\
pnpm install --frozen-lockfile --unsafe-perm
# Build the application
RUN NODE_ENV=production pnpm run build
# Purge node_modules
RUN rm -rf node_modules && pnpm recursive exec -- rm -rf ./node_modules
# Install production dependencies
RUN --mount=type=cache,id=pnpm-store,target=/tmp/cache/pnpm\
pnpm install --frozen-lockfile --unsafe-perm --prod
RUN npx prisma generate
#
# Package
#
# Build the final image with only production dependencies
FROM base AS package
WORKDIR /app
# https://www.specfy.io/blog/1-efficient-dockerfile-nodejs-in-7-steps#h-final-docker-image
USER node
# Copy the client bundle
COPY --from=build --chown=node:node /build/src/client/build ./src/client/build
# Copy the server and its dependencies
COPY --from=build --chown=node:node /build/app.json ./app.json
COPY --from=build --chown=node:node /build/package.json ./package.json
COPY --from=build --chown=node:node /build/node_modules ./node_modules
COPY --from=build --chown=node:node /build/infrastructure ./infrastructure
COPY --from=build --chown=node:node /build/src/server/dist ./src/server/dist
COPY --from=build --chown=node:node /build/src/server/node_modules ./src/server/node_modules
COPY --from=build --chown=node:node /build/src/shared/i18n/__generated__ ./src/shared/i18n/__generated__
COPY --from=build --chown=node:node /build/src/shared/schema/__generated__ ./src/shared/schema/__generated__
COPY --from=build --chown=node:node /build/src/shared/schema/archive ./src/shared/schema/archive
#
# Start
#
CMD pnpm start
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment