mirror of
https://github.com/makeplane/plane.git
synced 2025-12-16 20:07:56 +01:00
139 lines
5.0 KiB
Docker
139 lines
5.0 KiB
Docker
# syntax=docker/dockerfile:1.7
|
|
#
|
|
# Unified multi-stage Dockerfile for Next.js apps in this monorepo.
|
|
# Supports:
|
|
# - target=dev (hot-reload, expects bind-mounted repo)
|
|
# - target=runtime (production image using Next.js standalone output)
|
|
#
|
|
# Usage examples:
|
|
# - Build dev image for web: docker build --target dev --build-arg APP_SCOPE=web -t plane-web:dev .
|
|
# - Run dev (with compose): mount the repo into /repo and override command/ports as needed
|
|
# - Build prod image for web: docker build --target runtime --build-arg APP_SCOPE=web -t plane-web:latest .
|
|
#
|
|
# APP_SCOPE must be one of: web, space, admin
|
|
|
|
ARG NODE_VERSION=22-alpine
|
|
ARG TURBO_VERSION=2.5.6
|
|
|
|
# -----------------------------------------------------------------------------
|
|
# Base: Node + pnpm (corepack)
|
|
# -----------------------------------------------------------------------------
|
|
FROM node:${NODE_VERSION} AS base
|
|
|
|
ENV PNPM_HOME=/pnpm
|
|
ENV PATH=$PNPM_HOME:$PATH
|
|
RUN corepack enable && apk add --no-cache libc6-compat
|
|
|
|
# -----------------------------------------------------------------------------
|
|
# builder: prune workspace using turbo for the selected app scope
|
|
# -----------------------------------------------------------------------------
|
|
FROM base AS builder
|
|
ARG APP_SCOPE
|
|
WORKDIR /repo
|
|
|
|
# Full context is required for turbo prune
|
|
COPY . .
|
|
RUN pnpm add -g turbo@${TURBO_VERSION}
|
|
RUN turbo prune --scope=${APP_SCOPE} --docker
|
|
|
|
# -----------------------------------------------------------------------------
|
|
# installer: install deps (offline) and build the selected scope
|
|
# -----------------------------------------------------------------------------
|
|
FROM base AS installer
|
|
WORKDIR /repo
|
|
|
|
# Seed minimal files for reproducible installs and good caching
|
|
COPY .gitignore .gitignore
|
|
COPY --from=builder /repo/out/json/ .
|
|
COPY --from=builder /repo/out/pnpm-lock.yaml ./pnpm-lock.yaml
|
|
|
|
# Fetch dependencies into a cached store layer
|
|
RUN --mount=type=cache,id=pnpm-store,target=/pnpm/store \
|
|
pnpm fetch --store-dir=/pnpm/store
|
|
|
|
# Bring in only the pruned workspace for fast installs/builds
|
|
COPY --from=builder /repo/out/full/ .
|
|
COPY turbo.json turbo.json
|
|
|
|
# Offline, frozen lockfile install from cached store
|
|
RUN --mount=type=cache,id=pnpm-store,target=/pnpm/store \
|
|
pnpm install --offline --frozen-lockfile --store-dir=/pnpm/store
|
|
|
|
# Build-time environment (safe to pass through; only NEXT_PUBLIC_* are embedded)
|
|
# Keep parity with existing app Dockerfiles
|
|
ARG NEXT_PUBLIC_API_BASE_URL=""
|
|
ENV NEXT_PUBLIC_API_BASE_URL=$NEXT_PUBLIC_API_BASE_URL
|
|
|
|
ARG NEXT_PUBLIC_ADMIN_BASE_URL=""
|
|
ENV NEXT_PUBLIC_ADMIN_BASE_URL=$NEXT_PUBLIC_ADMIN_BASE_URL
|
|
|
|
ARG NEXT_PUBLIC_ADMIN_BASE_PATH="/god-mode"
|
|
ENV NEXT_PUBLIC_ADMIN_BASE_PATH=$NEXT_PUBLIC_ADMIN_BASE_PATH
|
|
|
|
ARG NEXT_PUBLIC_SPACE_BASE_URL=""
|
|
ENV NEXT_PUBLIC_SPACE_BASE_URL=$NEXT_PUBLIC_SPACE_BASE_URL
|
|
|
|
ARG NEXT_PUBLIC_SPACE_BASE_PATH="/spaces"
|
|
ENV NEXT_PUBLIC_SPACE_BASE_PATH=$NEXT_PUBLIC_SPACE_BASE_PATH
|
|
|
|
ARG NEXT_PUBLIC_WEB_BASE_URL=""
|
|
ENV NEXT_PUBLIC_WEB_BASE_URL=$NEXT_PUBLIC_WEB_BASE_URL
|
|
|
|
ENV NEXT_TELEMETRY_DISABLED=1
|
|
ENV TURBO_TELEMETRY_DISABLED=1
|
|
|
|
# Build only the selected scope
|
|
ARG APP_SCOPE
|
|
RUN pnpm turbo run build --filter=${APP_SCOPE}
|
|
|
|
# -----------------------------------------------------------------------------
|
|
# dev: for local development with hot reload (bind-mount the repo to /repo)
|
|
# -----------------------------------------------------------------------------
|
|
FROM base AS dev
|
|
WORKDIR /repo
|
|
|
|
# Helpful global tool for selective builds/dev
|
|
RUN pnpm add -g turbo@${TURBO_VERSION}
|
|
|
|
ENV NODE_ENV=development \
|
|
NEXT_TELEMETRY_DISABLED=1 \
|
|
TURBO_TELEMETRY_DISABLED=1
|
|
|
|
# Select which app to run in dev (web|space|admin)
|
|
ARG APP_SCOPE
|
|
ENV APP_SCOPE=${APP_SCOPE}
|
|
|
|
EXPOSE 3000
|
|
# Expect the source to be bind-mounted; install deps and start dev server
|
|
CMD ["sh", "-lc", "pnpm install && pnpm dev --filter=${APP_SCOPE}"]
|
|
|
|
# -----------------------------------------------------------------------------
|
|
# runtime: minimal Next.js standalone runner for the selected scope
|
|
# -----------------------------------------------------------------------------
|
|
FROM node:${NODE_VERSION} AS runtime
|
|
WORKDIR /app
|
|
|
|
ENV NODE_ENV=production \
|
|
NEXT_TELEMETRY_DISABLED=1 \
|
|
TURBO_TELEMETRY_DISABLED=1 \
|
|
HOSTNAME=0.0.0.0 \
|
|
PORT=3000
|
|
|
|
# Drop privileges
|
|
RUN addgroup -S -g 1001 nodejs \
|
|
&& adduser -S -u 1001 -G nodejs -h /home/nextjs -D nextjs \
|
|
&& mkdir -p /home/nextjs \
|
|
&& chown -R nextjs:nodejs /home/nextjs
|
|
USER nextjs
|
|
|
|
# Copy only the built output for the selected scope
|
|
ARG APP_SCOPE
|
|
ENV APP_SCOPE=${APP_SCOPE}
|
|
# Next.js standalone layout
|
|
COPY --from=installer /repo/apps/${APP_SCOPE}/.next/standalone ./
|
|
COPY --from=installer /repo/apps/${APP_SCOPE}/.next/static ./apps/${APP_SCOPE}/.next/static
|
|
COPY --from=installer /repo/apps/${APP_SCOPE}/public ./apps/${APP_SCOPE}/public
|
|
|
|
EXPOSE 3000
|
|
CMD ["sh", "-lc", "set -e; : \"${APP_SCOPE:?APP_SCOPE env is required}\"; SERVER=\"apps/${APP_SCOPE}/server.js\"; if [ ! -f \"$SERVER\" ]; then echo \"Error: $SERVER not found.\"; ls -la \"apps/${APP_SCOPE}\" || true; echo \"Known apps:\"; ls -1 apps || true; exit 1; fi; exec node \"$SERVER\""]
|