Implementation:Langgenius Dify Env Sync Script
| Knowledge Sources | Dify |
|---|---|
| Domains | DevOps, Deployment, Migration, Configuration |
| Last Updated | 2026-02-12 00:00 GMT |
Overview
Concrete tool for synchronizing an existing Dify .env file with the latest .env.example template during version upgrades, and for applying database schema migrations through Flask-Migrate, provided by docker/dify-env-sync.sh and api/app_factory.py:create_migrations_app().
Description
The dify-env-sync.sh script (located at docker/dify-env-sync.sh) orchestrates a safe update of the .env file. Its main() function (lines 436-460) calls six subroutines in sequence:
check_files()-- Verifies.env.exampleexists; creates.envfrom template if missing.create_backup()-- Creates a timestamped backup atenv-backup/.env.backup_YYYYMMDD_HHMMSS.detect_differences()-- Uses AWK to efficiently compare all key-value pairs between.envand.env.example, reporting changes with analysis (numeric increase/decrease, boolean flip, URL change, string length change).detect_removed_variables()-- Usescommon sorted key lists to find variables present in.envbut removed from.env.example.sync_env_file()-- Rebuilds.envusing.env.exampleas the structural template, preserving customized values while adding new variables with their defaults.show_statistics()-- Displays the total number of environment variables in both files.
For database migrations, the create_migrations_app() function in api/app_factory.py (lines 152-160) creates a minimal Flask app:
def create_migrations_app() -> DifyApp:
app = create_flask_app_with_configs()
from extensions import ext_database, ext_migrate
# Initialize only required extensions
ext_database.init_app(app)
ext_migrate.init_app(app)
return app
This lightweight app avoids initializing Redis, Celery, or other non-essential extensions, making the migration step fast and dependency-minimal.
Usage
Run dify-env-sync.sh from the docker/ directory after pulling new Dify source or images. Database migrations run automatically when the API container starts (controlled by MIGRATION_ENABLED=true).
Code Reference
Source Location:
docker/dify-env-sync.sh, lines 436-460 (main function)api/app_factory.py, lines 152-160 (create_migrations_app)
Signature (env sync script):
#!/bin/bash
set -eo pipefail
main() {
log_info "=== Dify Environment Variables Synchronization Script ==="
log_info "Execution started: $(date)"
# Check prerequisites
check_files
# Create backup
create_backup
# Detect differences
detect_differences
# Detect removed variables (before sync)
detect_removed_variables
# Synchronize environment file
sync_env_file
# Show statistics
show_statistics
log_success "=== Synchronization process completed successfully ==="
log_info "Execution finished: $(date)"
}
# Execute main function only when script is run directly
if [[ "${BASH_SOURCE[0]}" == "${0}" ]]; then
main "$@"
fi
Signature (migrations app):
def create_migrations_app() -> DifyApp:
app = create_flask_app_with_configs()
ext_database.init_app(app)
ext_migrate.init_app(app)
return app
Import statement:
from app_factory import create_migrations_app
I/O Contract
Inputs (Env Sync Script)
| Parameter | Type | Required | Default | Description |
|---|---|---|---|---|
| .env.example | File | Yes | docker/.env.example | The upstream template with all current environment variables |
| .env | File | No | Created from template if missing | The operator's current environment configuration |
| Working directory | Path | Yes | docker/ | Script must be run from the docker directory |
Outputs (Env Sync Script)
| Output | Type | Description |
|---|---|---|
| Updated .env | File | Synchronized file with new variables added and custom values preserved |
| Backup file | File | Timestamped copy at env-backup/.env.backup_YYYYMMDD_HHMMSS
|
| Console report | stdout/stderr | Colored output showing differences, removed variables, and statistics |
Inputs (Migrations App)
| Parameter | Type | Required | Default | Description |
|---|---|---|---|---|
| DB_HOST | string | No | db_postgres | Database hostname |
| DB_USERNAME | string | No | postgres | Database username |
| DB_PASSWORD | string | No | difyai123456 | Database password |
| DB_DATABASE | string | No | dify | Database name |
| MIGRATION_ENABLED | boolean | No | true | Controls whether migrations run at API startup |
Outputs (Migrations App)
| Output | Type | Description |
|---|---|---|
| DifyApp | Application instance | Minimal Flask app with database and migration extensions only |
| Applied migrations | Database DDL | Alembic revisions applied to bring the schema to the latest version |
Usage Examples
Run environment sync before upgrading:
cd docker
# Pull latest code/images
git pull origin main
docker compose pull
# Synchronize environment variables
bash dify-env-sync.sh
# Output example:
# [INFO] === Dify Environment Variables Synchronization Script ===
# [SUCCESS] Required files verified
# [SUCCESS] Backed up existing .env to env-backup/.env.backup_20260212_120000
# [SUCCESS] Detected differences in 3 environment variables
#
# [1] PLUGIN_MAX_EXECUTION_TIMEOUT
# .env (current) : 300
# .env.example (recommended): 600
# -> Numeric increase (300 < 600)
#
# [SUCCESS] No removed environment variables found
# [SUCCESS] Partial synchronization of .env file completed
# Preserved .env values: 3
# Updated to .env.example values: 642
# Restart with updated configuration and images
docker compose up -d
Roll back a failed environment sync:
cd docker
# List available backups
ls -la env-backup/
# .env.backup_20260212_120000
# .env.backup_20260211_090000
# Restore the previous backup
cp env-backup/.env.backup_20260212_120000 .env
# Restart services
docker compose up -d
Run database migrations manually:
# Enter the API container
docker compose exec api bash
# Run pending migrations using Flask-Migrate
flask db upgrade
# Check current migration revision
flask db current
Complete upgrade workflow:
cd docker
# 1. Pull latest images
docker compose pull
# 2. Sync environment variables
bash dify-env-sync.sh
# 3. Restart services (migrations run automatically via MIGRATION_ENABLED=true)
docker compose up -d
# 4. Verify all services are healthy
docker compose ps