|
| 1 | +FROM node:20-alpine AS base |
| 2 | + |
| 3 | +# mostly inspired from https://github.com/BretFisher/node-docker-good-defaults/blob/main/Dockerfile & https://github.com/remix-run/example-trellix/blob/main/Dockerfile |
| 4 | + |
| 5 | +# Check https://github.com/nodejs/docker-node/tree/b4117f9333da4138b03a546ec926ef50a31506c3#nodealpine to understand why libc6-compat might be needed. |
| 6 | +RUN apk add --no-cache libc6-compat |
| 7 | +RUN corepack enable && corepack prepare pnpm@8.15.4 --activate |
| 8 | +# set the store dir to a folder that is not in the project |
| 9 | +RUN pnpm config set store-dir ~/.pnpm-store |
| 10 | +RUN pnpm fetch |
| 11 | + |
| 12 | +# 1. Install all dependencies including dev dependencies |
| 13 | +FROM base AS deps |
| 14 | +# Root user is implicit so you don't have to actually specify it. From https://stackoverflow.com/a/45553149/6141587 |
| 15 | +# USER root |
| 16 | +USER node |
| 17 | +# WORKDIR now sets correct permissions if you set USER first so `USER node` has permissions on `/app` directory |
| 18 | +WORKDIR /app |
| 19 | + |
| 20 | +# Install dependencies based on the preferred package manager |
| 21 | +COPY --chown=node:node package.json pnpm-lock.yaml* ./ |
| 22 | +COPY --chown=node:node /src/app/db/migrations ./migrations |
| 23 | + |
| 24 | +USER root |
| 25 | +RUN pnpm install --frozen-lockfile --prefer-offline |
| 26 | +RUN pnpm install sharp@0.32.6 |
| 27 | + |
| 28 | +# 2. Rebuild the source code only when needed |
| 29 | +FROM base AS builder |
| 30 | +WORKDIR /app |
| 31 | +# Inspired by https://github.com/vercel/next.js/discussions/36935 |
| 32 | +RUN mkdir -p /app/.next/cache && chown -R node:node /app/.next/cache |
| 33 | +# Persist the next cache in a volume |
| 34 | +VOLUME ["/app/.next/cache"] |
| 35 | +COPY --from=deps --chown=node:node /app/node_modules ./node_modules |
| 36 | + |
| 37 | +COPY --chown=node:node . . |
| 38 | + |
| 39 | +# This will do the trick, use the corresponding env file for each environment. |
| 40 | +COPY --chown=node:node .env.staging .env.staging |
| 41 | + |
| 42 | +# Copied from https://stackoverflow.com/a/69867550/6141587 |
| 43 | +USER root |
| 44 | +# Give /data directory correct permissions otherwise WAL mode won't work. It means you can't have 2 users writing to the database at the same time without this line as *.sqlite-wal & *.sqlite-shm are automatically created & deleted when *.sqlite is busy. |
| 45 | +RUN mkdir -p /data && chown -R node:node /data |
| 46 | + |
| 47 | +# set to production otherwise it throws error ⚠ You are using a non-standard "NODE_ENV" value in your environment. This creates inconsistencies in the project and is strongly advised against. Read more: https://nextjs.org/docs/messages/non-standard-node-env |
| 48 | +ENV NODE_ENV production |
| 49 | +ENV NEXT_TELEMETRY_DISABLED 1 |
| 50 | + |
| 51 | +RUN pnpm build |
| 52 | + |
| 53 | +# 3. Production image, copy all the files and run next |
| 54 | +FROM base AS runner |
| 55 | +USER node |
| 56 | +WORKDIR /app |
| 57 | + |
| 58 | +EXPOSE 3000 |
| 59 | + |
| 60 | +ENV PORT 3000 |
| 61 | +ENV HOSTNAME 0.0.0.0 |
| 62 | +ENV NODE_ENV production |
| 63 | +ENV NEXT_TELEMETRY_DISABLED 1 |
| 64 | + |
| 65 | +COPY --from=builder --chown=node:node /app/public ./public |
| 66 | + |
| 67 | +# Automatically leverage output traces to reduce image size |
| 68 | +# https://nextjs.org/docs/advanced-features/output-file-tracing |
| 69 | +COPY --from=builder --chown=node:node /app/.next/standalone ./ |
| 70 | +COPY --from=builder --chown=node:node /app/.next/static ./.next/static |
| 71 | + |
| 72 | +# Move the drizzle directory to the runtime image |
| 73 | +COPY --from=builder --chown=node:node /app/src/app/db/migrations ./migrations |
| 74 | + |
| 75 | +# Move the litestream binary to the runtime image from the litestream image |
| 76 | +# You can use a specific version of litestream by changing the tag |
| 77 | +# COPY --from=litestream/litestream:0.3.13 /usr/local/bin/litestream /usr/local/bin/litestream |
| 78 | +COPY --from=litestream/litestream:latest --chown=node:node /usr/local/bin/litestream /usr/local/bin/litestream |
| 79 | +COPY --from=builder --chown=node:node /app/litestream.yml /etc/litestream.yml |
| 80 | + |
| 81 | +COPY --from=builder --chown=node:node /app/scripts/drizzle-migrate.mjs ./scripts/drizzle-migrate.mjs |
| 82 | +COPY --from=builder --chown=node:node /app/scripts/package.json ./scripts/package.json |
| 83 | +COPY --from=builder --chown=node:node /app/scripts/pnpm-lock.yaml ./scripts/pnpm-lock.yaml |
| 84 | +COPY --from=builder --chown=node:node /app/scripts/run.staging.sh ./run.staging.sh |
| 85 | +RUN chmod +x run.staging.sh |
| 86 | + |
| 87 | +CMD ["sh", "run.staging.sh"] |
0 commit comments