Docker Frontend Configuration#
The Dify web frontend (langgenius/dify-web) uses a multi-stage Docker build that produces two parallel runtime targets — a Next.js standalone server and a Vite-based vinext server — and defers all environment configuration to container startup via an entrypoint script.
Multi-Stage Build#
web/Dockerfile defines four stages:
| Stage | Purpose |
|---|---|
base | Node 22 + Alpine, sets pnpm home, accepts NEXT_PUBLIC_BASE_PATH build arg |
packages | Installs workspace dependencies with pnpm install --frozen-lockfile |
builder | Runs pnpm build && pnpm build:vinext to produce both Next.js and vinext output |
production | Copies compiled outputs to /app/targets/next and /app/targets/vinext |
The builder stage sets NODE_OPTIONS="--max-old-space-size=4096" to handle memory-intensive compilation. The Next.js build output lands in web/.next/standalone (copied to targets/next/), while the vinext build lands in web/dist/standalone (copied to targets/vinext/) . Next.js is configured with output: 'standalone' in next.config.ts.
The production stage creates a non-root dify user (uid 1001) and all app files are owned by that user. Port 3000 is exposed and the ENTRYPOINT is set to entrypoint.sh .
The NEXT_PUBLIC_BASE_PATH is the only build-time variable baked in at image creation — all other variables are injected at runtime .
Runtime Environment Injection via Entrypoint#
Because Next.js bakes NEXT_PUBLIC_* variables into the JS bundle at build time, Dify works around this by using web/docker/entrypoint.sh to set these variables as process-level environment variables before the Node server starts. The running Next.js server then reads them server-side and exposes them to the client as needed — enabling configuration changes without rebuilding the image.
The entrypoint maps Docker-native env vars to their NEXT_PUBLIC_* equivalents:
CONSOLE_API_URL → NEXT_PUBLIC_API_PREFIX (appended with /console/api)
APP_API_URL → NEXT_PUBLIC_PUBLIC_API_PREFIX (appended with /api)
MARKETPLACE_API_URL → NEXT_PUBLIC_MARKETPLACE_API_PREFIX
DEPLOY_ENV → NEXT_PUBLIC_DEPLOY_ENV
EDITION → NEXT_PUBLIC_EDITION
This means operators set simple Docker-style variables (e.g., CONSOLE_API_URL=https://api.example.com) and the entrypoint handles constructing the full URL prefixes.
For several variables, the entrypoint uses shell fallback syntax (${VAR:-${FALLBACK}}) so that either the NEXT_PUBLIC_* form or the plain form can be used — useful for cloud/self-hosted feature flags like MARKETPLACE_ENABLED, ALLOW_REGISTER, etc.
Runtime Target Selection#
At the end of entrypoint.sh, a single conditional selects the server to start:
- If
EXPERIMENTAL_ENABLE_VINEXT=true→ runsnode /app/targets/vinext/server.js - Otherwise (default) → runs
node /app/targets/next/web/server.js
This allows toggling between the Next.js and vinext runtimes at container startup with no image rebuild. The default in docker-compose.yaml is EXPERIMENTAL_ENABLE_VINEXT: ${EXPERIMENTAL_ENABLE_VINEXT:-false} .
docker-compose.yaml Configuration#
The web service in docker/docker-compose.yaml passes environment variables directly under environment:, using ${VAR:-default} syntax. Key variables:
| Variable | Default | Purpose |
|---|---|---|
CONSOLE_API_URL | "" | Backend API base URL |
APP_API_URL | "" | Web App API base URL |
NEXT_PUBLIC_SOCKET_URL | ws://localhost | WebSocket URL |
MARKETPLACE_API_URL | https://marketplace.dify.ai | Plugin marketplace API |
EXPERIMENTAL_ENABLE_VINEXT | false | Toggle vinext runtime |
TEXT_GENERATION_TIMEOUT_MS | 60000 | Streaming timeout (ms) |
The compose file is auto-generated from a template — modify docker-compose-template.yaml or the relevant .env.example file rather than editing it directly.
Reference Files#
| File | Purpose |
|---|---|
web/Dockerfile | Multi-stage build definition |
web/docker/entrypoint.sh | Runtime env injection + server startup |
web/next.config.ts | Next.js config (standalone output, basePath) |
web/.env.example | Full list of configurable variables with descriptions |
docker/docker-compose.yaml | Web service container definition |