Runtime environment variable resolution for Next.js standalone/Docker deployments. Allows the same Docker image to work across multiple environments.
npm install next-standalone-env> Runtime environment variable resolution for Next.js standalone/Docker deployments


When Next.js builds in standalone mode (used for Docker deployments), environment variables like NEXTAUTH_URL are baked in at build time. This means:
- ❌ You need separate Docker images for dev, staging, and production
- ❌ You can't use the same image across environments
- ❌ OAuth callbacks fail when URLs don't match
- ❌ You have to rebuild for every environment change
next-standalone-env patches environment variables at runtime when your container starts, allowing:
- ✅ One Docker image for all environments
- ✅ Runtime configuration via APP_ENV
- ✅ Proper OAuth redirects in every environment
- ✅ Build once, deploy everywhere
``bash`
npm install next-standalone-envor
yarn add next-standalone-envor
pnpm add next-standalone-env
Replace your Next.js standalone server with our runtime-aware server:
`dockerfileIn your Dockerfile
FROM node:20-alpine
Set your environment:
`bash
Development
docker run -e APP_ENV=development your-imageProduction
docker run -e APP_ENV=production your-imageStaging
docker run -e APP_ENV=staging your-image
`$3
Create
runtime-env.config.js in your project root:`javascript
module.exports = {
environments: {
production: {
vars: {
NEXTAUTH_URL: 'https://app.example.com',
NEXT_PUBLIC_API_URL: 'https://api.example.com'
}
},
development: {
vars: {
NEXTAUTH_URL: 'https://dev.example.com',
NEXT_PUBLIC_API_URL: 'https://api-dev.example.com'
}
},
staging: {
vars: {
NEXTAUTH_URL: 'https://staging.example.com',
NEXT_PUBLIC_API_URL: 'https://api-staging.example.com'
}
}
},
// Variables that can be overridden at runtime
variables: ['NEXTAUTH_URL', 'NEXT_PUBLIC_API_URL', 'DATABASE_URL'],
// The env var that determines which environment to use
envSelector: 'APP_ENV', // or 'NODE_ENV', 'ENVIRONMENT', etc.
// Enable debug logging
debug: true
};
`$3
Your NextAuth configuration works seamlessly:
`javascript
// app/api/auth/[...nextauth]/route.js
import NextAuth from 'next-auth';
import AzureADProvider from 'next-auth/providers/azure-ad';const handler = NextAuth({
providers: [
AzureADProvider({
clientId: process.env.AZURE_AD_CLIENT_ID,
clientSecret: process.env.AZURE_AD_CLIENT_SECRET,
tenantId: process.env.AZURE_AD_TENANT_ID,
}),
],
// NEXTAUTH_URL is now set correctly at runtime!
});
export { handler as GET, handler as POST };
`Advanced Usage
$3
`javascript
import { patchProcessEnv } from 'next-standalone-env';// In your custom server
patchProcessEnv({
environments: {
production: {
vars: { NEXTAUTH_URL: 'https://app.example.com' }
},
development: {
vars: { NEXTAUTH_URL: 'https://dev.example.com' }
}
},
variables: ['NEXTAUTH_URL'],
debug: true
});
// Then start Next.js
const app = next({ / ... / });
`$3
`javascript
// next.config.js
const { withRuntimeEnv } = require('next-standalone-env');const nextConfig = {
// your config
};
module.exports = withRuntimeEnv(nextConfig, {
environments: { / ... / },
variables: ['NEXTAUTH_URL', 'NEXT_PUBLIC_API_URL']
});
`$3
Override any variable at runtime with the
RUNTIME_ prefix:`bash
Override NEXTAUTH_URL regardless of APP_ENV
docker run \
-e APP_ENV=production \
-e RUNTIME_NEXTAUTH_URL=https://custom.example.com \
your-image
`Environment Variable Priority
1.
RUNTIME_* prefixed variables (highest priority)
2. Environment-specific configuration based on APP_ENV
3. Existing environment variables
4. DefaultsDocker Example
`dockerfile
Build stage
FROM node:20-alpine AS builderWORKDIR /app
Copy package files
COPY package*.json ./
RUN npm ciCopy source
COPY . .Build Next.js
RUN npm run buildProduction stage
FROM node:20-alpine AS runnerWORKDIR /app
Install next-standalone-env
RUN npm install next-standalone-envCopy built application
COPY --from=builder /app/.next/standalone ./
COPY --from=builder /app/.next/static ./.next/static
COPY --from=builder /app/public ./publicCopy runtime config (optional)
COPY runtime-env.config.js ./Use runtime-aware server
CMD ["npx", "next-standalone-env/server"]
`Kubernetes Example
`yaml
apiVersion: apps/v1
kind: Deployment
metadata:
name: nextjs-app
spec:
template:
spec:
containers:
- name: app
image: your-image:latest
env:
- name: APP_ENV
value: "development" # or "production", "staging"
- name: NODE_ENV
value: "production" # Always production for Next.js
# Secrets still work normally
- name: AZURE_AD_CLIENT_SECRET
valueFrom:
secretKeyRef:
name: auth-secrets
key: client-secret
`How It Works
1. Build Time: Next.js builds with default/production values
2. Container Start: Our server runs before Next.js
3. Runtime Patch: Environment variables are updated based on
APP_ENV
4. Next.js Start: Next.js starts with the correct runtime valuesCommon Use Cases
$3
`javascript
{
environments: {
'customer-a': {
vars: {
NEXTAUTH_URL: 'https://a.example.com',
TENANT_ID: 'customer-a'
}
},
'customer-b': {
vars: {
NEXTAUTH_URL: 'https://b.example.com',
TENANT_ID: 'customer-b'
}
}
}
}
`$3
`javascript
{
environments: {
'production': {
vars: {
FEATURE_NEW_UI: 'false'
}
},
'canary': {
vars: {
FEATURE_NEW_UI: 'true'
}
}
}
}
`$3
`javascript
{
environments: {
'us-east': {
vars: {
API_ENDPOINT: 'https://us-east.api.example.com',
REGION: 'us-east-1'
}
},
'eu-west': {
vars: {
API_ENDPOINT: 'https://eu-west.api.example.com',
REGION: 'eu-west-1'
}
}
}
}
`Debugging
Enable debug mode to see what's happening:
`bash
docker run -e DEBUG=true -e APP_ENV=development your-image
`Output:
`
[next-standalone-env] Starting server with environment: development
[next-standalone-env] Setting NEXTAUTH_URL=https://dev.example.com (was: https://prod.example.com)
[next-standalone-env] Server ready on http://0.0.0.0:3000
[next-standalone-env] NextAuth URL: https://dev.example.com
[next-standalone-env] Environment: development
`Migration Guide
$3
Before:
`dockerfile
Dockerfile.dev
ENV NEXTAUTH_URL=https://dev.example.com
... build ...
Dockerfile.prod
ENV NEXTAUTH_URL=https://prod.example.com
... build ...
`After:
`dockerfile
Single Dockerfile
No environment-specific variables!
... build ...
CMD ["npx", "next-standalone-env/server"]
`$3
Before:
`bash
docker build --build-arg NEXTAUTH_URL=https://dev.example.com -t app:dev .
docker build --build-arg NEXTAUTH_URL=https://prod.example.com -t app:prod .
`After:
`bash
docker build -t app:latest .
docker run -e APP_ENV=development app:latest
docker run -e APP_ENV=production app:latest
`FAQ
$3
No, this is specifically for self-hosted Next.js deployments using standalone output mode.$3
It works with any environment variable. However, NEXT_PUBLIC_*` variables that are inlined during build may still need rebuilding for changes.Contributions welcome! Please feel free to submit a Pull Request.
MIT © Vinnie Espo
- next-bun-docker - Webpack fixes for Bun + Docker + Next.js
If this package helps you, please consider:
- ⭐ Starring the repo
- 🐛 Reporting issues
- 🔀 Contributing improvements
- 📢 Sharing with others who might need it