Skip to main content

Overview

Environment variables provide runtime configuration for your applications. Dokploy supports environment variables at multiple levels with inheritance and secret management.

Variable Hierarchy

Dokploy applies environment variables in this order (later overrides earlier):
1

Project Variables

Shared across all applications in a project:
# Set at project level
COMPANY_NAME=Acme Corp
DEFAULT_REGION=us-east-1
2

Environment Variables

Specific to an environment (dev, staging, prod):
# Set at environment level
ENV_NAME=production
LOG_LEVEL=info
3

Application Variables

Specific to individual applications:
# Set at application level
DATABASE_URL=postgresql://...
API_KEY=abc123
PORT=3000
Highest priority - overrides project and environment variables.

Configuration

Basic Variables

Set environment variables in the Dokploy UI or via API:
{
  "applicationId": "app-123",
  "env": "NODE_ENV=production\nPORT=3000\nDATABASE_URL=postgresql://user:pass@db:5432/myapp\nAPI_URL=https://api.example.com"
}
Format:
  • One variable per line
  • Use KEY=value format
  • No quotes needed around values
  • Empty lines are ignored

Multi-line Values

For values containing newlines:
# Private key example
PRIVATE_KEY="-----BEGIN RSA PRIVATE KEY-----
MIIEpAIBAAKCAQEA...
-----END RSA PRIVATE KEY-----"

# JSON configuration
CONFIG='{"key":"value","nested":{"data":"here"}}'

Special Characters

Escape special characters in values:
# Quotes in values
MESSAGE="He said \"Hello\""

# Dollar signs
PASSWORD="my\$ecret\$pass"

# Equals signs in value
CONNECTION="host=localhost;port=5432;password=pass=word"

Common Use Cases

Database Connection

Configure database connectivity:
DATABASE_URL=postgresql://user:password@postgres:5432/myapp
PGHOST=postgres
PGPORT=5432
PGDATABASE=myapp
PGUSER=user
PGPASSWORD=password
Use internal Docker network hostnames (e.g., postgres, redis) instead of localhost or IP addresses.

Framework-Specific

Configure popular frameworks:
NODE_ENV=production
PORT=3000

# Public variables (exposed to browser)
NEXT_PUBLIC_API_URL=https://api.example.com
NEXT_PUBLIC_SITE_URL=https://example.com

# Server-only variables
DATABASE_URL=postgresql://...
SECRET_KEY=your-secret-key
API_SECRET=internal-secret

Third-Party Services

Configure external service integrations:
# AWS
AWS_ACCESS_KEY_ID=AKIAIOSFODNN7EXAMPLE
AWS_SECRET_ACCESS_KEY=wJalrXUtnFEMI/K7MDENG/bPxRfiCYEXAMPLEKEY
AWS_DEFAULT_REGION=us-east-1
AWS_S3_BUCKET=my-bucket

# Stripe
STRIPE_PUBLIC_KEY=pk_live_xxxxx
STRIPE_SECRET_KEY=sk_live_xxxxx
STRIPE_WEBHOOK_SECRET=whsec_xxxxx

# SendGrid
SENDGRID_API_KEY=SG.xxxxx
SENDGRID_FROM_EMAIL=[email protected]

# Sentry
SENTRY_DSN=https://[email protected]/xxxxx
SENTRY_ENVIRONMENT=production

# Auth0
AUTH0_DOMAIN=myapp.auth0.com
AUTH0_CLIENT_ID=xxxxx
AUTH0_CLIENT_SECRET=xxxxx

Environment File Generation

Dokploy can create a .env file in your application container:
{
  "createEnvFile": true,  // Generate .env file
  "env": "NODE_ENV=production\nDATABASE_URL=postgresql://..."
}
When enabled:
  • Creates /app/.env in the container
  • Contains all environment variables
  • Useful for applications that read from .env files
  • Works alongside environment variables
Disable createEnvFile if your application doesn’t need it. Environment variables are always available regardless of this setting.

Build-Time vs Runtime

Build Arguments

