I have a pnpm workspace application which I'm trying to Dockerize. I get to build the images and containers, but the apps won't run inside it.
Basic structure is:
omnimart/
├── apps/
│ ├── backend/ → Express.js REST API
└── Dockerfile → Backend Dockerfile
│ └── frontend/ → Next.js 15 App Router
└── Dockerfile → Frontend Dockerfile
| └── orders.json → Orders JSON database
├── packages/
│ └── shared/ → Shared types, constants, schemas, and utils
├── package.json → Workspace root
├── tsconfig.json → Root TypeScript config
├── tsconfig.build.json → Root TypeScript build config
├── README.md
├── .dockerignore → Files for Docker ignore
└── docker-compose.yml → Docker orquestration
The container runs and builds and get online, then I get:
Error: Cannot find module '/app/apps/backend/dist/server.js' and also [email protected] start /app/apps/frontend next start next: not found.
I'm not understanding what I'm doing wrong here. Can anyone help me Dockerize this?
Dockerfile frontend:
# ---- Builder ----
FROM node:20-slim AS builder
WORKDIR /app
RUN npm install -g pnpm
# Copy monorepo files
COPY package.json pnpm-lock.yaml pnpm-workspace.yaml ./
COPY apps/frontend/package.json ./apps/frontend/
COPY apps/backend/package.json ./apps/backend/
COPY tsconfig.json tsconfig.build.json ./
# Install dependencies with cache
RUN pnpm install --frozen-lockfile
# Copy source
COPY . .
# Build Next.js app
RUN pnpm --filter omnimart build
# ---- Runner ----
FROM node:20-slim AS runner
WORKDIR /app/apps/frontend
RUN npm install -g pnpm
ENV NODE_ENV=production
# Copy production files
COPY --from=builder /app/apps/frontend/package.json ./
COPY --from=builder /app/node_modules ./node_modules
COPY --from=builder /app/apps/frontend/.next ./.next
COPY --from=builder /app/apps/frontend/next.config.ts ./next.config.ts
EXPOSE 3000
CMD ["pnpm", "start"]
Dockerfile backend:
# ---- Builder ----
FROM node:20-slim AS builder
WORKDIR /app
RUN npm install -g pnpm
# Copy monorepo files
COPY package.json pnpm-lock.yaml pnpm-workspace.yaml ./
COPY apps/backend/package.json ./apps/backend/
COPY apps/frontend/package.json ./apps/frontend/
COPY tsconfig.json tsconfig.build.json ./
# Install dependencies with cache
RUN pnpm install --frozen-lockfile
# Copy the entire monorepo
COPY . .
# Build backend
RUN pnpm --filter backend run build
# ---- Runner ----
FROM node:20-slim AS runner
WORKDIR /app/apps/backend
RUN npm install -g pnpm
ENV NODE_ENV=production
# Copy production files
COPY --from=builder /app/apps/backend/package.json ./
COPY --from=builder /app/node_modules ./node_modules
COPY --from=builder /app/apps/backend/dist ./dist
EXPOSE 3333
CMD ["node", "dist/server.js"]
docker-compose:
version: '3.9'
services:
backend:
build:
context: .
dockerfile: apps/backend/Dockerfile
ports:
- "3333:3333"
networks:
- omnimart
environment:
- NODE_ENV=production
frontend:
build:
context: .
dockerfile: apps/frontend/Dockerfile
ports:
- "3000:3000"
networks:
- omnimart
environment:
- NODE_ENV=production
depends_on:
- backend
networks:
omnimart:
driver: bridge
dockerignore:
# Git
.git
.gitignore
# Docker
.dockerignore
Dockerfile*
# Node / pnpm
node_modules
apps/**/node_modules
packages/**/node_modules
.pnpm-store/
# Build artifacts
.next
dist
# Env files
.env
.env*
*.log
# IDE config
.vscode