Docker

Multi-stage Dockerfile for container deployments.

Overview

Each example app includes a production Dockerfile with a two-stage build. The pattern is the same for any Foundry project.

Dockerfile

# Stage 1: Build
FROM node:22-slim AS builder
RUN corepack enable && corepack prepare pnpm@latest --activate

WORKDIR /app
COPY package.json pnpm-lock.yaml ./
RUN pnpm install --frozen-lockfile

COPY . .
RUN pnpm build

# Stage 2: Run
FROM node:22-slim
WORKDIR /app

COPY --from=builder /app/.output .output

ENV HOST=0.0.0.0
ENV PORT=3000
EXPOSE 3000

CMD ["node", ".output/server/index.mjs"]

Build and Run

docker build -t my-project .
docker run -p 3000:3000 \
  -e NUXT_PUBLIC_SITE_URL=https://mysite.com \
  -e NUXT_WEBHOOK_URL=https://discord.com/api/webhooks/... \
  my-project

Environment Variables

Pass environment variables at runtime with -e flags or a .env file:

docker run -p 3000:3000 --env-file .env my-project

Monorepo Builds

If deploying from the Foundry monorepo (not a standalone project), use pnpm's --filter flag:

# Install only the app's dependencies
RUN pnpm install --frozen-lockfile --filter @foundry/web...

# Build only the app
RUN pnpm --filter @foundry/web build

The example Dockerfiles in examples/foundry/Dockerfile and examples/astronera/Dockerfile demonstrate this pattern.

Optimization

The Dockerfiles use build cache mounts for node_modules and Nuxt cache:

RUN --mount=type=cache,target=/root/.local/share/pnpm/store \
    --mount=type=cache,target=/app/node_modules/.cache \
    pnpm install --frozen-lockfile

This significantly speeds up rebuilds when dependencies haven't changed.