Available during Docker build only:
{
  "buildArgs": "NODE_ENV=production\nAPI_URL=https://api.example.com"
}
Use for:
  • Compilation flags
  • Build-time URLs (Next.js NEXT_PUBLIC_*)
  • Version numbers
  • Build optimizations
Example in Dockerfile:
ARG NODE_ENV=production
ARG API_URL

# Available during build
RUN npm run build

# Not available at runtime

Environment Variables

Available at runtime only:
{
  "env": "DATABASE_URL=postgresql://...\nREDIS_URL=redis://..."
}
Use for:
  • Database connections
  • API keys
  • Runtime configuration
  • Feature flags
Most configuration should use environment variables, not build arguments. Build arguments are baked into the image.

Preview Deployment Variables

Set different variables for preview deployments:
{
  // Production variables
  "env": "NODE_ENV=production\nDATABASE_URL=postgresql://prod-db:5432/myapp",
  
  // Preview-specific variables
  "previewEnv": "NODE_ENV=preview\nDATABASE_URL=postgresql://preview-db:5432/myapp\nDEBUG=true",
  
  // Preview build arguments
  "previewBuildArgs": "BUILD_ENV=preview\nENABLE_SOURCEMAPS=true"
}
Preview variables override production variables in preview deployments.

Variable Interpolation

Reference other variables in values:
# Base URL
BASE_URL=https://example.com

# Reference in other variables
API_URL=${BASE_URL}/api
CDN_URL=${BASE_URL}/cdn
Variable interpolation is handled by your application or shell, not by Dokploy.

Secret Management

Marking as Secret

Mark sensitive variables as secrets in the UI:
  1. Add variable in Dokploy dashboard
  2. Click the lock icon next to the variable
  3. Value is encrypted and hidden

Build Secrets

For secrets needed during build:
{
  "buildSecrets": "NPM_TOKEN=npm_xxxxx\nGITHUB_TOKEN=ghp_xxxxx"
}
Use in Dockerfile:
# syntax=docker/dockerfile:1.4

RUN --mount=type=secret,id=NPM_TOKEN \
    echo "//registry.npmjs.org/:_authToken=$(cat /run/secrets/NPM_TOKEN)" > ~/.npmrc && \
    npm install && \
    rm ~/.npmrc
Build secrets are:
  • Not stored in image layers
  • Not available at runtime
  • More secure than build arguments

Best Practices

# .gitignore
.env
.env.local
.env.*.local
config/secrets.yml
*.pem
*.key
Always use environment variables for secrets, never hardcode in source.
# Generate secure random secrets
openssl rand -base64 32

# Example output
SECRET_KEY=8f7d9c6b5a4e3d2c1b0a9f8e7d6c5b4a3d2c1b0a9f8e7d6c5b4a
Update secrets periodically:
  1. Generate new secret
  2. Update in Dokploy
  3. Redeploy application
  4. Revoke old secret
Frequency: Every 90 days for high-security apps.
Use different secrets for each environment:
# Production
API_KEY=prod_xxxxx
DATABASE_URL=postgresql://prod-db/app

# Staging
API_KEY=staging_xxxxx
DATABASE_URL=postgresql://staging-db/app

# Development
API_KEY=dev_xxxxx
DATABASE_URL=postgresql://dev-db/app

Variable Validation

Validate required variables in your application:
// config.js
const requiredEnvVars = [
  'DATABASE_URL',
  'REDIS_URL',
  'SECRET_KEY'
];

for (const envVar of requiredEnvVars) {
  if (!process.env[envVar]) {
    throw new Error(`Missing required environment variable: ${envVar}`);
  }
}

module.exports = {
  databaseUrl: process.env.DATABASE_URL,
  redisUrl: process.env.REDIS_URL,
  secretKey: process.env.SECRET_KEY,
  port: parseInt(process.env.PORT || '3000', 10)
};

Accessing Variables

In Application Code

// Access via process.env
const dbUrl = process.env.DATABASE_URL;
const port = parseInt(process.env.PORT || '3000', 10);
const isProduction = process.env.NODE_ENV === 'production';

// Using dotenv package (optional)
require('dotenv').config();

In Docker Compose

Reference Dokploy environment variables in compose files:
services:
  app:
    image: myapp:latest
    environment:
      - DATABASE_URL=${DATABASE_URL}
      - REDIS_URL=${REDIS_URL}
      - NODE_ENV=production
    env_file:
      - .env  # If using env file generation

Dynamic Configuration

Update variables without redeploying:
# Update variables via API
curl -X POST https://your-domain.com/api/trpc/application.saveEnvironment \
  -H "x-api-key: your-api-key" \
  -H "Content-Type: application/json" \
  -d '{
    "applicationId": "app-123",
    "env": "NODE_ENV=production\nDATABASE_URL=postgresql://...\nNEW_FEATURE=enabled",
    "createEnvFile": true
  }'

# Redeploy to apply changes
curl -X POST https://your-domain.com/api/trpc/application.redeploy \
  -H "x-api-key: your-api-key" \
  -H "Content-Type: application/json" \
  -d '{
    "applicationId": "app-123",
    "title": "Update environment variables"
  }'
Variable changes require a redeploy to take effect. Use the redeploy endpoint (not deploy) to avoid rebuilding from source.

Troubleshooting

Symptoms: Application can’t read environment variableSolutions:
  1. Verify variable is set:
    docker exec <container-id> env | grep VARIABLE_NAME
    
  2. Check variable format:
    # Correct
    KEY=value
    
    # Incorrect
    export KEY=value  # Don't use export
    KEY = value       # No spaces around =
    
  3. Ensure application reads from correct source:
    // Node.js
    console.log(process.env.VARIABLE_NAME);
    
Symptoms: Variable has unexpected valueSolutions:
  1. Check variable hierarchy:
    • Application variables override environment variables
    • Environment variables override project variables
  2. Verify no hardcoded values:
    // Check source code for hardcoded values
    const apiUrl = process.env.API_URL || 'http://localhost:3000';
    
  3. Ensure redeploy after changes:
    # Variables only apply after redeploy
    curl -X POST .../application.redeploy
    
Symptoms: Variables with special characters breakSolutions:
  1. Escape special characters:
    # Dollar signs
    PASSWORD=my\$ecret
    
    # Quotes
    MESSAGE="He said \"Hello\""
    
  2. Use base64 for complex values:
    # Encode
    echo "complex$value" | base64
    # Result: Y29tcGxleCR2YWx1ZQ==
    
    # In environment
    ENCODED_VALUE=Y29tcGxleCR2YWx1ZQ==
    
    # Decode in application
    const decoded = Buffer.from(process.env.ENCODED_VALUE, 'base64').toString();
    
Symptoms: Build args are undefined at runtimeSolutions: Build arguments are build-time only. Use environment variables:
# Build-time (not available at runtime)
ARG API_URL

# Convert to environment variable
ENV API_URL=${API_URL}

# Now available at runtime
Or configure in Dokploy:
{
  "buildArgs": "API_URL=https://api.example.com",
  "env": "API_URL=https://api.example.com"  // For runtime
}

API Reference

Save Environment Variables

curl -X POST https://your-domain.com/api/trpc/application.saveEnvironment \
  -H "x-api-key: your-api-key" \
  -H "Content-Type: application/json" \
  -d '{
    "applicationId": "app-123",
    "env": "NODE_ENV=production\nDATABASE_URL=postgresql://...",
    "buildArgs": "NODE_ENV=production",
    "buildSecrets": "NPM_TOKEN=npm_xxxxx",
    "createEnvFile": true
  }'

Update Application

curl -X POST https://your-domain.com/api/trpc/application.update \
  -H "x-api-key: your-api-key" \
  -H "Content-Type: application/json" \
  -d '{
    "applicationId": "app-123",
    "env": "UPDATED_VAR=new-value"
  }'

Next Steps

Build Configuration

Configure build process and arguments

Git Integration

Automate deployments from Git

Security

Security best practices

Deployments Overview

Learn about deployment workflows

Build docs developers (and LLMs) love