Skip to content

Instantly share code, notes, and snippets.

@rphlmr
Last active April 24, 2025 20:55
Show Gist options
  • Save rphlmr/0e4645c628990155bd25523f0549a78c to your computer and use it in GitHub Desktop.
Save rphlmr/0e4645c628990155bd25523f0549a78c to your computer and use it in GitHub Desktop.
pnpm turbo monorepo and react router
ARG APP_NAME=my-app
# Base image
FROM node:22-alpine AS base
ENV COREPACK_ENABLE_DOWNLOAD_PROMPT=0
ENV PNPM_HOME="/pnpm"
ENV PATH="$PNPM_HOME:$PATH"
RUN addgroup --system --gid 1001 rr && \
adduser --system --uid 1001 --ingroup rr rr && \
apk add --no-cache libc6-compat && \
corepack enable && \
corepack install --global pnpm@10 && \
pnpm install turbo --global
# Pruner
FROM base AS pruner
ARG APP_NAME
WORKDIR /app
COPY --chown=rr:rr . .
RUN turbo prune $APP_NAME --docker
# Prefetch deps - refreshed only if pnpm workspace is updated
FROM base AS prefetch-deps
ARG APP_NAME
# We only need to warm the store
WORKDIR /.temp
COPY --chown=rr:rr pnpm-lock.yaml pnpm-workspace.yaml .npmrc ./
RUN pnpm fetch
# Dev and Build deps
FROM prefetch-deps AS dev-deps
ARG APP_NAME
WORKDIR /app
COPY --from=pruner --chown=rr:rr /app/out/json/ .
RUN pnpm --filter=$APP_NAME --frozen-lockfile --offline install
# Production deps
FROM prefetch-deps AS production-deps
ARG APP_NAME
WORKDIR /app
COPY --from=pruner --chown=rr:rr /app/out/json/ .
RUN pnpm --filter=$APP_NAME --frozen-lockfile --offline install --prod
# Builder
FROM base AS builder
ARG APP_NAME
ENV NODE_ENV=production
WORKDIR /app
COPY --from=pruner --chown=rr:rr /app/out/full/ .
COPY --from=dev-deps --chown=rr:rr /app/ .
COPY --chown=rr:rr turbo.json turbo.json
RUN turbo build --filter=$APP_NAME
# Final image
FROM base AS runner
ARG APP_NAME
ENV PORT=3000
ENV TZ=UTC
ENV NODE_ENV=production
ENV START=${APP_NAME}:start
WORKDIR /app
COPY --from=production-deps --chown=rr:rr /app/ .
COPY --from=builder --chown=rr:rr /app/package.json ./package.json
COPY --from=builder --chown=rr:rr /app/apps/$APP_NAME/package.json ./apps/$APP_NAME/package.json
COPY --from=builder --chown=rr:rr /app/apps/$APP_NAME/build ./apps/$APP_NAME/build
COPY --from=builder --chown=rr:rr /app/apps/$APP_NAME/public ./apps/$APP_NAME/public
EXPOSE 3000
USER rr
SHELL ["/bin/ash", "-c"]
CMD pnpm ${START}
**/.*
!**/*.server
!**/*.client
!.npmrc
**/node_modules
**/build
**/test
**/vitest.config.ts
**/.cache
**/README.md
**/Dockerfile
**/types
**/*test*
biome.json
{
"name": "my-repo",
"private": true,
"scripts": {
"build": "turbo run build",
"dev": "turbo run dev",
"my-app:start": "pnpm run --filter my-app start",
"my-app:start:docker": "run-s my-app:docker:*",
"my-app:docker:build": "docker build --progress plain -f apps/my-app/Dockerfile -t my-app .",
"my-app:docker:run": "docker run --rm -p 3000:3000 --env-file ./apps/my-app/.env my-app"
},
"devDependencies": {
"@biomejs/biome": "^1.9.4",
"npm-run-all": "^4.1.5",
"turbo": "^2.5.0",
"typescript": "5.8.2"
},
"engines": {
"node": ">=22"
},
"packageManager": "[email protected]+sha512.0486e394640d3c1fb3c9d43d49cf92879ff74f8516959c235308f5a8f62e2e19528a65cdc2a3058f587cde71eba3d5b56327c8c33a97e4c4051ca48a10ca2d5f"
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment