Last verified: April 2026 8 Services Explained

Dify Docker Setup 2026 — Step-by-Step Installation Guide

Everything you need to know about Dify's Docker architecture — from what each container does to production-hardening your deployment with custom configurations.

Dify's Docker Architecture

Dify's docker-compose.yaml spins up eight services. Understanding what each does helps you configure, troubleshoot and scale your deployment.

nginx Reverse proxy / web server

Routes incoming HTTP requests to the correct internal service (web UI or API). This is the only container that needs to be publicly accessible.

~50 MB
api Dify API server

The core Python/Flask backend. Handles all business logic, LLM calls, RAG pipeline execution and REST API endpoints.

~300 MB
worker Celery background worker

Processes async tasks: document indexing, dataset imports, long-running LLM chains. Shares code with the API container.

~300 MB
web Next.js frontend

The React-based user interface served as a Next.js app. Communicates with the API container.

~150 MB
db PostgreSQL database

Stores all persistent data: apps, conversations, datasets metadata, users and API keys.

~100 MB
redis Cache & message broker

Caches frequent queries, stores Celery task queue for the worker, and handles rate-limiting data.

~30 MB
weaviate Vector database

Stores document embeddings for RAG knowledge bases. The heaviest memory consumer. Can be replaced with pgvector or Qdrant.

~500 MB
sandbox Code execution sandbox

Isolated container for running user-defined code nodes in Dify workflows. Runs with restricted permissions.

~100 MB

Total RAM baseline: ~1.5 GB just for idle containers. On a 4GB server, this leaves ~2.5 GB for the OS and actual workloads. For production, 8GB RAM is recommended.

Environment Variables Guide

All Dify configuration lives in dify/docker/.env. Copy from .env.example and customize these key settings:

Security (Required)

# Generate with: openssl rand -base64 42
SECRET_KEY=your-very-long-random-secret-key

# Encryption key for sensitive stored data
# Generate with: openssl rand -hex 16
ENCRYPT_IV=your-16-char-hex-value

Database Settings

# PostgreSQL settings (internal Docker network)
DB_USERNAME=postgres
DB_PASSWORD=change-this-strong-password
DB_HOST=db
DB_PORT=5432
DB_DATABASE=dify

# Redis settings
REDIS_HOST=redis
REDIS_PORT=6379
REDIS_PASSWORD=change-this-redis-password
REDIS_DB=0

URL & CORS Settings

# Your domain (no trailing slash)
CONSOLE_URL=https://your-domain.com
APP_URL=https://your-domain.com
SERVICE_API_URL=https://your-domain.com

# CORS origins (comma-separated)
CONSOLE_CORS_ALLOW_ORIGINS=https://your-domain.com
WEB_API_CORS_ALLOW_ORIGINS=https://your-domain.com

File Storage

# Default: local filesystem (stored in ./volumes/app/storage)
STORAGE_TYPE=local

# For S3-compatible storage (recommended for production)
# STORAGE_TYPE=s3
# S3_ENDPOINT=https://s3.amazonaws.com
# S3_BUCKET_NAME=my-dify-bucket
# S3_ACCESS_KEY=your-access-key
# S3_SECRET_KEY=your-secret-key
# S3_REGION=us-east-1

LLM API Keys (optional at setup)

# You can also configure these in the Dify web UI
# These .env settings pre-configure providers on first launch

OPENAI_API_KEY=sk-your-openai-key
ANTHROPIC_API_KEY=sk-ant-your-key
GOOGLE_API_KEY=your-gemini-key

# For Ollama (local LLMs)
# Configure in UI: Settings → Model Provider → Ollama

Custom Configurations

Custom Port Mapping

If port 80 is taken, change the host port Dify's Nginx binds to by editing .env:

# Change Nginx container's host port
EXPOSE_NGINX_PORT=8080
EXPOSE_NGINX_SSL_PORT=8443

Disable Weaviate (use pgvector instead)

Weaviate uses ~500MB RAM. On low-memory servers, switch to pgvector (already available in the PostgreSQL container):

# In .env — switch vector store to pgvector
VECTOR_STORE=pgvector

# Then restart without Weaviate
docker compose up -d --scale weaviate=0

Enable GPU Support

To pass through an NVIDIA GPU (for local embedding models), add the GPU runtime to your docker-compose.override.yaml:

services:
  api:
    deploy:
      resources:
        reservations:
          devices:
            - driver: nvidia
              count: all
              capabilities: [gpu]

See the GPU hosting guide for full setup instructions.

Common Commands

Start all services docker compose up -d
Stop all services docker compose down
Restart a single service docker compose restart api
View logs (follow) docker compose logs -f api worker
Open shell in API container docker compose exec api bash
Check container health docker compose ps
Resource usage per container docker stats
Remove stopped containers docker compose down --remove-orphans
Pull latest images docker compose pull
Rebuild a service docker compose up -d --build api

Troubleshooting

Container keeps restarting / CrashLoopBackOff

Check logs: docker compose logs api. Usually caused by wrong SECRET_KEY format or a missing required environment variable. Ensure SECRET_KEY is at least 32 characters.

Out of memory — containers killed by OOM killer

Add swap space and/or upgrade to a larger server. Run dmesg | grep -i "killed process" to confirm OOM kills. The weaviate container is usually the culprit — consider switching to pgvector.

Database connection errors

Ensure the DB container is healthy before the API starts: docker compose ps db. The API has a depends_on with health check, but on slow servers the DB may not finish initializing in time. Try docker compose restart api.

Permission denied errors on ./volumes

The storage volume directory needs correct permissions. Run: sudo chown -R 1000:1000 ./volumes from the dify/docker directory.

Production Hardening

Before going live, apply these security measures:

1. Change all default passwords

Set strong unique values for DB_PASSWORD, REDIS_PASSWORD, and especially SECRET_KEY. Never use the .env.example defaults in production.

2. Secure your .env file

chmod 600 dify/docker/.env
# Never commit .env to version control

3. Enable automated backups

Add to crontab (crontab -e):

0 3 * * * cd ~/dify/docker && docker compose exec -T db pg_dump -U postgres dify > ~/backups/dify_$(date +\%Y\%m\%d).sql

4. Use S3 for file storage

Switch STORAGE_TYPE=s3 so uploaded documents are stored separately from your server and survive container rebuilds.

Common Mistakes and How to Avoid Them

1. Incorrect Environment Variable Configuration

Many users overlook the necessity of properly configuring the environment variables in dify/docker/.env. This often leads to errors like:

ERROR: Database connection failed

Ensure that variables such as DB_PASSWORD and REDIS_PASSWORD are set correctly and match the credentials expected by the services.

2. Not Allocating Sufficient Resources

Deploying Dify on a server with less than 8GB of RAM can lead to performance issues. Symptoms include:

ERROR: Out of memory

Always provision at least 8GB of RAM to ensure smooth operation, especially under load.

3. Ignoring Docker Network Configuration

Failing to set the correct Docker network can cause service communication failures. You might see:

ERROR: Service 'api' failed to connect to 'db'

Verify that all services are on the same network defined in docker-compose.yaml.

4. Misconfigured Ports

Using the same ports for multiple services can lead to binding errors like:

ERROR: Port 80 is already in use

Check the ports section in docker-compose.yaml and ensure each service uses unique ports.

Advanced Configuration

To enhance the reliability and performance of your Dify deployment, consider the following configurations:

1. Enable Health Checks

Adding health checks ensures that Docker can restart unhealthy containers automatically. Update your docker-compose.yaml:

services:
  api:
    healthcheck:
      test: ["CMD", "curl", "-f", "http://localhost:8000/health"]
      interval: 30s
      timeout: 10s
      retries: 3

2. Configure Resource Limits

Set resource limits to prevent any single container from consuming all available resources:

services:
  api:
    deploy:
      resources:
        limits:
          cpus: '0.5'
          memory: 512M

3. Use Docker Volumes for Persistent Data

To ensure data persistence, mount volumes for your database and Redis services:

services:
  db:
    volumes:
      - db_data:/var/lib/postgresql/data
  redis:
    volumes:
      - redis_data:/data