Deploy project apps
What this page is for: When you deploy, you need the folder for each app, the command that builds it, and the command that starts it. The tables below are that cheat sheet. It is not a step-by-step hosting tutorial, and security and compliance stay on your side.
The accelerator lives in one Git repo with several apps under apps/. There are no sample Dockerfiles in the repo—you choose your own images and orchestration. Use a Node version that matches engines in the root package.json.
To build everything locally from a fresh clone: npm ci, then npm run build from the repo root (details in the README.md).
Docker and image size: If your build context is the whole repository, a normal npm ci installs packages for every workspace app (presentation, BFF, Storybook, Typedoc, shared packages, …). That is fine on a developer machine, but a production image that only runs the BFF or the storefront does not need the rest. turbo prune copies out a subset of the repo: one app (by package name) plus the workspace packages it actually depends on, so npm ci inside the image stays smaller. Each app table below includes the npx turbo prune … --docker line that matches that app; Turborepo’s Docker guide shows how to plug prune into a typical multi-stage Dockerfile (it is the upstream recipe, not something defined in this site repo).
Environment variables at deploy time
Environment variables · .env.example
| Variable | Build (Next) | Run (Next) | Run (BFF) | Secret |
|---|---|---|---|---|
NEXT_PUBLIC_BFF_EXTERNAL_URL | Yes | Yes | No | No |
NEXT_BFF_INTERNAL_URL | No | Yes | No | Yes |
FRONTEND_URL | No | No | Yes | No |
COMMERCETOOLS_CLIENT_ID | No | No | Yes | Yes |
COMMERCETOOLS_CLIENT_SECRET | No | No | Yes | Yes |
COMMERCETOOLS_PROJECT_KEY | No | No | Yes | No |
COMMERCETOOLS_API_URL | No | No | Yes | No |
COMMERCETOOLS_AUTH_URL | No | No | Yes | No |
CONTENTFUL_ACCESS_TOKEN | No | No | Yes | Yes |
CONTENTFUL_PREVIEW_ACCESS_TOKEN | No | No | Yes | Yes |
CONTENTFUL_SPACE | No | No | Yes | No |
CONTENTFUL_ENVIRONMENT | No | No | Yes | No |
NEXT_DRAFT_MODE_SECRET | No | Yes | Yes | Yes |
CONTENTFUL_MANAGEMENT_ACCESS_TOKEN | No | No | No | Yes |
JWT_ENCRYPTION_KEY | No | No | Yes | Yes |
JWT_SIGNING_KEY | No | No | Yes | Yes |
CSRF_TOKEN_ENCRYPTION_KEY | No | No | Yes | Yes |
CSRF_TOKEN_SIGNING_KEY | No | No | Yes | Yes |
LOG_LEVEL, LOG_PRETTY_PRINT | No | Yes | Yes | No |
BFF_RATE_LIMIT_ENABLED, BFF_RATE_LIMIT_TTL, BFF_RATE_LIMIT_LIMIT, BFF_RATE_LIMIT_SECURE_TTL, BFF_RATE_LIMIT_SECURE_LIMIT | No | No | Yes | No |
Presentation app
| Item | Value |
|---|---|
| App path | apps/presentation/ |
| Package name | @apps/presentation |
| Turborepo command | npx turbo prune @apps/presentation --docker |
| Build command | npx turbo run build --filter=@apps/presentation |
| Run command | node apps/presentation/server.js |
Next.js uses output: 'standalone'. Copy standalone and static output per Next.js standalone output. Deploy-time URLs: apps/presentation/README.md.
Presentation — Build: files to copy
From paths are relative to the monorepo root in the image (the tree that still has apps/ and package.json after prune/build). To paths are relative to the runtime WORKDIR where node apps/presentation/server.js runs (often the standalone output root).
| From | To |
|---|---|
apps/presentation/public/ | ./apps/presentation/public/ |
apps/presentation/.next/standalone/ | ./ |
apps/presentation/.next/static/ | ./apps/presentation/.next/static/ |
Backend for Frontend (BFF)
| Item | Value |
|---|---|
| App path | apps/bff/ |
| Package name | @apps/bff |
| Turborepo command | npx turbo prune @apps/bff --docker |
| Build command | npx turbo run build --filter=@apps/bff |
| Run command | node apps/bff/dist/main.js |
Routing and data sources: apps/bff/README.md. Integrations overview: integrations/README.md.
BFF — Build: files to copy
From / To relative to monorepo root; WORKDIR = that root for node apps/bff/dist/main.js. Ship the full pruned tree after install + build (not only apps/bff/dist/).
| From | To |
|---|---|
Pruned monorepo after npm ci and build | ./ |
Storybook
| Item | Value |
|---|---|
| App path | apps/storybook/ |
| Package name | @apps/storybook |
| Turborepo command | npx turbo prune @apps/storybook @apps/presentation --docker |
| Build command | npx turbo run build --filter=@apps/storybook |
| Serve | Static site from apps/storybook/storybook-static/ (use your own static host or reverse proxy) |
Stories depend on @apps/presentation, so the prune command includes both packages.
Storybook — Build: files to copy
If you need both site root and a /storybook/ base path, mirror the static output twice (same From relative to monorepo root):
| From | To |
|---|---|
apps/storybook/storybook-static/ | ./ |
apps/storybook/storybook-static/ | ./storybook/ |
Typedoc
| Item | Value |
|---|---|
| App path | apps/typedoc/ |
| Package name | @apps/typedoc |
| Turborepo command | npx turbo prune @apps/typedoc --docker |
| Build command | npx turbo run build --filter=@apps/typedoc |
| Serve | Static site from apps/typedoc/docs/ (use your own static host or reverse proxy) |
Typedoc — Build: files to copy
When serving under /typedoc/ as well as root (paths From relative to monorepo root):
| From | To |
|---|---|
apps/typedoc/docs/ | ./ |
apps/typedoc/docs/ | ./typedoc/ |
Related
- How to setup SHOPin — Local setup, env reference,
npm run dev/start:local - Integration setup — Data sources and integration packages