Skip to content

Instantly share code, notes, and snippets.

@tinrab
Created November 25, 2023 00:25
Show Gist options
  • Save tinrab/9d8bc4fe1eabc254167243505e0b97fc to your computer and use it in GitHub Desktop.
Save tinrab/9d8bc4fe1eabc254167243505e0b97fc to your computer and use it in GitHub Desktop.
Example Dockerfile for turbo-based monorepo with Next.js and sharp for image processing
FROM node:20.10-bullseye-slim as base
# Install dependencies only when needed
FROM base AS deps
WORKDIR /workspace
# Install libvips
# Credit: https://hub.docker.com/r/shivjm/node-libvips
ARG LIBVIPS_VERSION=8.15.0
RUN apt-get update -qq && \
apt-get install -qqy python git wget libc6 build-essential libglib2.0-dev libgirepository1.0-dev meson \
libfftw3-dev libexif-dev libjpeg62-turbo-dev \
libwebp-dev libtiff5-dev libpng-dev \
libheif-dev libexpat1-dev liborc-0.4-dev \
liblcms2-dev librsvg2-dev \
libffi-dev libopenjp2-7-dev \
libimagequant-dev && \
echo 'deb http://ftp.debian.org/debian bookworm main' > /etc/apt/sources.list.d/bookworm.list && \
echo 'APT::Default-Release "stable";' > /etc/apt/apt.conf.d/default-release && \
apt-get update -qq && \
apt-get -t bookworm install -qqy libcgif-dev
ENV LIBVIPS_VERSION=$LIBVIPS_VERSION
RUN wget -O /tmp/libvips.tar.gz https://github.com/libvips/libvips/releases/download/v$LIBVIPS_VERSION/vips-$LIBVIPS_VERSION.tar.xz && \
mkdir /libvips && cd /libvips && \
tar xf /tmp/libvips.tar.gz --strip-components=1 && \
meson setup build-dir --buildtype=release && \
cd build-dir && \
ninja && \
ninja test && \
ninja install && \
ldconfig && \
cd .. && \
rm -rf /libvips /tmp/libvips.tar.gz
# TODO: Use turbo prune (https://turbo.build/repo/docs/handbook/deploying-with-docker)
# Copy package files
COPY package.json pnpm-lock.yaml pnpm-workspace.yaml ./
COPY packages/common/package.json packages/common/package.json
COPY apps/site/package.json apps/site/package.json
# ...
# Install dependencies
RUN yarn global add pnpm && pnpm install --frozen-lockfile
# Rebuild the source code only when needed
FROM base AS builder
# Set environment variables
ARG TURNSTILE_SECRET_KEY
ARG MAILGUN_API_KEY
ENV TURNSTILE_SECRET_KEY=$TURNSTILE_SECRET_KEY
ENV MAILGUN_API_KEY=$MAILGUN_API_KEY
# ...
WORKDIR /workspace
COPY --from=deps /workspace/ ./
# Copy source files
COPY package.json pnpm-lock.yaml pnpm-workspace.yaml turbo.json ./
COPY packages packages
COPY apps/site apps/site
# Build monorepo
ENV NODE_ENV production
ENV NEXT_TELEMETRY_DISABLED 1
RUN yarn global add pnpm && pnpm run build
# Production image, copy all the files and run Next.js
FROM base AS runner
WORKDIR /app
# Install chrome for Puppeteer
# ENV PUPPETEER_SKIP_CHROMIUM_DOWNLOAD true
# RUN apt-get update && apt-get install gnupg wget -y && \
# wget --quiet --output-document=- https://dl-ssl.google.com/linux/linux_signing_key.pub | gpg --dearmor > /etc/apt/trusted.gpg.d/google-archive.gpg && \
# sh -c 'echo "deb [arch=amd64] http://dl.google.com/linux/chrome/deb/ stable main" >> /etc/apt/sources.list.d/google.list' && \
# apt-get update && \
# apt-get install google-chrome-stable -y --no-install-recommends
ENV NODE_ENV production
ENV NEXT_TELEMETRY_DISABLED 1
RUN addgroup --system --gid 1001 nodejs
RUN adduser --system --uid 1001 nextjs
RUN rm -rf /var/lib/apt/lists/*
# Set the correct permission for prerender cache
RUN mkdir .next
RUN chown nextjs:nodejs .next
RUN mkdir -p ./apps/site/.next
RUN chown nextjs:nodejs ./apps/site/.next
# Copy built standalone output
COPY --from=builder --chown=nextjs:nodejs /workspace/apps/site/.next/standalone ./
COPY --from=builder --chown=nextjs:nodejs /workspace/apps/site/.next/static ./apps/site/.next/static
COPY --from=builder --chown=nextjs:nodejs /workspace/apps/site/public ./apps/site/public
USER nextjs
EXPOSE 3000
ENV PORT 3000
# Set hostname to localhost
ENV HOSTNAME "0.0.0.0"
# Run the app
CMD ["node", "apps/site/server.js"]
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment