Compare commits
11 Commits
28-08-2025
...
09-03-2026
| Author | SHA1 | Date | |
|---|---|---|---|
| 34f81ffc2f | |||
| c8467d2d11 | |||
| 8f226ea714 | |||
| 8c845ec4aa | |||
| 0381268589 | |||
| 527c097c61 | |||
| 61e436a151 | |||
| 988bcb7223 | |||
| a0b5bb0c2a | |||
| 128651d310 | |||
| 6f07307229 |
@@ -14,6 +14,8 @@ _APP_DOMAIN_TARGET=localhost
|
||||
_APP_DOMAIN_TARGET_CNAME=localhost
|
||||
_APP_DOMAIN_TARGET_AAAA=::1
|
||||
_APP_DOMAIN_TARGET_A=127.0.0.1
|
||||
_APP_DOMAIN_TARGET_CAA=
|
||||
_APP_DNS=8.8.8.8
|
||||
_APP_CONSOLE_WHITELIST_ROOT=enabled
|
||||
_APP_CONSOLE_WHITELIST_EMAILS=
|
||||
_APP_CONSOLE_WHITELIST_IPS=
|
||||
@@ -98,6 +100,7 @@ _APP_FUNCTIONS_MEMORY_SWAP=0
|
||||
_APP_FUNCTIONS_RUNTIMES=node-16.0,php-8.0,python-3.9,ruby-3.0
|
||||
_APP_EXECUTOR_SECRET=your-secret-key
|
||||
_APP_EXECUTOR_HOST=http://exc1/v1
|
||||
_APP_BROWSER_HOST=http://appwrite-browser:3000/v1
|
||||
_APP_EXECUTOR_RUNTIME_NETWORK=appwrite_runtimes
|
||||
_APP_FUNCTIONS_ENVS=node-16.0,php-7.4,python-3.9,ruby-3.0
|
||||
_APP_FUNCTIONS_INACTIVE_THRESHOLD=60
|
||||
|
||||
@@ -28,7 +28,7 @@ services:
|
||||
- appwrite
|
||||
|
||||
appwrite:
|
||||
image: appwrite/appwrite:1.7.4
|
||||
image: appwrite/appwrite:1.8.1
|
||||
<<: *x-logging
|
||||
restart: unless-stopped
|
||||
networks:
|
||||
@@ -83,6 +83,8 @@ services:
|
||||
- _APP_DOMAIN_TARGET_CNAME
|
||||
- _APP_DOMAIN_TARGET_AAAA
|
||||
- _APP_DOMAIN_TARGET_A
|
||||
- _APP_DOMAIN_TARGET_CAA
|
||||
- _APP_DNS
|
||||
- _APP_DOMAIN_FUNCTIONS
|
||||
- _APP_REDIS_HOST
|
||||
- _APP_REDIS_PORT
|
||||
@@ -162,10 +164,9 @@ services:
|
||||
- _APP_MIGRATIONS_FIREBASE_CLIENT_ID
|
||||
- _APP_MIGRATIONS_FIREBASE_CLIENT_SECRET
|
||||
- _APP_ASSISTANT_OPENAI_API_KEY
|
||||
|
||||
appwrite-console:
|
||||
<<: *x-logging
|
||||
image: appwrite/console:6.0.13
|
||||
image: appwrite/console:7.5.7
|
||||
restart: unless-stopped
|
||||
networks:
|
||||
- appwrite
|
||||
@@ -185,7 +186,7 @@ services:
|
||||
- traefik.http.routers.appwrite_console_https.tls=true
|
||||
|
||||
appwrite-realtime:
|
||||
image: appwrite/appwrite:1.7.4
|
||||
image: appwrite/appwrite:1.8.1
|
||||
entrypoint: realtime
|
||||
<<: *x-logging
|
||||
restart: unless-stopped
|
||||
@@ -227,7 +228,7 @@ services:
|
||||
- _APP_LOGGING_CONFIG
|
||||
|
||||
appwrite-worker-audits:
|
||||
image: appwrite/appwrite:1.7.4
|
||||
image: appwrite/appwrite:1.8.1
|
||||
entrypoint: worker-audits
|
||||
<<: *x-logging
|
||||
restart: unless-stopped
|
||||
@@ -252,7 +253,7 @@ services:
|
||||
- _APP_LOGGING_CONFIG
|
||||
|
||||
appwrite-worker-webhooks:
|
||||
image: appwrite/appwrite:1.7.4
|
||||
image: appwrite/appwrite:1.8.1
|
||||
entrypoint: worker-webhooks
|
||||
<<: *x-logging
|
||||
restart: unless-stopped
|
||||
@@ -279,7 +280,7 @@ services:
|
||||
- _APP_LOGGING_CONFIG
|
||||
|
||||
appwrite-worker-deletes:
|
||||
image: appwrite/appwrite:1.7.4
|
||||
image: appwrite/appwrite:1.8.1
|
||||
entrypoint: worker-deletes
|
||||
<<: *x-logging
|
||||
restart: unless-stopped
|
||||
@@ -341,7 +342,7 @@ services:
|
||||
- _APP_EMAIL_CERTIFICATES
|
||||
|
||||
appwrite-worker-databases:
|
||||
image: appwrite/appwrite:1.7.4
|
||||
image: appwrite/appwrite:1.8.1
|
||||
entrypoint: worker-databases
|
||||
<<: *x-logging
|
||||
restart: unless-stopped
|
||||
@@ -366,7 +367,7 @@ services:
|
||||
- _APP_LOGGING_CONFIG
|
||||
|
||||
appwrite-worker-builds:
|
||||
image: appwrite/appwrite:1.7.4
|
||||
image: appwrite/appwrite:1.8.1
|
||||
entrypoint: worker-builds
|
||||
<<: *x-logging
|
||||
restart: unless-stopped
|
||||
@@ -433,7 +434,7 @@ services:
|
||||
- _APP_DOMAIN_SITES
|
||||
|
||||
appwrite-worker-certificates:
|
||||
image: appwrite/appwrite:1.7.4
|
||||
image: appwrite/appwrite:1.8.1
|
||||
entrypoint: worker-certificates
|
||||
<<: *x-logging
|
||||
restart: unless-stopped
|
||||
@@ -453,6 +454,8 @@ services:
|
||||
- _APP_DOMAIN_TARGET_CNAME
|
||||
- _APP_DOMAIN_TARGET_AAAA
|
||||
- _APP_DOMAIN_TARGET_A
|
||||
- _APP_DOMAIN_TARGET_CAA
|
||||
- _APP_DNS
|
||||
- _APP_DOMAIN_FUNCTIONS
|
||||
- _APP_EMAIL_CERTIFICATES
|
||||
- _APP_REDIS_HOST
|
||||
@@ -467,7 +470,7 @@ services:
|
||||
- _APP_LOGGING_CONFIG
|
||||
|
||||
appwrite-worker-functions:
|
||||
image: appwrite/appwrite:1.7.4
|
||||
image: appwrite/appwrite:1.8.1
|
||||
entrypoint: worker-functions
|
||||
<<: *x-logging
|
||||
restart: unless-stopped
|
||||
@@ -505,7 +508,7 @@ services:
|
||||
- _APP_LOGGING_CONFIG
|
||||
|
||||
appwrite-worker-mails:
|
||||
image: appwrite/appwrite:1.7.4
|
||||
image: appwrite/appwrite:1.8.1
|
||||
entrypoint: worker-mails
|
||||
<<: *x-logging
|
||||
restart: unless-stopped
|
||||
@@ -538,7 +541,7 @@ services:
|
||||
- _APP_OPTIONS_FORCE_HTTPS
|
||||
|
||||
appwrite-worker-messaging:
|
||||
image: appwrite/appwrite:1.7.4
|
||||
image: appwrite/appwrite:1.8.1
|
||||
entrypoint: worker-messaging
|
||||
<<: *x-logging
|
||||
restart: unless-stopped
|
||||
@@ -588,7 +591,7 @@ services:
|
||||
- _APP_STORAGE_WASABI_BUCKET
|
||||
|
||||
appwrite-worker-migrations:
|
||||
image: appwrite/appwrite:1.7.4
|
||||
image: appwrite/appwrite:1.8.1
|
||||
entrypoint: worker-migrations
|
||||
<<: *x-logging
|
||||
restart: unless-stopped
|
||||
@@ -606,6 +609,8 @@ services:
|
||||
- _APP_DOMAIN_TARGET_CNAME
|
||||
- _APP_DOMAIN_TARGET_AAAA
|
||||
- _APP_DOMAIN_TARGET_A
|
||||
- _APP_DOMAIN_TARGET_CAA
|
||||
- _APP_DNS
|
||||
- _APP_EMAIL_SECURITY
|
||||
- _APP_REDIS_HOST
|
||||
- _APP_REDIS_PORT
|
||||
@@ -621,7 +626,7 @@ services:
|
||||
- _APP_MIGRATIONS_FIREBASE_CLIENT_SECRET
|
||||
|
||||
appwrite-task-maintenance:
|
||||
image: appwrite/appwrite:1.7.4
|
||||
image: appwrite/appwrite:1.8.1
|
||||
entrypoint: maintenance
|
||||
<<: *x-logging
|
||||
restart: unless-stopped
|
||||
@@ -636,6 +641,8 @@ services:
|
||||
- _APP_DOMAIN_TARGET_CNAME
|
||||
- _APP_DOMAIN_TARGET_AAAA
|
||||
- _APP_DOMAIN_TARGET_A
|
||||
- _APP_DOMAIN_TARGET_CAA
|
||||
- _APP_DNS
|
||||
- _APP_DOMAIN_FUNCTIONS
|
||||
- _APP_OPENSSL_KEY_V1
|
||||
- _APP_REDIS_HOST
|
||||
@@ -657,7 +664,7 @@ services:
|
||||
- _APP_MAINTENANCE_RETENTION_SCHEDULES
|
||||
|
||||
appwrite-task-stats-resources:
|
||||
image: appwrite/appwrite:1.7.4
|
||||
image: appwrite/appwrite:1.8.1
|
||||
entrypoint: stats-resources
|
||||
<<: *x-logging
|
||||
restart: unless-stopped
|
||||
@@ -685,7 +692,7 @@ services:
|
||||
- _APP_STATS_RESOURCES_INTERVAL
|
||||
|
||||
appwrite-worker-stats-resources:
|
||||
image: appwrite/appwrite:1.7.4
|
||||
image: appwrite/appwrite:1.8.1
|
||||
entrypoint: worker-stats-resources
|
||||
<<: *x-logging
|
||||
restart: unless-stopped
|
||||
@@ -712,7 +719,7 @@ services:
|
||||
- _APP_STATS_RESOURCES_INTERVAL
|
||||
|
||||
appwrite-worker-stats-usage:
|
||||
image: appwrite/appwrite:1.7.4
|
||||
image: appwrite/appwrite:1.8.1
|
||||
entrypoint: worker-stats-usage
|
||||
<<: *x-logging
|
||||
restart: unless-stopped
|
||||
@@ -739,7 +746,7 @@ services:
|
||||
- _APP_USAGE_AGGREGATION_INTERVAL
|
||||
|
||||
appwrite-task-scheduler-functions:
|
||||
image: appwrite/appwrite:1.7.4
|
||||
image: appwrite/appwrite:1.8.1
|
||||
entrypoint: schedule-functions
|
||||
<<: *x-logging
|
||||
restart: unless-stopped
|
||||
@@ -763,7 +770,7 @@ services:
|
||||
- _APP_DB_PASS
|
||||
|
||||
appwrite-task-scheduler-executions:
|
||||
image: appwrite/appwrite:1.7.4
|
||||
image: appwrite/appwrite:1.8.1
|
||||
entrypoint: schedule-executions
|
||||
<<: *x-logging
|
||||
restart: unless-stopped
|
||||
@@ -787,7 +794,7 @@ services:
|
||||
- _APP_DB_PASS
|
||||
|
||||
appwrite-task-scheduler-messages:
|
||||
image: appwrite/appwrite:1.7.4
|
||||
image: appwrite/appwrite:1.8.1
|
||||
entrypoint: schedule-messages
|
||||
<<: *x-logging
|
||||
restart: unless-stopped
|
||||
@@ -811,7 +818,7 @@ services:
|
||||
- _APP_DB_PASS
|
||||
|
||||
appwrite-assistant:
|
||||
image: appwrite/assistant:0.4.0
|
||||
image: appwrite/assistant:0.8.4
|
||||
<<: *x-logging
|
||||
restart: unless-stopped
|
||||
networks:
|
||||
@@ -820,7 +827,7 @@ services:
|
||||
- _APP_ASSISTANT_OPENAI_API_KEY
|
||||
|
||||
appwrite-browser:
|
||||
image: appwrite/browser:0.2.4
|
||||
image: appwrite/browser:0.3.2
|
||||
<<: *x-logging
|
||||
restart: unless-stopped
|
||||
networks:
|
||||
@@ -831,7 +838,7 @@ services:
|
||||
<<: *x-logging
|
||||
restart: unless-stopped
|
||||
stop_signal: SIGINT
|
||||
image: openruntimes/executor:0.7.14
|
||||
image: openruntimes/executor:0.7.22
|
||||
networks:
|
||||
- appwrite
|
||||
- runtimes
|
||||
|
||||
@@ -1,5 +0,0 @@
|
||||
# Dify
|
||||
|
||||
- copied from https://github.com/langgenius/dify
|
||||
- removed `container_name`
|
||||
- removed `ports`
|
||||
+326
-37
@@ -24,6 +24,11 @@ CONSOLE_WEB_URL=
|
||||
# Example: https://api.dify.ai
|
||||
SERVICE_API_URL=
|
||||
|
||||
# Trigger external URL
|
||||
# used to display trigger endpoint API Base URL to the front-end.
|
||||
# Example: https://api.dify.ai
|
||||
TRIGGER_URL=http://localhost
|
||||
|
||||
# WebApp API backend Url,
|
||||
# used to declare the back-end URL for the front-end API.
|
||||
# If empty, it is the same domain.
|
||||
@@ -53,10 +58,13 @@ FILES_URL=
|
||||
INTERNAL_FILES_URL=
|
||||
|
||||
# Ensure UTF-8 encoding
|
||||
LANG=en_US.UTF-8
|
||||
LC_ALL=en_US.UTF-8
|
||||
LANG=C.UTF-8
|
||||
LC_ALL=C.UTF-8
|
||||
PYTHONIOENCODING=utf-8
|
||||
|
||||
# Set UV cache directory to avoid permission issues with non-existent home directory
|
||||
UV_CACHE_DIR=/tmp/.uv-cache
|
||||
|
||||
# ------------------------------
|
||||
# Server Configuration
|
||||
# ------------------------------
|
||||
@@ -64,6 +72,8 @@ PYTHONIOENCODING=utf-8
|
||||
# The log level for the application.
|
||||
# Supported values are `DEBUG`, `INFO`, `WARNING`, `ERROR`, `CRITICAL`
|
||||
LOG_LEVEL=INFO
|
||||
# Log output format: text or json
|
||||
LOG_OUTPUT_FORMAT=text
|
||||
# Log file path
|
||||
LOG_FILE=/app/logs/server.log
|
||||
# Log file max size, the unit is MB
|
||||
@@ -128,6 +138,8 @@ ACCESS_TOKEN_EXPIRE_MINUTES=60
|
||||
# Refresh token expiration time in days
|
||||
REFRESH_TOKEN_EXPIRE_DAYS=30
|
||||
|
||||
# The default number of active requests for the application, where 0 means unlimited, should be a non-negative integer.
|
||||
APP_DEFAULT_ACTIVE_REQUESTS=0
|
||||
# The maximum number of active requests for the application, where 0 means unlimited, should be a non-negative integer.
|
||||
APP_MAX_ACTIVE_REQUESTS=0
|
||||
APP_MAX_EXECUTION_TIME=1200
|
||||
@@ -149,6 +161,12 @@ DIFY_PORT=5001
|
||||
SERVER_WORKER_AMOUNT=1
|
||||
|
||||
# Defaults to gevent. If using windows, it can be switched to sync or solo.
|
||||
#
|
||||
# Warning: Changing this parameter requires disabling patching for
|
||||
# psycopg2 and gRPC (see `gunicorn.conf.py` and `celery_entrypoint.py`).
|
||||
# Modifying it may also decrease throughput.
|
||||
#
|
||||
# It is strongly discouraged to change this parameter.
|
||||
SERVER_WORKER_CLASS=gevent
|
||||
|
||||
# Default number of worker connections, the default is 10.
|
||||
@@ -156,6 +174,12 @@ SERVER_WORKER_CONNECTIONS=10
|
||||
|
||||
# Similar to SERVER_WORKER_CLASS.
|
||||
# If using windows, it can be switched to sync or solo.
|
||||
#
|
||||
# Warning: Changing this parameter requires disabling patching for
|
||||
# psycopg2 and gRPC (see `gunicorn_conf.py` and `celery_entrypoint.py`).
|
||||
# Modifying it may also decrease throughput.
|
||||
#
|
||||
# It is strongly discouraged to change this parameter.
|
||||
CELERY_WORKER_CLASS=
|
||||
|
||||
# Request handling timeout. The default is 200,
|
||||
@@ -201,17 +225,26 @@ ENABLE_WEBSITE_JINAREADER=true
|
||||
ENABLE_WEBSITE_FIRECRAWL=true
|
||||
ENABLE_WEBSITE_WATERCRAWL=true
|
||||
|
||||
# Enable inline LaTeX rendering with single dollar signs ($...$) in the web frontend
|
||||
# Default is false for security reasons to prevent conflicts with regular text
|
||||
NEXT_PUBLIC_ENABLE_SINGLE_DOLLAR_LATEX=false
|
||||
|
||||
# ------------------------------
|
||||
# Database Configuration
|
||||
# The database uses PostgreSQL. Please use the public schema.
|
||||
# It is consistent with the configuration in the 'db' service below.
|
||||
# The database uses PostgreSQL or MySQL. OceanBase and seekdb are also supported. Please use the public schema.
|
||||
# It is consistent with the configuration in the database service below.
|
||||
# You can adjust the database configuration according to your needs.
|
||||
# ------------------------------
|
||||
|
||||
# Database type, supported values are `postgresql`, `mysql`, `oceanbase`, `seekdb`
|
||||
DB_TYPE=postgresql
|
||||
# For MySQL, only `root` user is supported for now
|
||||
DB_USERNAME=postgres
|
||||
DB_PASSWORD=difyai123456
|
||||
DB_HOST=db
|
||||
DB_HOST=db_postgres
|
||||
DB_PORT=5432
|
||||
DB_DATABASE=dify
|
||||
|
||||
# The size of the database connection pool.
|
||||
# The default is 30 connections, which can be appropriately increased.
|
||||
SQLALCHEMY_POOL_SIZE=30
|
||||
@@ -225,6 +258,9 @@ SQLALCHEMY_ECHO=false
|
||||
SQLALCHEMY_POOL_PRE_PING=false
|
||||
# Whether to enable the Last in first out option or use default FIFO queue if is false
|
||||
SQLALCHEMY_POOL_USE_LIFO=false
|
||||
# Number of seconds to wait for a connection from the pool before raising a timeout error.
|
||||
# Default is 30
|
||||
SQLALCHEMY_POOL_TIMEOUT=30
|
||||
|
||||
# Maximum number of connections to the database
|
||||
# Default is 100
|
||||
@@ -256,6 +292,43 @@ POSTGRES_MAINTENANCE_WORK_MEM=64MB
|
||||
# Reference: https://www.postgresql.org/docs/current/runtime-config-query.html#GUC-EFFECTIVE-CACHE-SIZE
|
||||
POSTGRES_EFFECTIVE_CACHE_SIZE=4096MB
|
||||
|
||||
# Sets the maximum allowed duration of any statement before termination.
|
||||
# Default is 0 (no timeout).
|
||||
#
|
||||
# Reference: https://www.postgresql.org/docs/current/runtime-config-client.html#GUC-STATEMENT-TIMEOUT
|
||||
# A value of 0 prevents the server from timing out statements.
|
||||
POSTGRES_STATEMENT_TIMEOUT=0
|
||||
|
||||
# Sets the maximum allowed duration of any idle in-transaction session before termination.
|
||||
# Default is 0 (no timeout).
|
||||
#
|
||||
# Reference: https://www.postgresql.org/docs/current/runtime-config-client.html#GUC-IDLE-IN-TRANSACTION-SESSION-TIMEOUT
|
||||
# A value of 0 prevents the server from terminating idle sessions.
|
||||
POSTGRES_IDLE_IN_TRANSACTION_SESSION_TIMEOUT=0
|
||||
|
||||
# MySQL Performance Configuration
|
||||
# Maximum number of connections to MySQL
|
||||
#
|
||||
# Default is 1000
|
||||
MYSQL_MAX_CONNECTIONS=1000
|
||||
|
||||
# InnoDB buffer pool size
|
||||
# Default is 512M
|
||||
# Recommended value: 70-80% of available memory for dedicated MySQL server
|
||||
# Reference: https://dev.mysql.com/doc/refman/8.0/en/innodb-parameters.html#sysvar_innodb_buffer_pool_size
|
||||
MYSQL_INNODB_BUFFER_POOL_SIZE=512M
|
||||
|
||||
# InnoDB log file size
|
||||
# Default is 128M
|
||||
# Reference: https://dev.mysql.com/doc/refman/8.0/en/innodb-parameters.html#sysvar_innodb_log_file_size
|
||||
MYSQL_INNODB_LOG_FILE_SIZE=128M
|
||||
|
||||
# InnoDB flush log at transaction commit
|
||||
# Default is 2 (flush to OS cache, sync every second)
|
||||
# Options: 0 (no flush), 1 (flush and sync), 2 (flush to OS cache)
|
||||
# Reference: https://dev.mysql.com/doc/refman/8.0/en/innodb-parameters.html#sysvar_innodb_flush_log_at_trx_commit
|
||||
MYSQL_INNODB_FLUSH_LOG_AT_TRX_COMMIT=2
|
||||
|
||||
# ------------------------------
|
||||
# Redis Configuration
|
||||
# This Redis configuration is used for caching and for pub/sub during conversation.
|
||||
@@ -276,6 +349,9 @@ REDIS_SSL_CERTFILE=
|
||||
REDIS_SSL_KEYFILE=
|
||||
# Path to client private key file for SSL authentication
|
||||
REDIS_DB=0
|
||||
# Optional: limit total Redis connections used by API/Worker (unset for default)
|
||||
# Align with API's REDIS_MAX_CONNECTIONS in configs
|
||||
REDIS_MAX_CONNECTIONS=
|
||||
|
||||
# Whether to use Redis Sentinel mode.
|
||||
# If set to true, the application will automatically discover and connect to the master node through Sentinel.
|
||||
@@ -299,7 +375,7 @@ REDIS_CLUSTERS_PASSWORD=
|
||||
# Celery Configuration
|
||||
# ------------------------------
|
||||
|
||||
# Use standalone redis as the broker, and redis db 1 for celery broker. (redis_username is usually set by defualt as empty)
|
||||
# Use standalone redis as the broker, and redis db 1 for celery broker. (redis_username is usually set by default as empty)
|
||||
# Format as follows: `redis://<redis_username>:<redis_password>@<redis_host>:<redis_port>/<redis_database>`.
|
||||
# Example: redis://:difyai123456@redis:6379/1
|
||||
# If use Redis Sentinel, format as follows: `sentinel://<redis_username>:<redis_password>@<sentinel_host1>:<sentinel_port>/<redis_database>`
|
||||
@@ -314,6 +390,8 @@ CELERY_USE_SENTINEL=false
|
||||
CELERY_SENTINEL_MASTER_NAME=
|
||||
CELERY_SENTINEL_PASSWORD=
|
||||
CELERY_SENTINEL_SOCKET_TIMEOUT=0.1
|
||||
# e.g. {"tasks.add": {"rate_limit": "10/s"}}
|
||||
CELERY_TASK_ANNOTATIONS=null
|
||||
|
||||
# ------------------------------
|
||||
# CORS Configuration
|
||||
@@ -327,6 +405,11 @@ WEB_API_CORS_ALLOW_ORIGINS=*
|
||||
# Specifies the allowed origins for cross-origin requests to the console API,
|
||||
# e.g. https://cloud.dify.ai or * for all origins.
|
||||
CONSOLE_CORS_ALLOW_ORIGINS=*
|
||||
# When the frontend and backend run on different subdomains, set COOKIE_DOMAIN to the site's top-level domain (e.g., `example.com`). Leading dots are optional.
|
||||
COOKIE_DOMAIN=
|
||||
# When the frontend and backend run on different subdomains, set NEXT_PUBLIC_COOKIE_DOMAIN=1.
|
||||
NEXT_PUBLIC_COOKIE_DOMAIN=
|
||||
NEXT_PUBLIC_BATCH_CONCURRENCY=5
|
||||
|
||||
# ------------------------------
|
||||
# File Storage Configuration
|
||||
@@ -374,6 +457,15 @@ S3_SECRET_KEY=
|
||||
# If set to false, the access key and secret key must be provided.
|
||||
S3_USE_AWS_MANAGED_IAM=false
|
||||
|
||||
# Workflow run and Conversation archive storage (S3-compatible)
|
||||
ARCHIVE_STORAGE_ENABLED=false
|
||||
ARCHIVE_STORAGE_ENDPOINT=
|
||||
ARCHIVE_STORAGE_ARCHIVE_BUCKET=
|
||||
ARCHIVE_STORAGE_EXPORT_BUCKET=
|
||||
ARCHIVE_STORAGE_ACCESS_KEY=
|
||||
ARCHIVE_STORAGE_SECRET_KEY=
|
||||
ARCHIVE_STORAGE_REGION=auto
|
||||
|
||||
# Azure Blob Configuration
|
||||
#
|
||||
AZURE_BLOB_ACCOUNT_NAME=difyai
|
||||
@@ -396,6 +488,7 @@ ALIYUN_OSS_REGION=ap-southeast-1
|
||||
ALIYUN_OSS_AUTH_VERSION=v4
|
||||
# Don't start with '/'. OSS doesn't support leading slash in object names.
|
||||
ALIYUN_OSS_PATH=your-path
|
||||
ALIYUN_CLOUDBOX_ID=your-cloudbox-id
|
||||
|
||||
# Tencent COS Configuration
|
||||
#
|
||||
@@ -404,6 +497,7 @@ TENCENT_COS_SECRET_KEY=your-secret-key
|
||||
TENCENT_COS_SECRET_ID=your-secret-id
|
||||
TENCENT_COS_REGION=your-region
|
||||
TENCENT_COS_SCHEME=your-scheme
|
||||
TENCENT_COS_CUSTOM_DOMAIN=your-custom-domain
|
||||
|
||||
# Oracle Storage Configuration
|
||||
#
|
||||
@@ -419,6 +513,7 @@ HUAWEI_OBS_BUCKET_NAME=your-bucket-name
|
||||
HUAWEI_OBS_SECRET_KEY=your-secret-key
|
||||
HUAWEI_OBS_ACCESS_KEY=your-access-key
|
||||
HUAWEI_OBS_SERVER=your-server-url
|
||||
HUAWEI_OBS_PATH_STYLE=false
|
||||
|
||||
# Volcengine TOS Configuration
|
||||
#
|
||||
@@ -446,7 +541,7 @@ SUPABASE_URL=your-server-url
|
||||
# ------------------------------
|
||||
|
||||
# The type of vector store to use.
|
||||
# Supported values are `weaviate`, `qdrant`, `milvus`, `myscale`, `relyt`, `pgvector`, `pgvecto-rs`, `chroma`, `opensearch`, `oracle`, `tencent`, `elasticsearch`, `elasticsearch-ja`, `analyticdb`, `couchbase`, `vikingdb`, `oceanbase`, `opengauss`, `tablestore`,`vastbase`,`tidb`,`tidb_on_qdrant`,`baidu`,`lindorm`,`huawei_cloud`,`upstash`, `matrixone`, `clickzetta`.
|
||||
# Supported values are `weaviate`, `oceanbase`, `seekdb`, `qdrant`, `milvus`, `myscale`, `relyt`, `pgvector`, `pgvecto-rs`, `chroma`, `opensearch`, `oracle`, `tencent`, `elasticsearch`, `elasticsearch-ja`, `analyticdb`, `couchbase`, `vikingdb`, `opengauss`, `tablestore`, `vastbase`, `tidb`, `tidb_on_qdrant`, `baidu`, `lindorm`, `huawei_cloud`, `upstash`, `matrixone`, `clickzetta`, `alibabacloud_mysql`, `iris`.
|
||||
VECTOR_STORE=weaviate
|
||||
# Prefix used to create collection name in vector database
|
||||
VECTOR_INDEX_NAME_PREFIX=Vector_index
|
||||
@@ -454,6 +549,25 @@ VECTOR_INDEX_NAME_PREFIX=Vector_index
|
||||
# The Weaviate endpoint URL. Only available when VECTOR_STORE is `weaviate`.
|
||||
WEAVIATE_ENDPOINT=http://weaviate:8080
|
||||
WEAVIATE_API_KEY=WVF5YThaHlkYwhGUSmCRgsX3tD5ngdN8pkih
|
||||
WEAVIATE_GRPC_ENDPOINT=grpc://weaviate:50051
|
||||
WEAVIATE_TOKENIZATION=word
|
||||
|
||||
# For OceanBase metadata database configuration, available when `DB_TYPE` is `oceanbase`.
|
||||
# For OceanBase vector database configuration, available when `VECTOR_STORE` is `oceanbase`
|
||||
# If you want to use OceanBase as both vector database and metadata database, you need to set both `DB_TYPE` and `VECTOR_STORE` to `oceanbase`, and set Database Configuration is the same as the vector database.
|
||||
# seekdb is the lite version of OceanBase and shares the connection configuration with OceanBase.
|
||||
OCEANBASE_VECTOR_HOST=oceanbase
|
||||
OCEANBASE_VECTOR_PORT=2881
|
||||
OCEANBASE_VECTOR_USER=root@test
|
||||
OCEANBASE_VECTOR_PASSWORD=difyai123456
|
||||
OCEANBASE_VECTOR_DATABASE=test
|
||||
OCEANBASE_CLUSTER_NAME=difyai
|
||||
OCEANBASE_MEMORY_LIMIT=6G
|
||||
OCEANBASE_ENABLE_HYBRID_SEARCH=false
|
||||
# For OceanBase vector database, built-in fulltext parsers are `ngram`, `beng`, `space`, `ngram2`, `ik`
|
||||
# For OceanBase vector database, external fulltext parsers (require plugin installation) are `japanese_ftparser`, `thai_ftparser`
|
||||
OCEANBASE_FULLTEXT_PARSER=ik
|
||||
SEEKDB_MEMORY_LIMIT=2G
|
||||
|
||||
# The Qdrant endpoint URL. Only available when VECTOR_STORE is `qdrant`.
|
||||
QDRANT_URL=http://qdrant:6333
|
||||
@@ -577,6 +691,15 @@ ORACLE_WALLET_LOCATION=/app/api/storage/wallet
|
||||
ORACLE_WALLET_PASSWORD=dify
|
||||
ORACLE_IS_AUTONOMOUS=false
|
||||
|
||||
# AlibabaCloud MySQL configuration, only available when VECTOR_STORE is `alibabcloud_mysql`
|
||||
ALIBABACLOUD_MYSQL_HOST=127.0.0.1
|
||||
ALIBABACLOUD_MYSQL_PORT=3306
|
||||
ALIBABACLOUD_MYSQL_USER=root
|
||||
ALIBABACLOUD_MYSQL_PASSWORD=difyai123456
|
||||
ALIBABACLOUD_MYSQL_DATABASE=dify
|
||||
ALIBABACLOUD_MYSQL_MAX_CONNECTION=5
|
||||
ALIBABACLOUD_MYSQL_HNSW_M=6
|
||||
|
||||
# relyt configurations, only available when VECTOR_STORE is `relyt`
|
||||
RELYT_HOST=db
|
||||
RELYT_PORT=5432
|
||||
@@ -632,6 +755,8 @@ BAIDU_VECTOR_DB_API_KEY=dify
|
||||
BAIDU_VECTOR_DB_DATABASE=dify
|
||||
BAIDU_VECTOR_DB_SHARD=1
|
||||
BAIDU_VECTOR_DB_REPLICAS=3
|
||||
BAIDU_VECTOR_DB_INVERTED_INDEX_ANALYZER=DEFAULT_ANALYZER
|
||||
BAIDU_VECTOR_DB_INVERTED_INDEX_PARSER_MODE=COARSE_MODE
|
||||
|
||||
# VikingDB configurations, only available when VECTOR_STORE is `vikingdb`
|
||||
VIKINGDB_ACCESS_KEY=your-ak
|
||||
@@ -643,21 +768,12 @@ VIKINGDB_CONNECTION_TIMEOUT=30
|
||||
VIKINGDB_SOCKET_TIMEOUT=30
|
||||
|
||||
# Lindorm configuration, only available when VECTOR_STORE is `lindorm`
|
||||
LINDORM_URL=http://lindorm:30070
|
||||
LINDORM_USERNAME=lindorm
|
||||
LINDORM_PASSWORD=lindorm
|
||||
LINDORM_URL=http://localhost:30070
|
||||
LINDORM_USERNAME=admin
|
||||
LINDORM_PASSWORD=admin
|
||||
LINDORM_USING_UGC=True
|
||||
LINDORM_QUERY_TIMEOUT=1
|
||||
|
||||
# OceanBase Vector configuration, only available when VECTOR_STORE is `oceanbase`
|
||||
OCEANBASE_VECTOR_HOST=oceanbase
|
||||
OCEANBASE_VECTOR_PORT=2881
|
||||
OCEANBASE_VECTOR_USER=root@test
|
||||
OCEANBASE_VECTOR_PASSWORD=difyai123456
|
||||
OCEANBASE_VECTOR_DATABASE=test
|
||||
OCEANBASE_CLUSTER_NAME=difyai
|
||||
OCEANBASE_MEMORY_LIMIT=6G
|
||||
OCEANBASE_ENABLE_HYBRID_SEARCH=false
|
||||
|
||||
# opengauss configurations, only available when VECTOR_STORE is `opengauss`
|
||||
OPENGAUSS_HOST=opengauss
|
||||
OPENGAUSS_PORT=6600
|
||||
@@ -699,6 +815,21 @@ CLICKZETTA_ANALYZER_TYPE=chinese
|
||||
CLICKZETTA_ANALYZER_MODE=smart
|
||||
CLICKZETTA_VECTOR_DISTANCE_FUNCTION=cosine_distance
|
||||
|
||||
# InterSystems IRIS configuration, only available when VECTOR_STORE is `iris`
|
||||
IRIS_HOST=iris
|
||||
IRIS_SUPER_SERVER_PORT=1972
|
||||
IRIS_WEB_SERVER_PORT=52773
|
||||
IRIS_USER=_SYSTEM
|
||||
IRIS_PASSWORD=Dify@1234
|
||||
IRIS_DATABASE=USER
|
||||
IRIS_SCHEMA=dify
|
||||
IRIS_CONNECTION_URL=
|
||||
IRIS_MIN_CONNECTION=1
|
||||
IRIS_MAX_CONNECTION=3
|
||||
IRIS_TEXT_INDEX=true
|
||||
IRIS_TEXT_INDEX_LANGUAGE=en
|
||||
IRIS_TIMEZONE=UTC
|
||||
|
||||
# ------------------------------
|
||||
# Knowledge Configuration
|
||||
# ------------------------------
|
||||
@@ -709,6 +840,25 @@ UPLOAD_FILE_SIZE_LIMIT=15
|
||||
# The maximum number of files that can be uploaded at a time, default 5.
|
||||
UPLOAD_FILE_BATCH_LIMIT=5
|
||||
|
||||
# Comma-separated list of file extensions blocked from upload for security reasons.
|
||||
# Extensions should be lowercase without dots (e.g., exe,bat,sh,dll).
|
||||
# Empty by default to allow all file types.
|
||||
# Recommended: exe,bat,cmd,com,scr,vbs,ps1,msi,dll
|
||||
UPLOAD_FILE_EXTENSION_BLACKLIST=
|
||||
|
||||
# Maximum number of files allowed in a single chunk attachment, default 10.
|
||||
SINGLE_CHUNK_ATTACHMENT_LIMIT=10
|
||||
|
||||
# Maximum number of files allowed in a image batch upload operation
|
||||
IMAGE_FILE_BATCH_LIMIT=10
|
||||
|
||||
# Maximum allowed image file size for attachments in megabytes, default 2.
|
||||
ATTACHMENT_IMAGE_FILE_SIZE_LIMIT=2
|
||||
|
||||
# Timeout for downloading image attachments in seconds, default 60.
|
||||
ATTACHMENT_IMAGE_DOWNLOAD_TIMEOUT=60
|
||||
|
||||
|
||||
# ETL type, support: `dify`, `Unstructured`
|
||||
# `dify` Dify's proprietary file extraction scheme
|
||||
# `Unstructured` Unstructured.io file extraction scheme
|
||||
@@ -826,6 +976,8 @@ SMTP_USERNAME=
|
||||
SMTP_PASSWORD=
|
||||
SMTP_USE_TLS=true
|
||||
SMTP_OPPORTUNISTIC_TLS=false
|
||||
# Optional: override the local hostname used for SMTP HELO/EHLO
|
||||
SMTP_LOCAL_HOSTNAME=
|
||||
|
||||
# Sendgid configuration
|
||||
SENDGRID_API_KEY=
|
||||
@@ -843,33 +995,47 @@ INVITE_EXPIRY_HOURS=72
|
||||
|
||||
# Reset password token valid time (minutes),
|
||||
RESET_PASSWORD_TOKEN_EXPIRY_MINUTES=5
|
||||
EMAIL_REGISTER_TOKEN_EXPIRY_MINUTES=5
|
||||
CHANGE_EMAIL_TOKEN_EXPIRY_MINUTES=5
|
||||
OWNER_TRANSFER_TOKEN_EXPIRY_MINUTES=5
|
||||
|
||||
# The sandbox service endpoint.
|
||||
CODE_EXECUTION_ENDPOINT=http://sandbox:8194
|
||||
CODE_EXECUTION_API_KEY=dify-sandbox
|
||||
CODE_EXECUTION_SSL_VERIFY=True
|
||||
CODE_EXECUTION_POOL_MAX_CONNECTIONS=100
|
||||
CODE_EXECUTION_POOL_MAX_KEEPALIVE_CONNECTIONS=20
|
||||
CODE_EXECUTION_POOL_KEEPALIVE_EXPIRY=5.0
|
||||
CODE_MAX_NUMBER=9223372036854775807
|
||||
CODE_MIN_NUMBER=-9223372036854775808
|
||||
CODE_MAX_DEPTH=5
|
||||
CODE_MAX_PRECISION=20
|
||||
CODE_MAX_STRING_LENGTH=80000
|
||||
CODE_MAX_STRING_LENGTH=400000
|
||||
CODE_MAX_STRING_ARRAY_LENGTH=30
|
||||
CODE_MAX_OBJECT_ARRAY_LENGTH=30
|
||||
CODE_MAX_NUMBER_ARRAY_LENGTH=1000
|
||||
CODE_EXECUTION_CONNECT_TIMEOUT=10
|
||||
CODE_EXECUTION_READ_TIMEOUT=60
|
||||
CODE_EXECUTION_WRITE_TIMEOUT=10
|
||||
TEMPLATE_TRANSFORM_MAX_LENGTH=80000
|
||||
TEMPLATE_TRANSFORM_MAX_LENGTH=400000
|
||||
|
||||
# Workflow runtime configuration
|
||||
WORKFLOW_MAX_EXECUTION_STEPS=500
|
||||
WORKFLOW_MAX_EXECUTION_TIME=1200
|
||||
WORKFLOW_CALL_MAX_DEPTH=5
|
||||
MAX_VARIABLE_SIZE=204800
|
||||
WORKFLOW_PARALLEL_DEPTH_LIMIT=3
|
||||
WORKFLOW_FILE_UPLOAD_LIMIT=10
|
||||
|
||||
# GraphEngine Worker Pool Configuration
|
||||
# Minimum number of workers per GraphEngine instance (default: 1)
|
||||
GRAPH_ENGINE_MIN_WORKERS=1
|
||||
# Maximum number of workers per GraphEngine instance (default: 10)
|
||||
GRAPH_ENGINE_MAX_WORKERS=10
|
||||
# Queue depth threshold that triggers worker scale up (default: 3)
|
||||
GRAPH_ENGINE_SCALE_UP_THRESHOLD=3
|
||||
# Seconds of idle time before scaling down workers (default: 5.0)
|
||||
GRAPH_ENGINE_SCALE_DOWN_IDLE_TIME=5.0
|
||||
|
||||
# Workflow storage configuration
|
||||
# Options: rdbms, hybrid
|
||||
# rdbms: Use only the relational database (default)
|
||||
@@ -881,18 +1047,26 @@ WORKFLOW_NODE_EXECUTION_STORAGE=rdbms
|
||||
# Options:
|
||||
# - core.repositories.sqlalchemy_workflow_execution_repository.SQLAlchemyWorkflowExecutionRepository (default)
|
||||
# - core.repositories.celery_workflow_execution_repository.CeleryWorkflowExecutionRepository
|
||||
# - extensions.logstore.repositories.logstore_workflow_execution_repository.LogstoreWorkflowExecutionRepository
|
||||
CORE_WORKFLOW_EXECUTION_REPOSITORY=core.repositories.sqlalchemy_workflow_execution_repository.SQLAlchemyWorkflowExecutionRepository
|
||||
|
||||
# Core workflow node execution repository implementation
|
||||
# Options:
|
||||
# - core.repositories.sqlalchemy_workflow_node_execution_repository.SQLAlchemyWorkflowNodeExecutionRepository (default)
|
||||
# - core.repositories.celery_workflow_node_execution_repository.CeleryWorkflowNodeExecutionRepository
|
||||
# - extensions.logstore.repositories.logstore_workflow_node_execution_repository.LogstoreWorkflowNodeExecutionRepository
|
||||
CORE_WORKFLOW_NODE_EXECUTION_REPOSITORY=core.repositories.sqlalchemy_workflow_node_execution_repository.SQLAlchemyWorkflowNodeExecutionRepository
|
||||
|
||||
# API workflow run repository implementation
|
||||
# Options:
|
||||
# - repositories.sqlalchemy_api_workflow_run_repository.DifyAPISQLAlchemyWorkflowRunRepository (default)
|
||||
# - extensions.logstore.repositories.logstore_api_workflow_run_repository.LogstoreAPIWorkflowRunRepository
|
||||
API_WORKFLOW_RUN_REPOSITORY=repositories.sqlalchemy_api_workflow_run_repository.DifyAPISQLAlchemyWorkflowRunRepository
|
||||
|
||||
# API workflow node execution repository implementation
|
||||
# Options:
|
||||
# - repositories.sqlalchemy_api_workflow_node_execution_repository.DifyAPISQLAlchemyWorkflowNodeExecutionRepository (default)
|
||||
# - extensions.logstore.repositories.logstore_api_workflow_node_execution_repository.LogstoreAPIWorkflowNodeExecutionRepository
|
||||
API_WORKFLOW_NODE_EXECUTION_REPOSITORY=repositories.sqlalchemy_api_workflow_node_execution_repository.DifyAPISQLAlchemyWorkflowNodeExecutionRepository
|
||||
|
||||
# Workflow log cleanup configuration
|
||||
@@ -902,12 +1076,56 @@ WORKFLOW_LOG_CLEANUP_ENABLED=false
|
||||
WORKFLOW_LOG_RETENTION_DAYS=30
|
||||
# Batch size for workflow log cleanup operations (default: 100)
|
||||
WORKFLOW_LOG_CLEANUP_BATCH_SIZE=100
|
||||
# Comma-separated list of workflow IDs to clean logs for
|
||||
WORKFLOW_LOG_CLEANUP_SPECIFIC_WORKFLOW_IDS=
|
||||
|
||||
# Aliyun SLS Logstore Configuration
|
||||
# Aliyun Access Key ID
|
||||
ALIYUN_SLS_ACCESS_KEY_ID=
|
||||
# Aliyun Access Key Secret
|
||||
ALIYUN_SLS_ACCESS_KEY_SECRET=
|
||||
# Aliyun SLS Endpoint (e.g., cn-hangzhou.log.aliyuncs.com)
|
||||
ALIYUN_SLS_ENDPOINT=
|
||||
# Aliyun SLS Region (e.g., cn-hangzhou)
|
||||
ALIYUN_SLS_REGION=
|
||||
# Aliyun SLS Project Name
|
||||
ALIYUN_SLS_PROJECT_NAME=
|
||||
# Number of days to retain workflow run logs (default: 365 days, 3650 for permanent storage)
|
||||
ALIYUN_SLS_LOGSTORE_TTL=365
|
||||
# Enable dual-write to both SLS LogStore and SQL database (default: false)
|
||||
LOGSTORE_DUAL_WRITE_ENABLED=false
|
||||
# Enable dual-read fallback to SQL database when LogStore returns no results (default: true)
|
||||
# Useful for migration scenarios where historical data exists only in SQL database
|
||||
LOGSTORE_DUAL_READ_ENABLED=true
|
||||
# Control flag for whether to write the `graph` field to LogStore.
|
||||
# If LOGSTORE_ENABLE_PUT_GRAPH_FIELD is "true", write the full `graph` field;
|
||||
# otherwise write an empty {} instead. Defaults to writing the `graph` field.
|
||||
LOGSTORE_ENABLE_PUT_GRAPH_FIELD=true
|
||||
|
||||
# HTTP request node in workflow configuration
|
||||
HTTP_REQUEST_NODE_MAX_BINARY_SIZE=10485760
|
||||
HTTP_REQUEST_NODE_MAX_TEXT_SIZE=1048576
|
||||
HTTP_REQUEST_NODE_SSL_VERIFY=True
|
||||
|
||||
# HTTP request node timeout configuration
|
||||
# Maximum timeout values (in seconds) that users can set in HTTP request nodes
|
||||
# - Connect timeout: Time to wait for establishing connection (default: 10s)
|
||||
# - Read timeout: Time to wait for receiving response data (default: 600s, 10 minutes)
|
||||
# - Write timeout: Time to wait for sending request data (default: 600s, 10 minutes)
|
||||
HTTP_REQUEST_MAX_CONNECT_TIMEOUT=10
|
||||
HTTP_REQUEST_MAX_READ_TIMEOUT=600
|
||||
HTTP_REQUEST_MAX_WRITE_TIMEOUT=600
|
||||
|
||||
# Base64 encoded CA certificate data for custom certificate verification (PEM format, optional)
|
||||
# HTTP_REQUEST_NODE_SSL_CERT_DATA=LS0tLS1CRUdJTi...
|
||||
# Base64 encoded client certificate data for mutual TLS authentication (PEM format, optional)
|
||||
# HTTP_REQUEST_NODE_SSL_CLIENT_CERT_DATA=LS0tLS1CRUdJTi...
|
||||
# Base64 encoded client private key data for mutual TLS authentication (PEM format, optional)
|
||||
# HTTP_REQUEST_NODE_SSL_CLIENT_KEY_DATA=LS0tLS1CRUdJTi...
|
||||
|
||||
# Webhook request configuration
|
||||
WEBHOOK_REQUEST_BODY_MAX_SIZE=10485760
|
||||
|
||||
# Respect X-* headers to redirect clients
|
||||
RESPECT_XFORWARD_HEADERS_ENABLED=false
|
||||
|
||||
@@ -942,18 +1160,14 @@ ALLOW_UNSAFE_DATA_SCHEME=false
|
||||
MAX_TREE_DEPTH=50
|
||||
|
||||
# ------------------------------
|
||||
# Environment Variables for db Service
|
||||
# Environment Variables for database Service
|
||||
# ------------------------------
|
||||
|
||||
# The name of the default postgres user.
|
||||
POSTGRES_USER=${DB_USERNAME}
|
||||
# The password for the default postgres user.
|
||||
POSTGRES_PASSWORD=${DB_PASSWORD}
|
||||
# The name of the default postgres database.
|
||||
POSTGRES_DB=${DB_DATABASE}
|
||||
# postgres data directory
|
||||
# Postgres data directory
|
||||
PGDATA=/var/lib/postgresql/data/pgdata
|
||||
|
||||
# MySQL Default Configuration
|
||||
MYSQL_HOST_VOLUME=./volumes/mysql/data
|
||||
|
||||
# ------------------------------
|
||||
# Environment Variables for sandbox Service
|
||||
# ------------------------------
|
||||
@@ -987,6 +1201,10 @@ WEAVIATE_AUTHENTICATION_APIKEY_ALLOWED_KEYS=WVF5YThaHlkYwhGUSmCRgsX3tD5ngdN8pkih
|
||||
WEAVIATE_AUTHENTICATION_APIKEY_USERS=hello@dify.ai
|
||||
WEAVIATE_AUTHORIZATION_ADMINLIST_ENABLED=true
|
||||
WEAVIATE_AUTHORIZATION_ADMINLIST_USERS=hello@dify.ai
|
||||
WEAVIATE_DISABLE_TELEMETRY=false
|
||||
WEAVIATE_ENABLE_TOKENIZER_GSE=false
|
||||
WEAVIATE_ENABLE_TOKENIZER_KAGOME_JA=false
|
||||
WEAVIATE_ENABLE_TOKENIZER_KAGOME_KR=false
|
||||
|
||||
# ------------------------------
|
||||
# Environment Variables for Chroma
|
||||
@@ -1069,7 +1287,7 @@ NGINX_SSL_PORT=443
|
||||
# and modify the env vars below accordingly.
|
||||
NGINX_SSL_CERT_FILENAME=dify.crt
|
||||
NGINX_SSL_CERT_KEY_FILENAME=dify.key
|
||||
NGINX_SSL_PROTOCOLS=TLSv1.1 TLSv1.2 TLSv1.3
|
||||
NGINX_SSL_PROTOCOLS=TLSv1.2 TLSv1.3
|
||||
|
||||
# Nginx performance tuning
|
||||
NGINX_WORKER_PROCESSES=auto
|
||||
@@ -1108,14 +1326,17 @@ SSRF_DEFAULT_TIME_OUT=5
|
||||
SSRF_DEFAULT_CONNECT_TIME_OUT=5
|
||||
SSRF_DEFAULT_READ_TIME_OUT=5
|
||||
SSRF_DEFAULT_WRITE_TIME_OUT=5
|
||||
SSRF_POOL_MAX_CONNECTIONS=100
|
||||
SSRF_POOL_MAX_KEEPALIVE_CONNECTIONS=20
|
||||
SSRF_POOL_KEEPALIVE_EXPIRY=5.0
|
||||
|
||||
# ------------------------------
|
||||
# docker env var for specifying vector db type at startup
|
||||
# (based on the vector db type, the corresponding docker
|
||||
# docker env var for specifying vector db and metadata db type at startup
|
||||
# (based on the vector db and metadata db type, the corresponding docker
|
||||
# compose profile will be used)
|
||||
# if you want to use unstructured, add ',unstructured' to the end
|
||||
# ------------------------------
|
||||
COMPOSE_PROFILES=${VECTOR_STORE:-weaviate}
|
||||
COMPOSE_PROFILES=${VECTOR_STORE:-weaviate},${DB_TYPE:-postgresql}
|
||||
|
||||
# ------------------------------
|
||||
# Docker Compose Service Expose Host Port Configurations
|
||||
@@ -1164,6 +1385,7 @@ PLUGIN_DAEMON_PORT=5002
|
||||
PLUGIN_DAEMON_KEY=lYkiYYT6owG+71oLerGzA7GXCgOT++6ovaezWAjpCjf+Sjc3ZtU+qUEi
|
||||
PLUGIN_DAEMON_URL=http://plugin_daemon:5002
|
||||
PLUGIN_MAX_PACKAGE_SIZE=52428800
|
||||
PLUGIN_MODEL_SCHEMA_CACHE_TTL=3600
|
||||
PLUGIN_PPROF_ENABLED=false
|
||||
|
||||
PLUGIN_DEBUGGING_HOST=0.0.0.0
|
||||
@@ -1181,12 +1403,16 @@ MARKETPLACE_ENABLED=true
|
||||
MARKETPLACE_API_URL=https://marketplace.dify.ai
|
||||
|
||||
FORCE_VERIFYING_SIGNATURE=true
|
||||
ENFORCE_LANGGENIUS_PLUGIN_SIGNATURES=true
|
||||
|
||||
PLUGIN_STDIO_BUFFER_SIZE=1024
|
||||
PLUGIN_STDIO_MAX_BUFFER_SIZE=5242880
|
||||
|
||||
PLUGIN_PYTHON_ENV_INIT_TIMEOUT=120
|
||||
# Plugin Daemon side timeout (configure to match the API side below)
|
||||
PLUGIN_MAX_EXECUTION_TIMEOUT=600
|
||||
# API side timeout (configure to match the Plugin Daemon side above)
|
||||
PLUGIN_DAEMON_TIMEOUT=600.0
|
||||
# PIP_MIRROR_URL=https://pypi.tuna.tsinghua.edu.cn/simple
|
||||
PIP_MIRROR_URL=
|
||||
|
||||
@@ -1257,15 +1483,78 @@ QUEUE_MONITOR_ALERT_EMAILS=
|
||||
QUEUE_MONITOR_INTERVAL=30
|
||||
|
||||
# Swagger UI configuration
|
||||
SWAGGER_UI_ENABLED=true
|
||||
SWAGGER_UI_ENABLED=false
|
||||
SWAGGER_UI_PATH=/swagger-ui.html
|
||||
|
||||
# Whether to encrypt dataset IDs when exporting DSL files (default: true)
|
||||
# Set to false to export dataset IDs as plain text for easier cross-environment import
|
||||
DSL_EXPORT_ENCRYPT_DATASET_ID=true
|
||||
|
||||
# Maximum number of segments for dataset segments API (0 for unlimited)
|
||||
DATASET_MAX_SEGMENTS_PER_REQUEST=0
|
||||
|
||||
# Celery schedule tasks configuration
|
||||
ENABLE_CLEAN_EMBEDDING_CACHE_TASK=false
|
||||
ENABLE_CLEAN_UNUSED_DATASETS_TASK=false
|
||||
ENABLE_CREATE_TIDB_SERVERLESS_TASK=false
|
||||
ENABLE_UPDATE_TIDB_SERVERLESS_STATUS_TASK=false
|
||||
ENABLE_CLEAN_MESSAGES=false
|
||||
ENABLE_WORKFLOW_RUN_CLEANUP_TASK=false
|
||||
ENABLE_MAIL_CLEAN_DOCUMENT_NOTIFY_TASK=false
|
||||
ENABLE_DATASETS_QUEUE_MONITOR=false
|
||||
ENABLE_CHECK_UPGRADABLE_PLUGIN_TASK=true
|
||||
ENABLE_WORKFLOW_SCHEDULE_POLLER_TASK=true
|
||||
WORKFLOW_SCHEDULE_POLLER_INTERVAL=1
|
||||
WORKFLOW_SCHEDULE_POLLER_BATCH_SIZE=100
|
||||
WORKFLOW_SCHEDULE_MAX_DISPATCH_PER_TICK=0
|
||||
|
||||
# Tenant isolated task queue configuration
|
||||
TENANT_ISOLATED_TASK_CONCURRENCY=1
|
||||
|
||||
# Maximum allowed CSV file size for annotation import in megabytes
|
||||
ANNOTATION_IMPORT_FILE_SIZE_LIMIT=2
|
||||
#Maximum number of annotation records allowed in a single import
|
||||
ANNOTATION_IMPORT_MAX_RECORDS=10000
|
||||
# Minimum number of annotation records required in a single import
|
||||
ANNOTATION_IMPORT_MIN_RECORDS=1
|
||||
ANNOTATION_IMPORT_RATE_LIMIT_PER_MINUTE=5
|
||||
ANNOTATION_IMPORT_RATE_LIMIT_PER_HOUR=20
|
||||
# Maximum number of concurrent annotation import tasks per tenant
|
||||
ANNOTATION_IMPORT_MAX_CONCURRENT=5
|
||||
|
||||
# The API key of amplitude
|
||||
AMPLITUDE_API_KEY=
|
||||
|
||||
# Sandbox expired records clean configuration
|
||||
SANDBOX_EXPIRED_RECORDS_CLEAN_GRACEFUL_PERIOD=21
|
||||
SANDBOX_EXPIRED_RECORDS_CLEAN_BATCH_SIZE=1000
|
||||
SANDBOX_EXPIRED_RECORDS_CLEAN_BATCH_MAX_INTERVAL=200
|
||||
SANDBOX_EXPIRED_RECORDS_RETENTION_DAYS=30
|
||||
|
||||
|
||||
# Redis URL used for PubSub between API and
|
||||
# celery worker
|
||||
# defaults to url constructed from `REDIS_*`
|
||||
# configurations
|
||||
PUBSUB_REDIS_URL=
|
||||
# Pub/sub channel type for streaming events.
|
||||
# valid options are:
|
||||
#
|
||||
# - pubsub: for normal Pub/Sub
|
||||
# - sharded: for sharded Pub/Sub
|
||||
#
|
||||
# It's highly recommended to use sharded Pub/Sub AND redis cluster
|
||||
# for large deployments.
|
||||
PUBSUB_REDIS_CHANNEL_TYPE=pubsub
|
||||
# Whether to use Redis cluster mode while running
|
||||
# PubSub.
|
||||
# It's highly recommended to enable this for large deployments.
|
||||
PUBSUB_REDIS_USE_CLUSTERS=false
|
||||
|
||||
# Whether to Enable human input timeout check task
|
||||
ENABLE_HUMAN_INPUT_TIMEOUT_TASK=true
|
||||
# Human input timeout check interval in minutes
|
||||
HUMAN_INPUT_TIMEOUT_TASK_INTERVAL=1
|
||||
|
||||
|
||||
SANDBOX_EXPIRED_RECORDS_CLEAN_TASK_LOCK_TTL=90000
|
||||
|
||||
+48
-1
@@ -23,6 +23,10 @@ Welcome to the new `docker` directory for deploying Dify using Docker Compose. T
|
||||
- Navigate to the `docker` directory.
|
||||
- Copy the `.env.example` file to a new file named `.env` by running `cp .env.example .env`.
|
||||
- Customize the `.env` file as needed. Refer to the `.env.example` file for detailed configuration options.
|
||||
- **Optional (Recommended for upgrades)**:
|
||||
You may use the environment synchronization tool to help keep your `.env` file aligned with the latest `.env.example` updates, while preserving your custom settings.
|
||||
This is especially useful when upgrading Dify or managing a large, customized `.env` file.
|
||||
See the [Environment Variables Synchronization](#environment-variables-synchronization) section below.
|
||||
1. **Running the Services**:
|
||||
- Execute `docker compose up` from the `docker` directory to start the services.
|
||||
- To specify a vector database, set the `VECTOR_STORE` variable in your `.env` file to your desired vector database service, such as `milvus`, `weaviate`, or `opensearch`.
|
||||
@@ -40,7 +44,9 @@ Welcome to the new `docker` directory for deploying Dify using Docker Compose. T
|
||||
- Ensure the `middleware.env` file is created by running `cp middleware.env.example middleware.env` (refer to the `middleware.env.example` file).
|
||||
1. **Running Middleware Services**:
|
||||
- Navigate to the `docker` directory.
|
||||
- Execute `docker compose -f docker-compose.middleware.yaml --profile weaviate -p dify up -d` to start the middleware services. (Change the profile to other vector database if you are not using weaviate)
|
||||
- Execute `docker compose --env-file middleware.env -f docker-compose.middleware.yaml -p dify up -d` to start PostgreSQL/MySQL (per `DB_TYPE`) plus the bundled Weaviate instance.
|
||||
|
||||
> Compose automatically loads `COMPOSE_PROFILES=${DB_TYPE:-postgresql},weaviate` from `middleware.env`, so no extra `--profile` flags are needed. Adjust variables in `middleware.env` if you want a different combination of services.
|
||||
|
||||
### Migration for Existing Users
|
||||
|
||||
@@ -109,6 +115,47 @@ The `.env.example` file provided in the Docker setup is extensive and covers a w
|
||||
|
||||
- Each service like `nginx`, `redis`, `db`, and vector databases have specific environment variables that are directly referenced in the `docker-compose.yaml`.
|
||||
|
||||
### Environment Variables Synchronization
|
||||
|
||||
When upgrading Dify or pulling the latest changes, new environment variables may be introduced in `.env.example`.
|
||||
|
||||
To help keep your existing `.env` file up to date **without losing your custom values**, an optional environment variables synchronization tool is provided.
|
||||
|
||||
> This tool performs a **one-way synchronization** from `.env.example` to `.env`.
|
||||
> Existing values in `.env` are never overwritten automatically.
|
||||
|
||||
#### `dify-env-sync.sh` (Optional)
|
||||
|
||||
This script compares your current `.env` file with the latest `.env.example` template and helps safely apply new or updated environment variables.
|
||||
|
||||
**What it does**
|
||||
|
||||
- Creates a backup of the current `.env` file before making any changes
|
||||
- Synchronizes newly added environment variables from `.env.example`
|
||||
- Preserves all existing custom values in `.env`
|
||||
- Displays differences and variables removed from `.env.example` for review
|
||||
|
||||
**Backup behavior**
|
||||
|
||||
Before synchronization, the current `.env` file is saved to the `env-backup/` directory with a timestamped filename
|
||||
(e.g. `env-backup/.env.backup_20231218_143022`).
|
||||
|
||||
**When to use**
|
||||
|
||||
- After upgrading Dify to a newer version
|
||||
- When `.env.example` has been updated with new environment variables
|
||||
- When managing a large or heavily customized `.env` file
|
||||
|
||||
**Usage**
|
||||
|
||||
```bash
|
||||
# Grant execution permission (first time only)
|
||||
chmod +x dify-env-sync.sh
|
||||
|
||||
# Run the synchronization
|
||||
./dify-env-sync.sh
|
||||
```
|
||||
|
||||
### Additional Information
|
||||
|
||||
- **Continuous Improvement Phase**: We are actively seeking feedback from the community to refine and enhance the deployment process. As more users adopt this new method, we will continue to make improvements based on your experiences and suggestions.
|
||||
|
||||
Executable
+465
@@ -0,0 +1,465 @@
|
||||
#!/bin/bash
|
||||
|
||||
# ================================================================
|
||||
# Dify Environment Variables Synchronization Script
|
||||
#
|
||||
# Features:
|
||||
# - Synchronize latest settings from .env.example to .env
|
||||
# - Preserve custom settings in existing .env
|
||||
# - Add new environment variables
|
||||
# - Detect removed environment variables
|
||||
# - Create backup files
|
||||
# ================================================================
|
||||
|
||||
set -eo pipefail # Exit on error and pipe failures (safer for complex variable handling)
|
||||
|
||||
# Error handling function
|
||||
# Arguments:
|
||||
# $1 - Line number where error occurred
|
||||
# $2 - Error code
|
||||
handle_error() {
|
||||
local line_no=$1
|
||||
local error_code=$2
|
||||
echo -e "\033[0;31m[ERROR]\033[0m Script error: line $line_no with error code $error_code" >&2
|
||||
echo -e "\033[0;31m[ERROR]\033[0m Debug info: current working directory $(pwd)" >&2
|
||||
exit $error_code
|
||||
}
|
||||
|
||||
# Set error trap
|
||||
trap 'handle_error ${LINENO} $?' ERR
|
||||
|
||||
# Color settings for output
|
||||
readonly RED='\033[0;31m'
|
||||
readonly GREEN='\033[0;32m'
|
||||
readonly YELLOW='\033[1;33m'
|
||||
readonly BLUE='\033[0;34m'
|
||||
readonly NC='\033[0m' # No Color
|
||||
|
||||
# Logging functions
|
||||
# Print informational message in blue
|
||||
# Arguments: $1 - Message to print
|
||||
log_info() {
|
||||
echo -e "${BLUE}[INFO]${NC} $1"
|
||||
}
|
||||
|
||||
# Print success message in green
|
||||
# Arguments: $1 - Message to print
|
||||
log_success() {
|
||||
echo -e "${GREEN}[SUCCESS]${NC} $1"
|
||||
}
|
||||
|
||||
# Print warning message in yellow
|
||||
# Arguments: $1 - Message to print
|
||||
log_warning() {
|
||||
echo -e "${YELLOW}[WARNING]${NC} $1" >&2
|
||||
}
|
||||
|
||||
# Print error message in red to stderr
|
||||
# Arguments: $1 - Message to print
|
||||
log_error() {
|
||||
echo -e "${RED}[ERROR]${NC} $1" >&2
|
||||
}
|
||||
|
||||
# Check for required files and create .env if missing
|
||||
# Verifies that .env.example exists and creates .env from template if needed
|
||||
check_files() {
|
||||
log_info "Checking required files..."
|
||||
|
||||
if [[ ! -f ".env.example" ]]; then
|
||||
log_error ".env.example file not found"
|
||||
exit 1
|
||||
fi
|
||||
|
||||
if [[ ! -f ".env" ]]; then
|
||||
log_warning ".env file does not exist. Creating from .env.example."
|
||||
cp ".env.example" ".env"
|
||||
log_success ".env file created"
|
||||
fi
|
||||
|
||||
log_success "Required files verified"
|
||||
}
|
||||
|
||||
# Create timestamped backup of .env file
|
||||
# Creates env-backup directory if needed and backs up current .env file
|
||||
create_backup() {
|
||||
local timestamp=$(date +"%Y%m%d_%H%M%S")
|
||||
local backup_dir="env-backup"
|
||||
|
||||
# Create backup directory if it doesn't exist
|
||||
if [[ ! -d "$backup_dir" ]]; then
|
||||
mkdir -p "$backup_dir"
|
||||
log_info "Created backup directory: $backup_dir"
|
||||
fi
|
||||
|
||||
if [[ -f ".env" ]]; then
|
||||
local backup_file="${backup_dir}/.env.backup_${timestamp}"
|
||||
cp ".env" "$backup_file"
|
||||
log_success "Backed up existing .env to $backup_file"
|
||||
fi
|
||||
}
|
||||
|
||||
# Detect differences between .env and .env.example (optimized for large files)
|
||||
detect_differences() {
|
||||
log_info "Detecting differences between .env and .env.example..."
|
||||
|
||||
# Create secure temporary directory
|
||||
local temp_dir=$(mktemp -d)
|
||||
local temp_diff="$temp_dir/env_diff"
|
||||
|
||||
# Store diff file path as global variable
|
||||
declare -g DIFF_FILE="$temp_diff"
|
||||
declare -g TEMP_DIR="$temp_dir"
|
||||
|
||||
# Initialize difference file
|
||||
> "$temp_diff"
|
||||
|
||||
# Use awk for efficient comparison (much faster for large files)
|
||||
local diff_count=$(awk -F= '
|
||||
BEGIN { OFS="\x01" }
|
||||
FNR==NR {
|
||||
if (!/^[[:space:]]*#/ && !/^[[:space:]]*$/ && /=/) {
|
||||
gsub(/^[[:space:]]+|[[:space:]]+$/, "", $1)
|
||||
key = $1
|
||||
value = substr($0, index($0,"=")+1)
|
||||
gsub(/^[[:space:]]+|[[:space:]]+$/, "", value)
|
||||
env_values[key] = value
|
||||
}
|
||||
next
|
||||
}
|
||||
{
|
||||
if (!/^[[:space:]]*#/ && !/^[[:space:]]*$/ && /=/) {
|
||||
gsub(/^[[:space:]]+|[[:space:]]+$/, "", $1)
|
||||
key = $1
|
||||
example_value = substr($0, index($0,"=")+1)
|
||||
gsub(/^[[:space:]]+|[[:space:]]+$/, "", example_value)
|
||||
|
||||
if (key in env_values && env_values[key] != example_value) {
|
||||
print key, env_values[key], example_value > "'$temp_diff'"
|
||||
diff_count++
|
||||
}
|
||||
}
|
||||
}
|
||||
END { print diff_count }
|
||||
' .env .env.example)
|
||||
|
||||
if [[ $diff_count -gt 0 ]]; then
|
||||
log_success "Detected differences in $diff_count environment variables"
|
||||
# Show detailed differences
|
||||
show_differences_detail
|
||||
else
|
||||
log_info "No differences detected"
|
||||
fi
|
||||
}
|
||||
|
||||
# Parse environment variable line
|
||||
# Extracts key-value pairs from .env file format lines
|
||||
# Arguments:
|
||||
# $1 - Line to parse
|
||||
# Returns:
|
||||
# 0 - Success, outputs "key|value" format
|
||||
# 1 - Skip (empty line, comment, or invalid format)
|
||||
parse_env_line() {
|
||||
local line="$1"
|
||||
local key=""
|
||||
local value=""
|
||||
|
||||
# Skip empty lines or comment lines
|
||||
[[ -z "$line" || "$line" =~ ^[[:space:]]*# ]] && return 1
|
||||
|
||||
# Split by =
|
||||
if [[ "$line" =~ ^([^=]+)=(.*)$ ]]; then
|
||||
key="${BASH_REMATCH[1]}"
|
||||
value="${BASH_REMATCH[2]}"
|
||||
|
||||
# Remove leading and trailing whitespace
|
||||
key=$(echo "$key" | sed 's/^[[:space:]]*//; s/[[:space:]]*$//')
|
||||
value=$(echo "$value" | sed 's/^[[:space:]]*//; s/[[:space:]]*$//')
|
||||
|
||||
if [[ -n "$key" ]]; then
|
||||
echo "$key|$value"
|
||||
return 0
|
||||
fi
|
||||
fi
|
||||
|
||||
return 1
|
||||
}
|
||||
|
||||
# Show detailed differences
|
||||
show_differences_detail() {
|
||||
log_info ""
|
||||
log_info "=== Environment Variable Differences ==="
|
||||
|
||||
# Read differences from the already created diff file
|
||||
if [[ ! -s "$DIFF_FILE" ]]; then
|
||||
log_info "No differences to display"
|
||||
return
|
||||
fi
|
||||
|
||||
# Display differences
|
||||
local count=1
|
||||
while IFS=$'\x01' read -r key env_value example_value; do
|
||||
echo ""
|
||||
echo -e "${YELLOW}[$count] $key${NC}"
|
||||
echo -e " ${GREEN}.env (current)${NC} : ${env_value}"
|
||||
echo -e " ${BLUE}.env.example (recommended)${NC}: ${example_value}"
|
||||
|
||||
# Analyze value changes
|
||||
analyze_value_change "$env_value" "$example_value"
|
||||
((count++))
|
||||
done < "$DIFF_FILE"
|
||||
|
||||
echo ""
|
||||
log_info "=== Difference Analysis Complete ==="
|
||||
log_info "Note: Consider changing to the recommended values above."
|
||||
log_info "Current implementation preserves .env values."
|
||||
echo ""
|
||||
}
|
||||
|
||||
# Analyze value changes
|
||||
analyze_value_change() {
|
||||
local current_value="$1"
|
||||
local recommended_value="$2"
|
||||
|
||||
# Analyze value characteristics
|
||||
local analysis=""
|
||||
|
||||
# Empty value check
|
||||
if [[ -z "$current_value" && -n "$recommended_value" ]]; then
|
||||
analysis=" ${RED}→ Setting from empty to recommended value${NC}"
|
||||
elif [[ -n "$current_value" && -z "$recommended_value" ]]; then
|
||||
analysis=" ${RED}→ Recommended value changed to empty${NC}"
|
||||
# Numeric check - using arithmetic evaluation for robust comparison
|
||||
elif [[ "$current_value" =~ ^[0-9]+$ && "$recommended_value" =~ ^[0-9]+$ ]]; then
|
||||
# Use arithmetic evaluation to handle leading zeros correctly
|
||||
if (( 10#$current_value < 10#$recommended_value )); then
|
||||
analysis=" ${BLUE}→ Numeric increase (${current_value} < ${recommended_value})${NC}"
|
||||
elif (( 10#$current_value > 10#$recommended_value )); then
|
||||
analysis=" ${YELLOW}→ Numeric decrease (${current_value} > ${recommended_value})${NC}"
|
||||
fi
|
||||
# Boolean check
|
||||
elif [[ "$current_value" =~ ^(true|false)$ && "$recommended_value" =~ ^(true|false)$ ]]; then
|
||||
if [[ "$current_value" != "$recommended_value" ]]; then
|
||||
analysis=" ${BLUE}→ Boolean value change (${current_value} → ${recommended_value})${NC}"
|
||||
fi
|
||||
# URL/endpoint check
|
||||
elif [[ "$current_value" =~ ^https?:// || "$recommended_value" =~ ^https?:// ]]; then
|
||||
analysis=" ${BLUE}→ URL/endpoint change${NC}"
|
||||
# File path check
|
||||
elif [[ "$current_value" =~ ^/ || "$recommended_value" =~ ^/ ]]; then
|
||||
analysis=" ${BLUE}→ File path change${NC}"
|
||||
else
|
||||
# Length comparison
|
||||
local current_len=${#current_value}
|
||||
local recommended_len=${#recommended_value}
|
||||
if [[ $current_len -ne $recommended_len ]]; then
|
||||
analysis=" ${YELLOW}→ String length change (${current_len} → ${recommended_len} characters)${NC}"
|
||||
fi
|
||||
fi
|
||||
|
||||
if [[ -n "$analysis" ]]; then
|
||||
echo -e "$analysis"
|
||||
fi
|
||||
}
|
||||
|
||||
# Synchronize .env file with .env.example while preserving custom values
|
||||
# Creates a new .env file based on .env.example structure, preserving existing custom values
|
||||
# Global variables used: DIFF_FILE, TEMP_DIR
|
||||
sync_env_file() {
|
||||
log_info "Starting partial synchronization of .env file..."
|
||||
|
||||
local new_env_file=".env.new"
|
||||
local preserved_count=0
|
||||
local updated_count=0
|
||||
|
||||
# Pre-process diff file for efficient lookup
|
||||
local lookup_file=""
|
||||
if [[ -f "$DIFF_FILE" && -s "$DIFF_FILE" ]]; then
|
||||
lookup_file="${DIFF_FILE}.lookup"
|
||||
# Create sorted lookup file for fast search
|
||||
sort "$DIFF_FILE" > "$lookup_file"
|
||||
log_info "Created lookup file for $(wc -l < "$DIFF_FILE") preserved values"
|
||||
fi
|
||||
|
||||
# Use AWK for efficient processing (much faster than bash loop for large files)
|
||||
log_info "Processing $(wc -l < .env.example) lines with AWK..."
|
||||
|
||||
local preserved_keys_file="${TEMP_DIR}/preserved_keys"
|
||||
local awk_preserved_count_file="${TEMP_DIR}/awk_preserved_count"
|
||||
local awk_updated_count_file="${TEMP_DIR}/awk_updated_count"
|
||||
|
||||
awk -F'=' -v lookup_file="$lookup_file" -v preserved_file="$preserved_keys_file" \
|
||||
-v preserved_count_file="$awk_preserved_count_file" -v updated_count_file="$awk_updated_count_file" '
|
||||
BEGIN {
|
||||
preserved_count = 0
|
||||
updated_count = 0
|
||||
|
||||
# Load preserved values if lookup file exists
|
||||
if (lookup_file != "") {
|
||||
while ((getline line < lookup_file) > 0) {
|
||||
split(line, parts, "\x01")
|
||||
key = parts[1]
|
||||
value = parts[2]
|
||||
preserved_values[key] = value
|
||||
}
|
||||
close(lookup_file)
|
||||
}
|
||||
}
|
||||
|
||||
# Process each line
|
||||
{
|
||||
# Check if this is an environment variable line
|
||||
if (/^[[:space:]]*[A-Za-z_][A-Za-z0-9_]*[[:space:]]*=/) {
|
||||
# Extract key
|
||||
key = $1
|
||||
gsub(/^[[:space:]]+|[[:space:]]+$/, "", key)
|
||||
|
||||
# Check if key should be preserved
|
||||
if (key in preserved_values) {
|
||||
print key "=" preserved_values[key]
|
||||
print key > preserved_file
|
||||
preserved_count++
|
||||
} else {
|
||||
print $0
|
||||
updated_count++
|
||||
}
|
||||
} else {
|
||||
# Not an env var line, preserve as-is
|
||||
print $0
|
||||
}
|
||||
}
|
||||
|
||||
END {
|
||||
print preserved_count > preserved_count_file
|
||||
print updated_count > updated_count_file
|
||||
}
|
||||
' .env.example > "$new_env_file"
|
||||
|
||||
# Read counters and preserved keys
|
||||
if [[ -f "$awk_preserved_count_file" ]]; then
|
||||
preserved_count=$(cat "$awk_preserved_count_file")
|
||||
fi
|
||||
if [[ -f "$awk_updated_count_file" ]]; then
|
||||
updated_count=$(cat "$awk_updated_count_file")
|
||||
fi
|
||||
|
||||
# Show what was preserved
|
||||
if [[ -f "$preserved_keys_file" ]]; then
|
||||
while read -r key; do
|
||||
[[ -n "$key" ]] && log_info " Preserved: $key (.env value)"
|
||||
done < "$preserved_keys_file"
|
||||
fi
|
||||
|
||||
# Clean up lookup file
|
||||
[[ -n "$lookup_file" ]] && rm -f "$lookup_file"
|
||||
|
||||
# Replace the original .env file
|
||||
if mv "$new_env_file" ".env"; then
|
||||
log_success "Successfully created new .env file"
|
||||
else
|
||||
log_error "Failed to replace .env file"
|
||||
rm -f "$new_env_file"
|
||||
return 1
|
||||
fi
|
||||
|
||||
# Clean up difference file and temporary directory
|
||||
if [[ -n "${TEMP_DIR:-}" ]]; then
|
||||
rm -rf "${TEMP_DIR}"
|
||||
unset TEMP_DIR
|
||||
fi
|
||||
if [[ -n "${DIFF_FILE:-}" ]]; then
|
||||
unset DIFF_FILE
|
||||
fi
|
||||
|
||||
log_success "Partial synchronization of .env file completed"
|
||||
log_info " Preserved .env values: $preserved_count"
|
||||
log_info " Updated to .env.example values: $updated_count"
|
||||
}
|
||||
|
||||
# Detect removed environment variables
|
||||
detect_removed_variables() {
|
||||
log_info "Detecting removed environment variables..."
|
||||
|
||||
if [[ ! -f ".env" ]]; then
|
||||
return
|
||||
fi
|
||||
|
||||
# Use temporary files for efficient lookup
|
||||
local temp_dir="${TEMP_DIR:-$(mktemp -d)}"
|
||||
local temp_example_keys="$temp_dir/example_keys"
|
||||
local temp_current_keys="$temp_dir/current_keys"
|
||||
local cleanup_temp_dir=""
|
||||
|
||||
# Set flag if we created a new temp directory
|
||||
if [[ -z "${TEMP_DIR:-}" ]]; then
|
||||
cleanup_temp_dir="$temp_dir"
|
||||
fi
|
||||
|
||||
# Get keys from .env.example and .env, sorted for comm
|
||||
awk -F= '!/^[[:space:]]*#/ && /=/ {gsub(/^[[:space:]]+|[[:space:]]+$/, "", $1); print $1}' .env.example | sort > "$temp_example_keys"
|
||||
awk -F= '!/^[[:space:]]*#/ && /=/ {gsub(/^[[:space:]]+|[[:space:]]+$/, "", $1); print $1}' .env | sort > "$temp_current_keys"
|
||||
|
||||
# Get keys from existing .env and check for removals
|
||||
local removed_vars=()
|
||||
while IFS= read -r var; do
|
||||
removed_vars+=("$var")
|
||||
done < <(comm -13 "$temp_example_keys" "$temp_current_keys")
|
||||
|
||||
# Clean up temporary files if we created a new temp directory
|
||||
if [[ -n "$cleanup_temp_dir" ]]; then
|
||||
rm -rf "$cleanup_temp_dir"
|
||||
fi
|
||||
|
||||
if [[ ${#removed_vars[@]} -gt 0 ]]; then
|
||||
log_warning "The following environment variables have been removed from .env.example:"
|
||||
for var in "${removed_vars[@]}"; do
|
||||
log_warning " - $var"
|
||||
done
|
||||
log_warning "Consider manually removing these variables from .env"
|
||||
else
|
||||
log_success "No removed environment variables found"
|
||||
fi
|
||||
}
|
||||
|
||||
# Show statistics
|
||||
show_statistics() {
|
||||
log_info "Synchronization statistics:"
|
||||
|
||||
local total_example=$(grep -c "^[^#]*=" .env.example 2>/dev/null || echo "0")
|
||||
local total_env=$(grep -c "^[^#]*=" .env 2>/dev/null || echo "0")
|
||||
|
||||
log_info " .env.example environment variables: $total_example"
|
||||
log_info " .env environment variables: $total_env"
|
||||
}
|
||||
|
||||
# Main execution function
|
||||
# Orchestrates the complete synchronization process in the correct order
|
||||
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
|
||||
@@ -1,8 +1,27 @@
|
||||
x-shared-env: &shared-api-worker-env
|
||||
services:
|
||||
# Init container to fix permissions
|
||||
init_permissions:
|
||||
image: busybox:latest
|
||||
command:
|
||||
- sh
|
||||
- -c
|
||||
- |
|
||||
FLAG_FILE="/app/api/storage/.init_permissions"
|
||||
if [ -f "$${FLAG_FILE}" ]; then
|
||||
echo "Permissions already initialized. Exiting."
|
||||
exit 0
|
||||
fi
|
||||
echo "Initializing permissions for /app/api/storage"
|
||||
chown -R 1001:1001 /app/api/storage && touch "$${FLAG_FILE}"
|
||||
echo "Permissions initialized. Exiting."
|
||||
volumes:
|
||||
- ./volumes/app/storage:/app/api/storage
|
||||
restart: "no"
|
||||
|
||||
# API service
|
||||
api:
|
||||
image: langgenius/dify-api:1.8.0
|
||||
image: langgenius/dify-api:1.13.0
|
||||
restart: always
|
||||
environment:
|
||||
# Use the shared environment variables.
|
||||
@@ -15,10 +34,23 @@ services:
|
||||
PLUGIN_REMOTE_INSTALL_HOST: ${EXPOSE_PLUGIN_DEBUGGING_HOST:-localhost}
|
||||
PLUGIN_REMOTE_INSTALL_PORT: ${EXPOSE_PLUGIN_DEBUGGING_PORT:-5003}
|
||||
PLUGIN_MAX_PACKAGE_SIZE: ${PLUGIN_MAX_PACKAGE_SIZE:-52428800}
|
||||
PLUGIN_DAEMON_TIMEOUT: ${PLUGIN_DAEMON_TIMEOUT:-600.0}
|
||||
INNER_API_KEY_FOR_PLUGIN: ${PLUGIN_DIFY_INNER_API_KEY:-QaHbTe77CtuXmsfyhR7+vRjI/+XbV1AaFy691iy+kGDv2Jvy0/eAh8Y1}
|
||||
depends_on:
|
||||
db:
|
||||
init_permissions:
|
||||
condition: service_completed_successfully
|
||||
db_postgres:
|
||||
condition: service_healthy
|
||||
required: false
|
||||
db_mysql:
|
||||
condition: service_healthy
|
||||
required: false
|
||||
oceanbase:
|
||||
condition: service_healthy
|
||||
required: false
|
||||
seekdb:
|
||||
condition: service_healthy
|
||||
required: false
|
||||
redis:
|
||||
condition: service_started
|
||||
volumes:
|
||||
@@ -29,14 +61,14 @@ services:
|
||||
- default
|
||||
|
||||
# worker service
|
||||
# The Celery worker for processing the queue.
|
||||
# The Celery worker for processing all queues (dataset, workflow, mail, etc.)
|
||||
worker:
|
||||
image: langgenius/dify-api:1.8.0
|
||||
image: langgenius/dify-api:1.13.0
|
||||
restart: always
|
||||
environment:
|
||||
# Use the shared environment variables.
|
||||
<<: *shared-api-worker-env
|
||||
# Startup mode, 'worker' starts the Celery worker for processing the queue.
|
||||
# Startup mode, 'worker' starts the Celery worker for processing all queues.
|
||||
MODE: worker
|
||||
SENTRY_DSN: ${API_SENTRY_DSN:-}
|
||||
SENTRY_TRACES_SAMPLE_RATE: ${API_SENTRY_TRACES_SAMPLE_RATE:-1.0}
|
||||
@@ -44,8 +76,20 @@ services:
|
||||
PLUGIN_MAX_PACKAGE_SIZE: ${PLUGIN_MAX_PACKAGE_SIZE:-52428800}
|
||||
INNER_API_KEY_FOR_PLUGIN: ${PLUGIN_DIFY_INNER_API_KEY:-QaHbTe77CtuXmsfyhR7+vRjI/+XbV1AaFy691iy+kGDv2Jvy0/eAh8Y1}
|
||||
depends_on:
|
||||
db:
|
||||
init_permissions:
|
||||
condition: service_completed_successfully
|
||||
db_postgres:
|
||||
condition: service_healthy
|
||||
required: false
|
||||
db_mysql:
|
||||
condition: service_healthy
|
||||
required: false
|
||||
oceanbase:
|
||||
condition: service_healthy
|
||||
required: false
|
||||
seekdb:
|
||||
condition: service_healthy
|
||||
required: false
|
||||
redis:
|
||||
condition: service_started
|
||||
volumes:
|
||||
@@ -58,7 +102,7 @@ services:
|
||||
# worker_beat service
|
||||
# Celery beat for scheduling periodic tasks.
|
||||
worker_beat:
|
||||
image: langgenius/dify-api:1.8.0
|
||||
image: langgenius/dify-api:1.13.0
|
||||
restart: always
|
||||
environment:
|
||||
# Use the shared environment variables.
|
||||
@@ -66,8 +110,20 @@ services:
|
||||
# Startup mode, 'worker_beat' starts the Celery beat for scheduling periodic tasks.
|
||||
MODE: beat
|
||||
depends_on:
|
||||
db:
|
||||
init_permissions:
|
||||
condition: service_completed_successfully
|
||||
db_postgres:
|
||||
condition: service_healthy
|
||||
required: false
|
||||
db_mysql:
|
||||
condition: service_healthy
|
||||
required: false
|
||||
oceanbase:
|
||||
condition: service_healthy
|
||||
required: false
|
||||
seekdb:
|
||||
condition: service_healthy
|
||||
required: false
|
||||
redis:
|
||||
condition: service_started
|
||||
networks:
|
||||
@@ -76,11 +132,13 @@ services:
|
||||
|
||||
# Frontend web application.
|
||||
web:
|
||||
image: langgenius/dify-web:1.8.0
|
||||
image: langgenius/dify-web:1.13.0
|
||||
restart: always
|
||||
environment:
|
||||
CONSOLE_API_URL: ${CONSOLE_API_URL:-}
|
||||
APP_API_URL: ${APP_API_URL:-}
|
||||
AMPLITUDE_API_KEY: ${AMPLITUDE_API_KEY:-}
|
||||
NEXT_PUBLIC_COOKIE_DOMAIN: ${NEXT_PUBLIC_COOKIE_DOMAIN:-}
|
||||
SENTRY_DSN: ${WEB_SENTRY_DSN:-}
|
||||
NEXT_TELEMETRY_DISABLED: ${NEXT_TELEMETRY_DISABLED:-0}
|
||||
TEXT_GENERATION_TIMEOUT_MS: ${TEXT_GENERATION_TIMEOUT_MS:-60000}
|
||||
@@ -91,7 +149,6 @@ services:
|
||||
MARKETPLACE_URL: ${MARKETPLACE_URL:-https://marketplace.dify.ai}
|
||||
TOP_K_MAX_VALUE: ${TOP_K_MAX_VALUE:-}
|
||||
INDEXING_MAX_SEGMENTATION_TOKENS_LENGTH: ${INDEXING_MAX_SEGMENTATION_TOKENS_LENGTH:-}
|
||||
PM2_INSTANCES: ${PM2_INSTANCES:-2}
|
||||
LOOP_NODE_MAX_COUNT: ${LOOP_NODE_MAX_COUNT:-100}
|
||||
MAX_TOOLS_NUM: ${MAX_TOOLS_NUM:-10}
|
||||
MAX_PARALLEL_LIMIT: ${MAX_PARALLEL_LIMIT:-10}
|
||||
@@ -100,14 +157,17 @@ services:
|
||||
ENABLE_WEBSITE_JINAREADER: ${ENABLE_WEBSITE_JINAREADER:-true}
|
||||
ENABLE_WEBSITE_FIRECRAWL: ${ENABLE_WEBSITE_FIRECRAWL:-true}
|
||||
ENABLE_WEBSITE_WATERCRAWL: ${ENABLE_WEBSITE_WATERCRAWL:-true}
|
||||
# The postgres database.
|
||||
db:
|
||||
|
||||
# The PostgreSQL database.
|
||||
db_postgres:
|
||||
image: postgres:15-alpine
|
||||
profiles:
|
||||
- postgresql
|
||||
restart: always
|
||||
environment:
|
||||
POSTGRES_USER: ${POSTGRES_USER:-postgres}
|
||||
POSTGRES_PASSWORD: ${POSTGRES_PASSWORD:-difyai123456}
|
||||
POSTGRES_DB: ${POSTGRES_DB:-dify}
|
||||
POSTGRES_USER: ${DB_USERNAME:-postgres}
|
||||
POSTGRES_PASSWORD: ${DB_PASSWORD:-difyai123456}
|
||||
POSTGRES_DB: ${DB_DATABASE:-dify}
|
||||
PGDATA: ${PGDATA:-/var/lib/postgresql/data/pgdata}
|
||||
command: >
|
||||
postgres -c 'max_connections=${POSTGRES_MAX_CONNECTIONS:-100}'
|
||||
@@ -115,14 +175,56 @@ services:
|
||||
-c 'work_mem=${POSTGRES_WORK_MEM:-4MB}'
|
||||
-c 'maintenance_work_mem=${POSTGRES_MAINTENANCE_WORK_MEM:-64MB}'
|
||||
-c 'effective_cache_size=${POSTGRES_EFFECTIVE_CACHE_SIZE:-4096MB}'
|
||||
-c 'statement_timeout=${POSTGRES_STATEMENT_TIMEOUT:-0}'
|
||||
-c 'idle_in_transaction_session_timeout=${POSTGRES_IDLE_IN_TRANSACTION_SESSION_TIMEOUT:-0}'
|
||||
volumes:
|
||||
- ./volumes/db/data:/var/lib/postgresql/data
|
||||
healthcheck:
|
||||
test: [ 'CMD', 'pg_isready', '-h', 'db', '-U', '${PGUSER:-postgres}', '-d', '${POSTGRES_DB:-dify}' ]
|
||||
test:
|
||||
[
|
||||
"CMD",
|
||||
"pg_isready",
|
||||
"-h",
|
||||
"db_postgres",
|
||||
"-U",
|
||||
"${DB_USERNAME:-postgres}",
|
||||
"-d",
|
||||
"${DB_DATABASE:-dify}",
|
||||
]
|
||||
interval: 1s
|
||||
timeout: 3s
|
||||
retries: 60
|
||||
|
||||
# The mysql database.
|
||||
db_mysql:
|
||||
image: mysql:8.0
|
||||
profiles:
|
||||
- mysql
|
||||
restart: always
|
||||
environment:
|
||||
MYSQL_ROOT_PASSWORD: ${DB_PASSWORD:-difyai123456}
|
||||
MYSQL_DATABASE: ${DB_DATABASE:-dify}
|
||||
command: >
|
||||
--max_connections=1000
|
||||
--innodb_buffer_pool_size=${MYSQL_INNODB_BUFFER_POOL_SIZE:-512M}
|
||||
--innodb_log_file_size=${MYSQL_INNODB_LOG_FILE_SIZE:-128M}
|
||||
--innodb_flush_log_at_trx_commit=${MYSQL_INNODB_FLUSH_LOG_AT_TRX_COMMIT:-2}
|
||||
volumes:
|
||||
- ${MYSQL_HOST_VOLUME:-./volumes/mysql/data}:/var/lib/mysql
|
||||
healthcheck:
|
||||
test:
|
||||
[
|
||||
"CMD",
|
||||
"mysqladmin",
|
||||
"ping",
|
||||
"-u",
|
||||
"root",
|
||||
"-p${DB_PASSWORD:-difyai123456}",
|
||||
]
|
||||
interval: 1s
|
||||
timeout: 3s
|
||||
retries: 30
|
||||
|
||||
# The redis cache.
|
||||
redis:
|
||||
image: redis:6-alpine
|
||||
@@ -135,7 +237,11 @@ services:
|
||||
# Set the redis password when startup redis server.
|
||||
command: redis-server --requirepass ${REDIS_PASSWORD:-difyai123456}
|
||||
healthcheck:
|
||||
test: [ 'CMD', 'redis-cli', 'ping' ]
|
||||
test:
|
||||
[
|
||||
"CMD-SHELL",
|
||||
"redis-cli -a ${REDIS_PASSWORD:-difyai123456} ping | grep -q PONG",
|
||||
]
|
||||
|
||||
# The DifySandbox
|
||||
sandbox:
|
||||
@@ -157,13 +263,13 @@ services:
|
||||
- ./volumes/sandbox/dependencies:/dependencies
|
||||
- ./volumes/sandbox/conf:/conf
|
||||
healthcheck:
|
||||
test: [ 'CMD', 'curl', '-f', 'http://localhost:8194/health' ]
|
||||
test: ["CMD", "curl", "-f", "http://localhost:8194/health"]
|
||||
networks:
|
||||
- ssrf_proxy_network
|
||||
|
||||
# plugin daemon
|
||||
plugin_daemon:
|
||||
image: langgenius/dify-plugin-daemon:0.2.0-local
|
||||
image: langgenius/dify-plugin-daemon:0.5.3-local
|
||||
restart: always
|
||||
environment:
|
||||
# Use the shared environment variables.
|
||||
@@ -219,8 +325,18 @@ services:
|
||||
volumes:
|
||||
- ./volumes/plugin_daemon:/app/storage
|
||||
depends_on:
|
||||
db:
|
||||
db_postgres:
|
||||
condition: service_healthy
|
||||
required: false
|
||||
db_mysql:
|
||||
condition: service_healthy
|
||||
required: false
|
||||
oceanbase:
|
||||
condition: service_healthy
|
||||
required: false
|
||||
seekdb:
|
||||
condition: service_healthy
|
||||
required: false
|
||||
|
||||
# ssrf_proxy server
|
||||
# for more information, please refer to
|
||||
@@ -231,7 +347,12 @@ services:
|
||||
volumes:
|
||||
- ./ssrf_proxy/squid.conf.template:/etc/squid/squid.conf.template
|
||||
- ./ssrf_proxy/docker-entrypoint.sh:/docker-entrypoint-mount.sh
|
||||
entrypoint: [ 'sh', '-c', "cp /docker-entrypoint-mount.sh /docker-entrypoint.sh && sed -i 's/\r$$//' /docker-entrypoint.sh && chmod +x /docker-entrypoint.sh && /docker-entrypoint.sh" ]
|
||||
entrypoint:
|
||||
[
|
||||
"sh",
|
||||
"-c",
|
||||
"cp /docker-entrypoint-mount.sh /docker-entrypoint.sh && sed -i 's/\r$$//' /docker-entrypoint.sh && chmod +x /docker-entrypoint.sh && /docker-entrypoint.sh",
|
||||
]
|
||||
environment:
|
||||
# pls clearly modify the squid env vars to fit your network environment.
|
||||
HTTP_PORT: ${SSRF_HTTP_PORT:-3128}
|
||||
@@ -260,8 +381,8 @@ services:
|
||||
- CERTBOT_EMAIL=${CERTBOT_EMAIL}
|
||||
- CERTBOT_DOMAIN=${CERTBOT_DOMAIN}
|
||||
- CERTBOT_OPTIONS=${CERTBOT_OPTIONS:-}
|
||||
entrypoint: [ '/docker-entrypoint.sh' ]
|
||||
command: [ 'tail', '-f', '/dev/null' ]
|
||||
entrypoint: ["/docker-entrypoint.sh"]
|
||||
command: ["tail", "-f", "/dev/null"]
|
||||
|
||||
# The nginx reverse proxy.
|
||||
# used for reverse proxying the API service and Web service.
|
||||
@@ -278,7 +399,12 @@ services:
|
||||
- ./volumes/certbot/conf/live:/etc/letsencrypt/live # cert dir (with certbot container)
|
||||
- ./volumes/certbot/conf:/etc/letsencrypt
|
||||
- ./volumes/certbot/www:/var/www/html
|
||||
entrypoint: [ 'sh', '-c', "cp /docker-entrypoint-mount.sh /docker-entrypoint.sh && sed -i 's/\r$$//' /docker-entrypoint.sh && chmod +x /docker-entrypoint.sh && /docker-entrypoint.sh" ]
|
||||
entrypoint:
|
||||
[
|
||||
"sh",
|
||||
"-c",
|
||||
"cp /docker-entrypoint-mount.sh /docker-entrypoint.sh && sed -i 's/\r$$//' /docker-entrypoint.sh && chmod +x /docker-entrypoint.sh && /docker-entrypoint.sh",
|
||||
]
|
||||
environment:
|
||||
NGINX_SERVER_NAME: ${NGINX_SERVER_NAME:-_}
|
||||
NGINX_HTTPS_ENABLED: ${NGINX_HTTPS_ENABLED:-false}
|
||||
@@ -288,7 +414,7 @@ services:
|
||||
# and modify the env vars below in .env if HTTPS_ENABLED is true.
|
||||
NGINX_SSL_CERT_FILENAME: ${NGINX_SSL_CERT_FILENAME:-dify.crt}
|
||||
NGINX_SSL_CERT_KEY_FILENAME: ${NGINX_SSL_CERT_KEY_FILENAME:-dify.key}
|
||||
NGINX_SSL_PROTOCOLS: ${NGINX_SSL_PROTOCOLS:-TLSv1.1 TLSv1.2 TLSv1.3}
|
||||
NGINX_SSL_PROTOCOLS: ${NGINX_SSL_PROTOCOLS:-TLSv1.2 TLSv1.3}
|
||||
NGINX_WORKER_PROCESSES: ${NGINX_WORKER_PROCESSES:-auto}
|
||||
NGINX_CLIENT_MAX_BODY_SIZE: ${NGINX_CLIENT_MAX_BODY_SIZE:-100M}
|
||||
NGINX_KEEPALIVE_TIMEOUT: ${NGINX_KEEPALIVE_TIMEOUT:-65}
|
||||
@@ -300,14 +426,13 @@ services:
|
||||
- api
|
||||
- web
|
||||
ports:
|
||||
- '${EXPOSE_NGINX_PORT:-80}:${NGINX_PORT:-80}'
|
||||
- '${EXPOSE_NGINX_SSL_PORT:-443}:${NGINX_SSL_PORT:-443}'
|
||||
- "${EXPOSE_NGINX_PORT:-80}:${NGINX_PORT:-80}"
|
||||
- "${EXPOSE_NGINX_SSL_PORT:-443}:${NGINX_SSL_PORT:-443}"
|
||||
|
||||
# The Weaviate vector store.
|
||||
weaviate:
|
||||
image: semitechnologies/weaviate:1.19.0
|
||||
image: semitechnologies/weaviate:1.27.0
|
||||
profiles:
|
||||
- ''
|
||||
- weaviate
|
||||
restart: always
|
||||
volumes:
|
||||
@@ -326,11 +451,73 @@ services:
|
||||
AUTHENTICATION_APIKEY_USERS: ${WEAVIATE_AUTHENTICATION_APIKEY_USERS:-hello@dify.ai}
|
||||
AUTHORIZATION_ADMINLIST_ENABLED: ${WEAVIATE_AUTHORIZATION_ADMINLIST_ENABLED:-true}
|
||||
AUTHORIZATION_ADMINLIST_USERS: ${WEAVIATE_AUTHORIZATION_ADMINLIST_USERS:-hello@dify.ai}
|
||||
DISABLE_TELEMETRY: ${WEAVIATE_DISABLE_TELEMETRY:-false}
|
||||
ENABLE_TOKENIZER_GSE: ${WEAVIATE_ENABLE_TOKENIZER_GSE:-false}
|
||||
ENABLE_TOKENIZER_KAGOME_JA: ${WEAVIATE_ENABLE_TOKENIZER_KAGOME_JA:-false}
|
||||
ENABLE_TOKENIZER_KAGOME_KR: ${WEAVIATE_ENABLE_TOKENIZER_KAGOME_KR:-false}
|
||||
|
||||
# OceanBase vector database
|
||||
oceanbase:
|
||||
image: oceanbase/oceanbase-ce:4.3.5-lts
|
||||
container_name: oceanbase
|
||||
profiles:
|
||||
- oceanbase
|
||||
restart: always
|
||||
volumes:
|
||||
- ./volumes/oceanbase/data:/root/ob
|
||||
- ./volumes/oceanbase/conf:/root/.obd/cluster
|
||||
- ./volumes/oceanbase/init.d:/root/boot/init.d
|
||||
environment:
|
||||
OB_MEMORY_LIMIT: ${OCEANBASE_MEMORY_LIMIT:-6G}
|
||||
OB_SYS_PASSWORD: ${OCEANBASE_VECTOR_PASSWORD:-difyai123456}
|
||||
OB_TENANT_PASSWORD: ${OCEANBASE_VECTOR_PASSWORD:-difyai123456}
|
||||
OB_CLUSTER_NAME: ${OCEANBASE_CLUSTER_NAME:-difyai}
|
||||
OB_SERVER_IP: 127.0.0.1
|
||||
MODE: mini
|
||||
LANG: C.UTF-8
|
||||
LC_ALL: C.UTF-8
|
||||
ports:
|
||||
- "${OCEANBASE_VECTOR_PORT:-2881}:2881"
|
||||
healthcheck:
|
||||
test:
|
||||
[
|
||||
"CMD-SHELL",
|
||||
'obclient -h127.0.0.1 -P2881 -uroot@test -p${OCEANBASE_VECTOR_PASSWORD:-difyai123456} -e "SELECT 1;"',
|
||||
]
|
||||
interval: 10s
|
||||
retries: 30
|
||||
start_period: 30s
|
||||
timeout: 10s
|
||||
|
||||
# seekdb vector database
|
||||
seekdb:
|
||||
image: oceanbase/seekdb:latest
|
||||
container_name: seekdb
|
||||
profiles:
|
||||
- seekdb
|
||||
restart: always
|
||||
volumes:
|
||||
- ./volumes/seekdb:/var/lib/oceanbase
|
||||
environment:
|
||||
ROOT_PASSWORD: ${OCEANBASE_VECTOR_PASSWORD:-difyai123456}
|
||||
MEMORY_LIMIT: ${SEEKDB_MEMORY_LIMIT:-2G}
|
||||
REPORTER: dify-ai-seekdb
|
||||
ports:
|
||||
- "${OCEANBASE_VECTOR_PORT:-2881}:2881"
|
||||
healthcheck:
|
||||
test:
|
||||
[
|
||||
"CMD-SHELL",
|
||||
'mysql -h127.0.0.1 -P2881 -uroot -p${OCEANBASE_VECTOR_PASSWORD:-difyai123456} -e "SELECT 1;"',
|
||||
]
|
||||
interval: 5s
|
||||
retries: 60
|
||||
timeout: 5s
|
||||
|
||||
# Qdrant vector store.
|
||||
# (if used, you need to set VECTOR_STORE to qdrant in the api & worker service.)
|
||||
qdrant:
|
||||
image: langgenius/qdrant:v1.7.3
|
||||
image: langgenius/qdrant:v1.8.3
|
||||
profiles:
|
||||
- qdrant
|
||||
restart: always
|
||||
@@ -360,13 +547,17 @@ services:
|
||||
working_dir: /opt/couchbase
|
||||
stdin_open: true
|
||||
tty: true
|
||||
entrypoint: [ "" ]
|
||||
entrypoint: [""]
|
||||
command: sh -c "/opt/couchbase/init/init-cbserver.sh"
|
||||
volumes:
|
||||
- ./volumes/couchbase/data:/opt/couchbase/var/lib/couchbase/data
|
||||
healthcheck:
|
||||
# ensure bucket was created before proceeding
|
||||
test: [ "CMD-SHELL", "curl -s -f -u Administrator:password http://localhost:8091/pools/default/buckets | grep -q '\\[{' || exit 1" ]
|
||||
test:
|
||||
[
|
||||
"CMD-SHELL",
|
||||
"curl -s -f -u Administrator:password http://localhost:8091/pools/default/buckets | grep -q '\\[{' || exit 1",
|
||||
]
|
||||
interval: 10s
|
||||
retries: 10
|
||||
start_period: 30s
|
||||
@@ -392,9 +583,9 @@ services:
|
||||
volumes:
|
||||
- ./volumes/pgvector/data:/var/lib/postgresql/data
|
||||
- ./pgvector/docker-entrypoint.sh:/docker-entrypoint.sh
|
||||
entrypoint: [ '/docker-entrypoint.sh' ]
|
||||
entrypoint: ["/docker-entrypoint.sh"]
|
||||
healthcheck:
|
||||
test: [ 'CMD', 'pg_isready' ]
|
||||
test: ["CMD", "pg_isready"]
|
||||
interval: 1s
|
||||
timeout: 3s
|
||||
retries: 30
|
||||
@@ -411,14 +602,14 @@ services:
|
||||
- VB_USERNAME=dify
|
||||
- VB_PASSWORD=Difyai123456
|
||||
ports:
|
||||
- '5434:5432'
|
||||
- "5434:5432"
|
||||
volumes:
|
||||
- ./vastbase/lic:/home/vastbase/vastbase/lic
|
||||
- ./vastbase/data:/home/vastbase/data
|
||||
- ./vastbase/backup:/home/vastbase/backup
|
||||
- ./vastbase/backup_log:/home/vastbase/backup_log
|
||||
healthcheck:
|
||||
test: [ 'CMD', 'pg_isready' ]
|
||||
test: ["CMD", "pg_isready"]
|
||||
interval: 1s
|
||||
timeout: 3s
|
||||
retries: 30
|
||||
@@ -440,7 +631,7 @@ services:
|
||||
volumes:
|
||||
- ./volumes/pgvecto_rs/data:/var/lib/postgresql/data
|
||||
healthcheck:
|
||||
test: [ 'CMD', 'pg_isready' ]
|
||||
test: ["CMD", "pg_isready"]
|
||||
interval: 1s
|
||||
timeout: 3s
|
||||
retries: 30
|
||||
@@ -458,32 +649,26 @@ services:
|
||||
CHROMA_SERVER_AUTHN_PROVIDER: ${CHROMA_SERVER_AUTHN_PROVIDER:-chromadb.auth.token_authn.TokenAuthenticationServerProvider}
|
||||
IS_PERSISTENT: ${CHROMA_IS_PERSISTENT:-TRUE}
|
||||
|
||||
# OceanBase vector database
|
||||
oceanbase:
|
||||
image: oceanbase/oceanbase-ce:4.3.5-lts
|
||||
container_name: oceanbase
|
||||
# InterSystems IRIS vector database
|
||||
iris:
|
||||
image: containers.intersystems.com/intersystems/iris-community:2025.3
|
||||
profiles:
|
||||
- oceanbase
|
||||
- iris
|
||||
container_name: iris
|
||||
restart: always
|
||||
volumes:
|
||||
- ./volumes/oceanbase/data:/root/ob
|
||||
- ./volumes/oceanbase/conf:/root/.obd/cluster
|
||||
- ./volumes/oceanbase/init.d:/root/boot/init.d
|
||||
environment:
|
||||
OB_MEMORY_LIMIT: ${OCEANBASE_MEMORY_LIMIT:-6G}
|
||||
OB_SYS_PASSWORD: ${OCEANBASE_VECTOR_PASSWORD:-difyai123456}
|
||||
OB_TENANT_PASSWORD: ${OCEANBASE_VECTOR_PASSWORD:-difyai123456}
|
||||
OB_CLUSTER_NAME: ${OCEANBASE_CLUSTER_NAME:-difyai}
|
||||
OB_SERVER_IP: 127.0.0.1
|
||||
MODE: mini
|
||||
init: true
|
||||
ports:
|
||||
- "${OCEANBASE_VECTOR_PORT:-2881}:2881"
|
||||
healthcheck:
|
||||
test: [ 'CMD-SHELL', 'obclient -h127.0.0.1 -P2881 -uroot@test -p$${OB_TENANT_PASSWORD} -e "SELECT 1;"' ]
|
||||
interval: 10s
|
||||
retries: 30
|
||||
start_period: 30s
|
||||
timeout: 10s
|
||||
- "${IRIS_SUPER_SERVER_PORT:-1972}:1972"
|
||||
- "${IRIS_WEB_SERVER_PORT:-52773}:52773"
|
||||
volumes:
|
||||
- ./volumes/iris:/durable
|
||||
- ./iris/iris-init.script:/iris-init.script
|
||||
- ./iris/docker-entrypoint.sh:/custom-entrypoint.sh
|
||||
entrypoint: ["/custom-entrypoint.sh"]
|
||||
tty: true
|
||||
environment:
|
||||
TZ: ${IRIS_TIMEZONE:-UTC}
|
||||
ISC_DATA_DIRECTORY: /durable/iris
|
||||
|
||||
# Oracle vector database
|
||||
oracle:
|
||||
@@ -515,7 +700,7 @@ services:
|
||||
- ./volumes/milvus/etcd:/etcd
|
||||
command: etcd -advertise-client-urls=http://127.0.0.1:2379 -listen-client-urls http://0.0.0.0:2379 --data-dir /etcd
|
||||
healthcheck:
|
||||
test: [ 'CMD', 'etcdctl', 'endpoint', 'health' ]
|
||||
test: ["CMD", "etcdctl", "endpoint", "health"]
|
||||
interval: 30s
|
||||
timeout: 20s
|
||||
retries: 3
|
||||
@@ -534,7 +719,7 @@ services:
|
||||
- ./volumes/milvus/minio:/minio_data
|
||||
command: minio server /minio_data --console-address ":9001"
|
||||
healthcheck:
|
||||
test: [ 'CMD', 'curl', '-f', 'http://localhost:9000/minio/health/live' ]
|
||||
test: ["CMD", "curl", "-f", "http://localhost:9000/minio/health/live"]
|
||||
interval: 30s
|
||||
timeout: 20s
|
||||
retries: 3
|
||||
@@ -543,10 +728,10 @@ services:
|
||||
|
||||
milvus-standalone:
|
||||
container_name: milvus-standalone
|
||||
image: milvusdb/milvus:v2.5.15
|
||||
image: milvusdb/milvus:v2.6.3
|
||||
profiles:
|
||||
- milvus
|
||||
command: [ 'milvus', 'run', 'standalone' ]
|
||||
command: ["milvus", "run", "standalone"]
|
||||
environment:
|
||||
ETCD_ENDPOINTS: ${ETCD_ENDPOINTS:-etcd:2379}
|
||||
MINIO_ADDRESS: ${MINIO_ADDRESS:-minio:9000}
|
||||
@@ -554,7 +739,7 @@ services:
|
||||
volumes:
|
||||
- ./volumes/milvus/milvus:/var/lib/milvus
|
||||
healthcheck:
|
||||
test: [ 'CMD', 'curl', '-f', 'http://localhost:9091/healthz' ]
|
||||
test: ["CMD", "curl", "-f", "http://localhost:9091/healthz"]
|
||||
interval: 30s
|
||||
start_period: 90s
|
||||
timeout: 20s
|
||||
@@ -620,7 +805,7 @@ services:
|
||||
volumes:
|
||||
- ./volumes/opengauss/data:/var/lib/opengauss/data
|
||||
healthcheck:
|
||||
test: [ "CMD-SHELL", "netstat -lntp | grep tcp6 > /dev/null 2>&1" ]
|
||||
test: ["CMD-SHELL", "netstat -lntp | grep tcp6 > /dev/null 2>&1"]
|
||||
interval: 10s
|
||||
timeout: 10s
|
||||
retries: 10
|
||||
@@ -673,18 +858,19 @@ services:
|
||||
node.name: dify-es0
|
||||
discovery.type: single-node
|
||||
xpack.license.self_generated.type: basic
|
||||
xpack.security.enabled: 'true'
|
||||
xpack.security.enrollment.enabled: 'false'
|
||||
xpack.security.http.ssl.enabled: 'false'
|
||||
xpack.security.enabled: "true"
|
||||
xpack.security.enrollment.enabled: "false"
|
||||
xpack.security.http.ssl.enabled: "false"
|
||||
ports:
|
||||
- ${ELASTICSEARCH_PORT:-9200}:9200
|
||||
deploy:
|
||||
resources:
|
||||
limits:
|
||||
memory: 2g
|
||||
entrypoint: [ 'sh', '-c', "sh /docker-entrypoint-mount.sh" ]
|
||||
entrypoint: ["sh", "-c", "sh /docker-entrypoint-mount.sh"]
|
||||
healthcheck:
|
||||
test: [ 'CMD', 'curl', '-s', 'http://localhost:9200/_cluster/health?pretty' ]
|
||||
test:
|
||||
["CMD", "curl", "-s", "http://localhost:9200/_cluster/health?pretty"]
|
||||
interval: 30s
|
||||
timeout: 10s
|
||||
retries: 50
|
||||
@@ -702,17 +888,17 @@ services:
|
||||
environment:
|
||||
XPACK_ENCRYPTEDSAVEDOBJECTS_ENCRYPTIONKEY: d1a66dfd-c4d3-4a0a-8290-2abcb83ab3aa
|
||||
NO_PROXY: localhost,127.0.0.1,elasticsearch,kibana
|
||||
XPACK_SECURITY_ENABLED: 'true'
|
||||
XPACK_SECURITY_ENROLLMENT_ENABLED: 'false'
|
||||
XPACK_SECURITY_HTTP_SSL_ENABLED: 'false'
|
||||
XPACK_FLEET_ISAIRGAPPED: 'true'
|
||||
XPACK_SECURITY_ENABLED: "true"
|
||||
XPACK_SECURITY_ENROLLMENT_ENABLED: "false"
|
||||
XPACK_SECURITY_HTTP_SSL_ENABLED: "false"
|
||||
XPACK_FLEET_ISAIRGAPPED: "true"
|
||||
I18N_LOCALE: zh-CN
|
||||
SERVER_PORT: '5601'
|
||||
SERVER_PORT: "5601"
|
||||
ELASTICSEARCH_HOSTS: http://elasticsearch:9200
|
||||
ports:
|
||||
- ${KIBANA_PORT:-5601}:5601
|
||||
healthcheck:
|
||||
test: [ 'CMD-SHELL', 'curl -s http://localhost:5601 >/dev/null || exit 1' ]
|
||||
test: ["CMD-SHELL", "curl -s http://localhost:5601 >/dev/null || exit 1"]
|
||||
interval: 30s
|
||||
timeout: 10s
|
||||
retries: 3
|
||||
|
||||
@@ -1,13 +1,16 @@
|
||||
services:
|
||||
# The postgres database.
|
||||
db:
|
||||
db_postgres:
|
||||
image: postgres:15-alpine
|
||||
profiles:
|
||||
- ""
|
||||
- postgresql
|
||||
restart: always
|
||||
env_file:
|
||||
- ./middleware.env
|
||||
environment:
|
||||
POSTGRES_PASSWORD: ${POSTGRES_PASSWORD:-difyai123456}
|
||||
POSTGRES_DB: ${POSTGRES_DB:-dify}
|
||||
POSTGRES_PASSWORD: ${DB_PASSWORD:-difyai123456}
|
||||
POSTGRES_DB: ${DB_DATABASE:-dify}
|
||||
PGDATA: ${PGDATA:-/var/lib/postgresql/data/pgdata}
|
||||
command: >
|
||||
postgres -c 'max_connections=${POSTGRES_MAX_CONNECTIONS:-100}'
|
||||
@@ -15,12 +18,57 @@ services:
|
||||
-c 'work_mem=${POSTGRES_WORK_MEM:-4MB}'
|
||||
-c 'maintenance_work_mem=${POSTGRES_MAINTENANCE_WORK_MEM:-64MB}'
|
||||
-c 'effective_cache_size=${POSTGRES_EFFECTIVE_CACHE_SIZE:-4096MB}'
|
||||
-c 'statement_timeout=${POSTGRES_STATEMENT_TIMEOUT:-0}'
|
||||
-c 'idle_in_transaction_session_timeout=${POSTGRES_IDLE_IN_TRANSACTION_SESSION_TIMEOUT:-0}'
|
||||
volumes:
|
||||
- ${PGDATA_HOST_VOLUME:-./volumes/db/data}:/var/lib/postgresql/data
|
||||
ports:
|
||||
- "${EXPOSE_POSTGRES_PORT:-5432}:5432"
|
||||
healthcheck:
|
||||
test: [ 'CMD', 'pg_isready', '-h', 'db', '-U', '${PGUSER:-postgres}', '-d', '${POSTGRES_DB:-dify}' ]
|
||||
test:
|
||||
[
|
||||
"CMD",
|
||||
"pg_isready",
|
||||
"-h",
|
||||
"db_postgres",
|
||||
"-U",
|
||||
"${DB_USERNAME:-postgres}",
|
||||
"-d",
|
||||
"${DB_DATABASE:-dify}",
|
||||
]
|
||||
interval: 1s
|
||||
timeout: 3s
|
||||
retries: 30
|
||||
|
||||
db_mysql:
|
||||
image: mysql:8.0
|
||||
profiles:
|
||||
- mysql
|
||||
restart: always
|
||||
env_file:
|
||||
- ./middleware.env
|
||||
environment:
|
||||
MYSQL_ROOT_PASSWORD: ${DB_PASSWORD:-difyai123456}
|
||||
MYSQL_DATABASE: ${DB_DATABASE:-dify}
|
||||
command: >
|
||||
--max_connections=1000
|
||||
--innodb_buffer_pool_size=${MYSQL_INNODB_BUFFER_POOL_SIZE:-512M}
|
||||
--innodb_log_file_size=${MYSQL_INNODB_LOG_FILE_SIZE:-128M}
|
||||
--innodb_flush_log_at_trx_commit=${MYSQL_INNODB_FLUSH_LOG_AT_TRX_COMMIT:-2}
|
||||
volumes:
|
||||
- ${MYSQL_HOST_VOLUME:-./volumes/mysql/data}:/var/lib/mysql
|
||||
ports:
|
||||
- "${EXPOSE_MYSQL_PORT:-3306}:3306"
|
||||
healthcheck:
|
||||
test:
|
||||
[
|
||||
"CMD",
|
||||
"mysqladmin",
|
||||
"ping",
|
||||
"-u",
|
||||
"root",
|
||||
"-p${DB_PASSWORD:-difyai123456}",
|
||||
]
|
||||
interval: 1s
|
||||
timeout: 3s
|
||||
retries: 30
|
||||
@@ -41,7 +89,11 @@ services:
|
||||
ports:
|
||||
- "${EXPOSE_REDIS_PORT:-6379}:6379"
|
||||
healthcheck:
|
||||
test: [ "CMD", "redis-cli", "ping" ]
|
||||
test:
|
||||
[
|
||||
"CMD-SHELL",
|
||||
"redis-cli -a ${REDIS_PASSWORD:-difyai123456} ping | grep -q PONG",
|
||||
]
|
||||
|
||||
# The DifySandbox
|
||||
sandbox:
|
||||
@@ -65,22 +117,19 @@ services:
|
||||
- ./volumes/sandbox/dependencies:/dependencies
|
||||
- ./volumes/sandbox/conf:/conf
|
||||
healthcheck:
|
||||
test: [ "CMD", "curl", "-f", "http://localhost:8194/health" ]
|
||||
test: ["CMD", "curl", "-f", "http://localhost:8194/health"]
|
||||
networks:
|
||||
- ssrf_proxy_network
|
||||
|
||||
# plugin daemon
|
||||
plugin_daemon:
|
||||
image: langgenius/dify-plugin-daemon:0.2.0-local
|
||||
image: langgenius/dify-plugin-daemon:0.5.3-local
|
||||
restart: always
|
||||
env_file:
|
||||
- ./middleware.env
|
||||
environment:
|
||||
# Use the shared environment variables.
|
||||
DB_HOST: ${DB_HOST:-db}
|
||||
DB_PORT: ${DB_PORT:-5432}
|
||||
DB_USERNAME: ${DB_USER:-postgres}
|
||||
DB_PASSWORD: ${DB_PASSWORD:-difyai123456}
|
||||
LOG_OUTPUT_FORMAT: ${LOG_OUTPUT_FORMAT:-text}
|
||||
DB_DATABASE: ${DB_PLUGIN_DATABASE:-dify_plugin}
|
||||
REDIS_HOST: ${REDIS_HOST:-redis}
|
||||
REDIS_PORT: ${REDIS_PORT:-6379}
|
||||
@@ -94,7 +143,6 @@ services:
|
||||
PLUGIN_REMOTE_INSTALLING_HOST: ${PLUGIN_DEBUGGING_HOST:-0.0.0.0}
|
||||
PLUGIN_REMOTE_INSTALLING_PORT: ${PLUGIN_DEBUGGING_PORT:-5003}
|
||||
PLUGIN_WORKING_PATH: ${PLUGIN_WORKING_PATH:-/app/storage/cwd}
|
||||
FORCE_VERIFYING_SIGNATURE: ${FORCE_VERIFYING_SIGNATURE:-true}
|
||||
PYTHON_ENV_INIT_TIMEOUT: ${PLUGIN_PYTHON_ENV_INIT_TIMEOUT:-120}
|
||||
PLUGIN_MAX_EXECUTION_TIMEOUT: ${PLUGIN_MAX_EXECUTION_TIMEOUT:-600}
|
||||
PIP_MIRROR_URL: ${PIP_MIRROR_URL:-}
|
||||
@@ -126,6 +174,9 @@ services:
|
||||
VOLCENGINE_TOS_ACCESS_KEY: ${PLUGIN_VOLCENGINE_TOS_ACCESS_KEY:-}
|
||||
VOLCENGINE_TOS_SECRET_KEY: ${PLUGIN_VOLCENGINE_TOS_SECRET_KEY:-}
|
||||
VOLCENGINE_TOS_REGION: ${PLUGIN_VOLCENGINE_TOS_REGION:-}
|
||||
THIRD_PARTY_SIGNATURE_VERIFICATION_ENABLED: true
|
||||
THIRD_PARTY_SIGNATURE_VERIFICATION_PUBLIC_KEYS: /app/keys/publickey.pem
|
||||
FORCE_VERIFYING_SIGNATURE: false
|
||||
ports:
|
||||
- "${EXPOSE_PLUGIN_DAEMON_PORT:-5002}:${PLUGIN_DAEMON_PORT:-5002}"
|
||||
- "${EXPOSE_PLUGIN_DEBUGGING_PORT:-5003}:${PLUGIN_DEBUGGING_PORT:-5003}"
|
||||
@@ -141,7 +192,12 @@ services:
|
||||
volumes:
|
||||
- ./ssrf_proxy/squid.conf.template:/etc/squid/squid.conf.template
|
||||
- ./ssrf_proxy/docker-entrypoint.sh:/docker-entrypoint-mount.sh
|
||||
entrypoint: [ "sh", "-c", "cp /docker-entrypoint-mount.sh /docker-entrypoint.sh && sed -i 's/\r$$//' /docker-entrypoint.sh && chmod +x /docker-entrypoint.sh && /docker-entrypoint.sh" ]
|
||||
entrypoint:
|
||||
[
|
||||
"sh",
|
||||
"-c",
|
||||
"cp /docker-entrypoint-mount.sh /docker-entrypoint.sh && sed -i 's/\r$$//' /docker-entrypoint.sh && chmod +x /docker-entrypoint.sh && /docker-entrypoint.sh",
|
||||
]
|
||||
env_file:
|
||||
- ./middleware.env
|
||||
environment:
|
||||
@@ -160,7 +216,7 @@ services:
|
||||
|
||||
# The Weaviate vector store.
|
||||
weaviate:
|
||||
image: semitechnologies/weaviate:1.19.0
|
||||
image: semitechnologies/weaviate:1.27.0
|
||||
profiles:
|
||||
- ""
|
||||
- weaviate
|
||||
@@ -183,8 +239,10 @@ services:
|
||||
AUTHENTICATION_APIKEY_USERS: ${WEAVIATE_AUTHENTICATION_APIKEY_USERS:-hello@dify.ai}
|
||||
AUTHORIZATION_ADMINLIST_ENABLED: ${WEAVIATE_AUTHORIZATION_ADMINLIST_ENABLED:-true}
|
||||
AUTHORIZATION_ADMINLIST_USERS: ${WEAVIATE_AUTHORIZATION_ADMINLIST_USERS:-hello@dify.ai}
|
||||
DISABLE_TELEMETRY: ${WEAVIATE_DISABLE_TELEMETRY:-false}
|
||||
ports:
|
||||
- "${EXPOSE_WEAVIATE_PORT:-8080}:8080"
|
||||
- "${EXPOSE_WEAVIATE_GRPC_PORT:-50051}:50051"
|
||||
|
||||
networks:
|
||||
# create a network between sandbox, api and ssrf_proxy, and can not access outside.
|
||||
|
||||
+370
-103
@@ -8,14 +8,17 @@ x-shared-env: &shared-api-worker-env
|
||||
CONSOLE_API_URL: ${CONSOLE_API_URL:-}
|
||||
CONSOLE_WEB_URL: ${CONSOLE_WEB_URL:-}
|
||||
SERVICE_API_URL: ${SERVICE_API_URL:-}
|
||||
TRIGGER_URL: ${TRIGGER_URL:-http://localhost}
|
||||
APP_API_URL: ${APP_API_URL:-}
|
||||
APP_WEB_URL: ${APP_WEB_URL:-}
|
||||
FILES_URL: ${FILES_URL:-}
|
||||
INTERNAL_FILES_URL: ${INTERNAL_FILES_URL:-}
|
||||
LANG: ${LANG:-en_US.UTF-8}
|
||||
LC_ALL: ${LC_ALL:-en_US.UTF-8}
|
||||
LANG: ${LANG:-C.UTF-8}
|
||||
LC_ALL: ${LC_ALL:-C.UTF-8}
|
||||
PYTHONIOENCODING: ${PYTHONIOENCODING:-utf-8}
|
||||
UV_CACHE_DIR: ${UV_CACHE_DIR:-/tmp/.uv-cache}
|
||||
LOG_LEVEL: ${LOG_LEVEL:-INFO}
|
||||
LOG_OUTPUT_FORMAT: ${LOG_OUTPUT_FORMAT:-text}
|
||||
LOG_FILE: ${LOG_FILE:-/app/logs/server.log}
|
||||
LOG_FILE_MAX_SIZE: ${LOG_FILE_MAX_SIZE:-20}
|
||||
LOG_FILE_BACKUP_COUNT: ${LOG_FILE_BACKUP_COUNT:-5}
|
||||
@@ -33,6 +36,7 @@ x-shared-env: &shared-api-worker-env
|
||||
FILES_ACCESS_TIMEOUT: ${FILES_ACCESS_TIMEOUT:-300}
|
||||
ACCESS_TOKEN_EXPIRE_MINUTES: ${ACCESS_TOKEN_EXPIRE_MINUTES:-60}
|
||||
REFRESH_TOKEN_EXPIRE_DAYS: ${REFRESH_TOKEN_EXPIRE_DAYS:-30}
|
||||
APP_DEFAULT_ACTIVE_REQUESTS: ${APP_DEFAULT_ACTIVE_REQUESTS:-0}
|
||||
APP_MAX_ACTIVE_REQUESTS: ${APP_MAX_ACTIVE_REQUESTS:-0}
|
||||
APP_MAX_EXECUTION_TIME: ${APP_MAX_EXECUTION_TIME:-1200}
|
||||
DIFY_BIND_ADDRESS: ${DIFY_BIND_ADDRESS:-0.0.0.0}
|
||||
@@ -51,9 +55,11 @@ x-shared-env: &shared-api-worker-env
|
||||
ENABLE_WEBSITE_JINAREADER: ${ENABLE_WEBSITE_JINAREADER:-true}
|
||||
ENABLE_WEBSITE_FIRECRAWL: ${ENABLE_WEBSITE_FIRECRAWL:-true}
|
||||
ENABLE_WEBSITE_WATERCRAWL: ${ENABLE_WEBSITE_WATERCRAWL:-true}
|
||||
NEXT_PUBLIC_ENABLE_SINGLE_DOLLAR_LATEX: ${NEXT_PUBLIC_ENABLE_SINGLE_DOLLAR_LATEX:-false}
|
||||
DB_TYPE: ${DB_TYPE:-postgresql}
|
||||
DB_USERNAME: ${DB_USERNAME:-postgres}
|
||||
DB_PASSWORD: ${DB_PASSWORD:-difyai123456}
|
||||
DB_HOST: ${DB_HOST:-db}
|
||||
DB_HOST: ${DB_HOST:-db_postgres}
|
||||
DB_PORT: ${DB_PORT:-5432}
|
||||
DB_DATABASE: ${DB_DATABASE:-dify}
|
||||
SQLALCHEMY_POOL_SIZE: ${SQLALCHEMY_POOL_SIZE:-30}
|
||||
@@ -62,11 +68,18 @@ x-shared-env: &shared-api-worker-env
|
||||
SQLALCHEMY_ECHO: ${SQLALCHEMY_ECHO:-false}
|
||||
SQLALCHEMY_POOL_PRE_PING: ${SQLALCHEMY_POOL_PRE_PING:-false}
|
||||
SQLALCHEMY_POOL_USE_LIFO: ${SQLALCHEMY_POOL_USE_LIFO:-false}
|
||||
SQLALCHEMY_POOL_TIMEOUT: ${SQLALCHEMY_POOL_TIMEOUT:-30}
|
||||
POSTGRES_MAX_CONNECTIONS: ${POSTGRES_MAX_CONNECTIONS:-100}
|
||||
POSTGRES_SHARED_BUFFERS: ${POSTGRES_SHARED_BUFFERS:-128MB}
|
||||
POSTGRES_WORK_MEM: ${POSTGRES_WORK_MEM:-4MB}
|
||||
POSTGRES_MAINTENANCE_WORK_MEM: ${POSTGRES_MAINTENANCE_WORK_MEM:-64MB}
|
||||
POSTGRES_EFFECTIVE_CACHE_SIZE: ${POSTGRES_EFFECTIVE_CACHE_SIZE:-4096MB}
|
||||
POSTGRES_STATEMENT_TIMEOUT: ${POSTGRES_STATEMENT_TIMEOUT:-0}
|
||||
POSTGRES_IDLE_IN_TRANSACTION_SESSION_TIMEOUT: ${POSTGRES_IDLE_IN_TRANSACTION_SESSION_TIMEOUT:-0}
|
||||
MYSQL_MAX_CONNECTIONS: ${MYSQL_MAX_CONNECTIONS:-1000}
|
||||
MYSQL_INNODB_BUFFER_POOL_SIZE: ${MYSQL_INNODB_BUFFER_POOL_SIZE:-512M}
|
||||
MYSQL_INNODB_LOG_FILE_SIZE: ${MYSQL_INNODB_LOG_FILE_SIZE:-128M}
|
||||
MYSQL_INNODB_FLUSH_LOG_AT_TRX_COMMIT: ${MYSQL_INNODB_FLUSH_LOG_AT_TRX_COMMIT:-2}
|
||||
REDIS_HOST: ${REDIS_HOST:-redis}
|
||||
REDIS_PORT: ${REDIS_PORT:-6379}
|
||||
REDIS_USERNAME: ${REDIS_USERNAME:-}
|
||||
@@ -77,6 +90,7 @@ x-shared-env: &shared-api-worker-env
|
||||
REDIS_SSL_CERTFILE: ${REDIS_SSL_CERTFILE:-}
|
||||
REDIS_SSL_KEYFILE: ${REDIS_SSL_KEYFILE:-}
|
||||
REDIS_DB: ${REDIS_DB:-0}
|
||||
REDIS_MAX_CONNECTIONS: ${REDIS_MAX_CONNECTIONS:-}
|
||||
REDIS_USE_SENTINEL: ${REDIS_USE_SENTINEL:-false}
|
||||
REDIS_SENTINELS: ${REDIS_SENTINELS:-}
|
||||
REDIS_SENTINEL_SERVICE_NAME: ${REDIS_SENTINEL_SERVICE_NAME:-}
|
||||
@@ -93,8 +107,12 @@ x-shared-env: &shared-api-worker-env
|
||||
CELERY_SENTINEL_MASTER_NAME: ${CELERY_SENTINEL_MASTER_NAME:-}
|
||||
CELERY_SENTINEL_PASSWORD: ${CELERY_SENTINEL_PASSWORD:-}
|
||||
CELERY_SENTINEL_SOCKET_TIMEOUT: ${CELERY_SENTINEL_SOCKET_TIMEOUT:-0.1}
|
||||
CELERY_TASK_ANNOTATIONS: ${CELERY_TASK_ANNOTATIONS:-null}
|
||||
WEB_API_CORS_ALLOW_ORIGINS: ${WEB_API_CORS_ALLOW_ORIGINS:-*}
|
||||
CONSOLE_CORS_ALLOW_ORIGINS: ${CONSOLE_CORS_ALLOW_ORIGINS:-*}
|
||||
COOKIE_DOMAIN: ${COOKIE_DOMAIN:-}
|
||||
NEXT_PUBLIC_COOKIE_DOMAIN: ${NEXT_PUBLIC_COOKIE_DOMAIN:-}
|
||||
NEXT_PUBLIC_BATCH_CONCURRENCY: ${NEXT_PUBLIC_BATCH_CONCURRENCY:-5}
|
||||
STORAGE_TYPE: ${STORAGE_TYPE:-opendal}
|
||||
OPENDAL_SCHEME: ${OPENDAL_SCHEME:-fs}
|
||||
OPENDAL_FS_ROOT: ${OPENDAL_FS_ROOT:-storage}
|
||||
@@ -108,6 +126,13 @@ x-shared-env: &shared-api-worker-env
|
||||
S3_ACCESS_KEY: ${S3_ACCESS_KEY:-}
|
||||
S3_SECRET_KEY: ${S3_SECRET_KEY:-}
|
||||
S3_USE_AWS_MANAGED_IAM: ${S3_USE_AWS_MANAGED_IAM:-false}
|
||||
ARCHIVE_STORAGE_ENABLED: ${ARCHIVE_STORAGE_ENABLED:-false}
|
||||
ARCHIVE_STORAGE_ENDPOINT: ${ARCHIVE_STORAGE_ENDPOINT:-}
|
||||
ARCHIVE_STORAGE_ARCHIVE_BUCKET: ${ARCHIVE_STORAGE_ARCHIVE_BUCKET:-}
|
||||
ARCHIVE_STORAGE_EXPORT_BUCKET: ${ARCHIVE_STORAGE_EXPORT_BUCKET:-}
|
||||
ARCHIVE_STORAGE_ACCESS_KEY: ${ARCHIVE_STORAGE_ACCESS_KEY:-}
|
||||
ARCHIVE_STORAGE_SECRET_KEY: ${ARCHIVE_STORAGE_SECRET_KEY:-}
|
||||
ARCHIVE_STORAGE_REGION: ${ARCHIVE_STORAGE_REGION:-auto}
|
||||
AZURE_BLOB_ACCOUNT_NAME: ${AZURE_BLOB_ACCOUNT_NAME:-difyai}
|
||||
AZURE_BLOB_ACCOUNT_KEY: ${AZURE_BLOB_ACCOUNT_KEY:-difyai}
|
||||
AZURE_BLOB_CONTAINER_NAME: ${AZURE_BLOB_CONTAINER_NAME:-difyai-container}
|
||||
@@ -121,11 +146,13 @@ x-shared-env: &shared-api-worker-env
|
||||
ALIYUN_OSS_REGION: ${ALIYUN_OSS_REGION:-ap-southeast-1}
|
||||
ALIYUN_OSS_AUTH_VERSION: ${ALIYUN_OSS_AUTH_VERSION:-v4}
|
||||
ALIYUN_OSS_PATH: ${ALIYUN_OSS_PATH:-your-path}
|
||||
ALIYUN_CLOUDBOX_ID: ${ALIYUN_CLOUDBOX_ID:-your-cloudbox-id}
|
||||
TENCENT_COS_BUCKET_NAME: ${TENCENT_COS_BUCKET_NAME:-your-bucket-name}
|
||||
TENCENT_COS_SECRET_KEY: ${TENCENT_COS_SECRET_KEY:-your-secret-key}
|
||||
TENCENT_COS_SECRET_ID: ${TENCENT_COS_SECRET_ID:-your-secret-id}
|
||||
TENCENT_COS_REGION: ${TENCENT_COS_REGION:-your-region}
|
||||
TENCENT_COS_SCHEME: ${TENCENT_COS_SCHEME:-your-scheme}
|
||||
TENCENT_COS_CUSTOM_DOMAIN: ${TENCENT_COS_CUSTOM_DOMAIN:-your-custom-domain}
|
||||
OCI_ENDPOINT: ${OCI_ENDPOINT:-https://your-object-storage-namespace.compat.objectstorage.us-ashburn-1.oraclecloud.com}
|
||||
OCI_BUCKET_NAME: ${OCI_BUCKET_NAME:-your-bucket-name}
|
||||
OCI_ACCESS_KEY: ${OCI_ACCESS_KEY:-your-access-key}
|
||||
@@ -135,6 +162,7 @@ x-shared-env: &shared-api-worker-env
|
||||
HUAWEI_OBS_SECRET_KEY: ${HUAWEI_OBS_SECRET_KEY:-your-secret-key}
|
||||
HUAWEI_OBS_ACCESS_KEY: ${HUAWEI_OBS_ACCESS_KEY:-your-access-key}
|
||||
HUAWEI_OBS_SERVER: ${HUAWEI_OBS_SERVER:-your-server-url}
|
||||
HUAWEI_OBS_PATH_STYLE: ${HUAWEI_OBS_PATH_STYLE:-false}
|
||||
VOLCENGINE_TOS_BUCKET_NAME: ${VOLCENGINE_TOS_BUCKET_NAME:-your-bucket-name}
|
||||
VOLCENGINE_TOS_SECRET_KEY: ${VOLCENGINE_TOS_SECRET_KEY:-your-secret-key}
|
||||
VOLCENGINE_TOS_ACCESS_KEY: ${VOLCENGINE_TOS_ACCESS_KEY:-your-access-key}
|
||||
@@ -151,6 +179,18 @@ x-shared-env: &shared-api-worker-env
|
||||
VECTOR_INDEX_NAME_PREFIX: ${VECTOR_INDEX_NAME_PREFIX:-Vector_index}
|
||||
WEAVIATE_ENDPOINT: ${WEAVIATE_ENDPOINT:-http://weaviate:8080}
|
||||
WEAVIATE_API_KEY: ${WEAVIATE_API_KEY:-WVF5YThaHlkYwhGUSmCRgsX3tD5ngdN8pkih}
|
||||
WEAVIATE_GRPC_ENDPOINT: ${WEAVIATE_GRPC_ENDPOINT:-grpc://weaviate:50051}
|
||||
WEAVIATE_TOKENIZATION: ${WEAVIATE_TOKENIZATION:-word}
|
||||
OCEANBASE_VECTOR_HOST: ${OCEANBASE_VECTOR_HOST:-oceanbase}
|
||||
OCEANBASE_VECTOR_PORT: ${OCEANBASE_VECTOR_PORT:-2881}
|
||||
OCEANBASE_VECTOR_USER: ${OCEANBASE_VECTOR_USER:-root@test}
|
||||
OCEANBASE_VECTOR_PASSWORD: ${OCEANBASE_VECTOR_PASSWORD:-difyai123456}
|
||||
OCEANBASE_VECTOR_DATABASE: ${OCEANBASE_VECTOR_DATABASE:-test}
|
||||
OCEANBASE_CLUSTER_NAME: ${OCEANBASE_CLUSTER_NAME:-difyai}
|
||||
OCEANBASE_MEMORY_LIMIT: ${OCEANBASE_MEMORY_LIMIT:-6G}
|
||||
OCEANBASE_ENABLE_HYBRID_SEARCH: ${OCEANBASE_ENABLE_HYBRID_SEARCH:-false}
|
||||
OCEANBASE_FULLTEXT_PARSER: ${OCEANBASE_FULLTEXT_PARSER:-ik}
|
||||
SEEKDB_MEMORY_LIMIT: ${SEEKDB_MEMORY_LIMIT:-2G}
|
||||
QDRANT_URL: ${QDRANT_URL:-http://qdrant:6333}
|
||||
QDRANT_API_KEY: ${QDRANT_API_KEY:-difyai123456}
|
||||
QDRANT_CLIENT_TIMEOUT: ${QDRANT_CLIENT_TIMEOUT:-20}
|
||||
@@ -243,6 +283,13 @@ x-shared-env: &shared-api-worker-env
|
||||
ORACLE_WALLET_LOCATION: ${ORACLE_WALLET_LOCATION:-/app/api/storage/wallet}
|
||||
ORACLE_WALLET_PASSWORD: ${ORACLE_WALLET_PASSWORD:-dify}
|
||||
ORACLE_IS_AUTONOMOUS: ${ORACLE_IS_AUTONOMOUS:-false}
|
||||
ALIBABACLOUD_MYSQL_HOST: ${ALIBABACLOUD_MYSQL_HOST:-127.0.0.1}
|
||||
ALIBABACLOUD_MYSQL_PORT: ${ALIBABACLOUD_MYSQL_PORT:-3306}
|
||||
ALIBABACLOUD_MYSQL_USER: ${ALIBABACLOUD_MYSQL_USER:-root}
|
||||
ALIBABACLOUD_MYSQL_PASSWORD: ${ALIBABACLOUD_MYSQL_PASSWORD:-difyai123456}
|
||||
ALIBABACLOUD_MYSQL_DATABASE: ${ALIBABACLOUD_MYSQL_DATABASE:-dify}
|
||||
ALIBABACLOUD_MYSQL_MAX_CONNECTION: ${ALIBABACLOUD_MYSQL_MAX_CONNECTION:-5}
|
||||
ALIBABACLOUD_MYSQL_HNSW_M: ${ALIBABACLOUD_MYSQL_HNSW_M:-6}
|
||||
RELYT_HOST: ${RELYT_HOST:-db}
|
||||
RELYT_PORT: ${RELYT_PORT:-5432}
|
||||
RELYT_USER: ${RELYT_USER:-postgres}
|
||||
@@ -285,6 +332,8 @@ x-shared-env: &shared-api-worker-env
|
||||
BAIDU_VECTOR_DB_DATABASE: ${BAIDU_VECTOR_DB_DATABASE:-dify}
|
||||
BAIDU_VECTOR_DB_SHARD: ${BAIDU_VECTOR_DB_SHARD:-1}
|
||||
BAIDU_VECTOR_DB_REPLICAS: ${BAIDU_VECTOR_DB_REPLICAS:-3}
|
||||
BAIDU_VECTOR_DB_INVERTED_INDEX_ANALYZER: ${BAIDU_VECTOR_DB_INVERTED_INDEX_ANALYZER:-DEFAULT_ANALYZER}
|
||||
BAIDU_VECTOR_DB_INVERTED_INDEX_PARSER_MODE: ${BAIDU_VECTOR_DB_INVERTED_INDEX_PARSER_MODE:-COARSE_MODE}
|
||||
VIKINGDB_ACCESS_KEY: ${VIKINGDB_ACCESS_KEY:-your-ak}
|
||||
VIKINGDB_SECRET_KEY: ${VIKINGDB_SECRET_KEY:-your-sk}
|
||||
VIKINGDB_REGION: ${VIKINGDB_REGION:-cn-shanghai}
|
||||
@@ -292,18 +341,11 @@ x-shared-env: &shared-api-worker-env
|
||||
VIKINGDB_SCHEMA: ${VIKINGDB_SCHEMA:-http}
|
||||
VIKINGDB_CONNECTION_TIMEOUT: ${VIKINGDB_CONNECTION_TIMEOUT:-30}
|
||||
VIKINGDB_SOCKET_TIMEOUT: ${VIKINGDB_SOCKET_TIMEOUT:-30}
|
||||
LINDORM_URL: ${LINDORM_URL:-http://lindorm:30070}
|
||||
LINDORM_USERNAME: ${LINDORM_USERNAME:-lindorm}
|
||||
LINDORM_PASSWORD: ${LINDORM_PASSWORD:-lindorm}
|
||||
LINDORM_URL: ${LINDORM_URL:-http://localhost:30070}
|
||||
LINDORM_USERNAME: ${LINDORM_USERNAME:-admin}
|
||||
LINDORM_PASSWORD: ${LINDORM_PASSWORD:-admin}
|
||||
LINDORM_USING_UGC: ${LINDORM_USING_UGC:-True}
|
||||
LINDORM_QUERY_TIMEOUT: ${LINDORM_QUERY_TIMEOUT:-1}
|
||||
OCEANBASE_VECTOR_HOST: ${OCEANBASE_VECTOR_HOST:-oceanbase}
|
||||
OCEANBASE_VECTOR_PORT: ${OCEANBASE_VECTOR_PORT:-2881}
|
||||
OCEANBASE_VECTOR_USER: ${OCEANBASE_VECTOR_USER:-root@test}
|
||||
OCEANBASE_VECTOR_PASSWORD: ${OCEANBASE_VECTOR_PASSWORD:-difyai123456}
|
||||
OCEANBASE_VECTOR_DATABASE: ${OCEANBASE_VECTOR_DATABASE:-test}
|
||||
OCEANBASE_CLUSTER_NAME: ${OCEANBASE_CLUSTER_NAME:-difyai}
|
||||
OCEANBASE_MEMORY_LIMIT: ${OCEANBASE_MEMORY_LIMIT:-6G}
|
||||
OCEANBASE_ENABLE_HYBRID_SEARCH: ${OCEANBASE_ENABLE_HYBRID_SEARCH:-false}
|
||||
OPENGAUSS_HOST: ${OPENGAUSS_HOST:-opengauss}
|
||||
OPENGAUSS_PORT: ${OPENGAUSS_PORT:-6600}
|
||||
OPENGAUSS_USER: ${OPENGAUSS_USER:-postgres}
|
||||
@@ -334,8 +376,26 @@ x-shared-env: &shared-api-worker-env
|
||||
CLICKZETTA_ANALYZER_TYPE: ${CLICKZETTA_ANALYZER_TYPE:-chinese}
|
||||
CLICKZETTA_ANALYZER_MODE: ${CLICKZETTA_ANALYZER_MODE:-smart}
|
||||
CLICKZETTA_VECTOR_DISTANCE_FUNCTION: ${CLICKZETTA_VECTOR_DISTANCE_FUNCTION:-cosine_distance}
|
||||
IRIS_HOST: ${IRIS_HOST:-iris}
|
||||
IRIS_SUPER_SERVER_PORT: ${IRIS_SUPER_SERVER_PORT:-1972}
|
||||
IRIS_WEB_SERVER_PORT: ${IRIS_WEB_SERVER_PORT:-52773}
|
||||
IRIS_USER: ${IRIS_USER:-_SYSTEM}
|
||||
IRIS_PASSWORD: ${IRIS_PASSWORD:-Dify@1234}
|
||||
IRIS_DATABASE: ${IRIS_DATABASE:-USER}
|
||||
IRIS_SCHEMA: ${IRIS_SCHEMA:-dify}
|
||||
IRIS_CONNECTION_URL: ${IRIS_CONNECTION_URL:-}
|
||||
IRIS_MIN_CONNECTION: ${IRIS_MIN_CONNECTION:-1}
|
||||
IRIS_MAX_CONNECTION: ${IRIS_MAX_CONNECTION:-3}
|
||||
IRIS_TEXT_INDEX: ${IRIS_TEXT_INDEX:-true}
|
||||
IRIS_TEXT_INDEX_LANGUAGE: ${IRIS_TEXT_INDEX_LANGUAGE:-en}
|
||||
IRIS_TIMEZONE: ${IRIS_TIMEZONE:-UTC}
|
||||
UPLOAD_FILE_SIZE_LIMIT: ${UPLOAD_FILE_SIZE_LIMIT:-15}
|
||||
UPLOAD_FILE_BATCH_LIMIT: ${UPLOAD_FILE_BATCH_LIMIT:-5}
|
||||
UPLOAD_FILE_EXTENSION_BLACKLIST: ${UPLOAD_FILE_EXTENSION_BLACKLIST:-}
|
||||
SINGLE_CHUNK_ATTACHMENT_LIMIT: ${SINGLE_CHUNK_ATTACHMENT_LIMIT:-10}
|
||||
IMAGE_FILE_BATCH_LIMIT: ${IMAGE_FILE_BATCH_LIMIT:-10}
|
||||
ATTACHMENT_IMAGE_FILE_SIZE_LIMIT: ${ATTACHMENT_IMAGE_FILE_SIZE_LIMIT:-2}
|
||||
ATTACHMENT_IMAGE_DOWNLOAD_TIMEOUT: ${ATTACHMENT_IMAGE_DOWNLOAD_TIMEOUT:-60}
|
||||
ETL_TYPE: ${ETL_TYPE:-dify}
|
||||
UNSTRUCTURED_API_URL: ${UNSTRUCTURED_API_URL:-}
|
||||
UNSTRUCTURED_API_KEY: ${UNSTRUCTURED_API_KEY:-}
|
||||
@@ -368,32 +428,41 @@ x-shared-env: &shared-api-worker-env
|
||||
SMTP_PASSWORD: ${SMTP_PASSWORD:-}
|
||||
SMTP_USE_TLS: ${SMTP_USE_TLS:-true}
|
||||
SMTP_OPPORTUNISTIC_TLS: ${SMTP_OPPORTUNISTIC_TLS:-false}
|
||||
SMTP_LOCAL_HOSTNAME: ${SMTP_LOCAL_HOSTNAME:-}
|
||||
SENDGRID_API_KEY: ${SENDGRID_API_KEY:-}
|
||||
INDEXING_MAX_SEGMENTATION_TOKENS_LENGTH: ${INDEXING_MAX_SEGMENTATION_TOKENS_LENGTH:-4000}
|
||||
INVITE_EXPIRY_HOURS: ${INVITE_EXPIRY_HOURS:-72}
|
||||
RESET_PASSWORD_TOKEN_EXPIRY_MINUTES: ${RESET_PASSWORD_TOKEN_EXPIRY_MINUTES:-5}
|
||||
EMAIL_REGISTER_TOKEN_EXPIRY_MINUTES: ${EMAIL_REGISTER_TOKEN_EXPIRY_MINUTES:-5}
|
||||
CHANGE_EMAIL_TOKEN_EXPIRY_MINUTES: ${CHANGE_EMAIL_TOKEN_EXPIRY_MINUTES:-5}
|
||||
OWNER_TRANSFER_TOKEN_EXPIRY_MINUTES: ${OWNER_TRANSFER_TOKEN_EXPIRY_MINUTES:-5}
|
||||
CODE_EXECUTION_ENDPOINT: ${CODE_EXECUTION_ENDPOINT:-http://sandbox:8194}
|
||||
CODE_EXECUTION_API_KEY: ${CODE_EXECUTION_API_KEY:-dify-sandbox}
|
||||
CODE_EXECUTION_SSL_VERIFY: ${CODE_EXECUTION_SSL_VERIFY:-True}
|
||||
CODE_EXECUTION_POOL_MAX_CONNECTIONS: ${CODE_EXECUTION_POOL_MAX_CONNECTIONS:-100}
|
||||
CODE_EXECUTION_POOL_MAX_KEEPALIVE_CONNECTIONS: ${CODE_EXECUTION_POOL_MAX_KEEPALIVE_CONNECTIONS:-20}
|
||||
CODE_EXECUTION_POOL_KEEPALIVE_EXPIRY: ${CODE_EXECUTION_POOL_KEEPALIVE_EXPIRY:-5.0}
|
||||
CODE_MAX_NUMBER: ${CODE_MAX_NUMBER:-9223372036854775807}
|
||||
CODE_MIN_NUMBER: ${CODE_MIN_NUMBER:--9223372036854775808}
|
||||
CODE_MAX_DEPTH: ${CODE_MAX_DEPTH:-5}
|
||||
CODE_MAX_PRECISION: ${CODE_MAX_PRECISION:-20}
|
||||
CODE_MAX_STRING_LENGTH: ${CODE_MAX_STRING_LENGTH:-80000}
|
||||
CODE_MAX_STRING_LENGTH: ${CODE_MAX_STRING_LENGTH:-400000}
|
||||
CODE_MAX_STRING_ARRAY_LENGTH: ${CODE_MAX_STRING_ARRAY_LENGTH:-30}
|
||||
CODE_MAX_OBJECT_ARRAY_LENGTH: ${CODE_MAX_OBJECT_ARRAY_LENGTH:-30}
|
||||
CODE_MAX_NUMBER_ARRAY_LENGTH: ${CODE_MAX_NUMBER_ARRAY_LENGTH:-1000}
|
||||
CODE_EXECUTION_CONNECT_TIMEOUT: ${CODE_EXECUTION_CONNECT_TIMEOUT:-10}
|
||||
CODE_EXECUTION_READ_TIMEOUT: ${CODE_EXECUTION_READ_TIMEOUT:-60}
|
||||
CODE_EXECUTION_WRITE_TIMEOUT: ${CODE_EXECUTION_WRITE_TIMEOUT:-10}
|
||||
TEMPLATE_TRANSFORM_MAX_LENGTH: ${TEMPLATE_TRANSFORM_MAX_LENGTH:-80000}
|
||||
TEMPLATE_TRANSFORM_MAX_LENGTH: ${TEMPLATE_TRANSFORM_MAX_LENGTH:-400000}
|
||||
WORKFLOW_MAX_EXECUTION_STEPS: ${WORKFLOW_MAX_EXECUTION_STEPS:-500}
|
||||
WORKFLOW_MAX_EXECUTION_TIME: ${WORKFLOW_MAX_EXECUTION_TIME:-1200}
|
||||
WORKFLOW_CALL_MAX_DEPTH: ${WORKFLOW_CALL_MAX_DEPTH:-5}
|
||||
MAX_VARIABLE_SIZE: ${MAX_VARIABLE_SIZE:-204800}
|
||||
WORKFLOW_PARALLEL_DEPTH_LIMIT: ${WORKFLOW_PARALLEL_DEPTH_LIMIT:-3}
|
||||
WORKFLOW_FILE_UPLOAD_LIMIT: ${WORKFLOW_FILE_UPLOAD_LIMIT:-10}
|
||||
GRAPH_ENGINE_MIN_WORKERS: ${GRAPH_ENGINE_MIN_WORKERS:-1}
|
||||
GRAPH_ENGINE_MAX_WORKERS: ${GRAPH_ENGINE_MAX_WORKERS:-10}
|
||||
GRAPH_ENGINE_SCALE_UP_THRESHOLD: ${GRAPH_ENGINE_SCALE_UP_THRESHOLD:-3}
|
||||
GRAPH_ENGINE_SCALE_DOWN_IDLE_TIME: ${GRAPH_ENGINE_SCALE_DOWN_IDLE_TIME:-5.0}
|
||||
WORKFLOW_NODE_EXECUTION_STORAGE: ${WORKFLOW_NODE_EXECUTION_STORAGE:-rdbms}
|
||||
CORE_WORKFLOW_EXECUTION_REPOSITORY: ${CORE_WORKFLOW_EXECUTION_REPOSITORY:-core.repositories.sqlalchemy_workflow_execution_repository.SQLAlchemyWorkflowExecutionRepository}
|
||||
CORE_WORKFLOW_NODE_EXECUTION_REPOSITORY: ${CORE_WORKFLOW_NODE_EXECUTION_REPOSITORY:-core.repositories.sqlalchemy_workflow_node_execution_repository.SQLAlchemyWorkflowNodeExecutionRepository}
|
||||
@@ -402,9 +471,23 @@ x-shared-env: &shared-api-worker-env
|
||||
WORKFLOW_LOG_CLEANUP_ENABLED: ${WORKFLOW_LOG_CLEANUP_ENABLED:-false}
|
||||
WORKFLOW_LOG_RETENTION_DAYS: ${WORKFLOW_LOG_RETENTION_DAYS:-30}
|
||||
WORKFLOW_LOG_CLEANUP_BATCH_SIZE: ${WORKFLOW_LOG_CLEANUP_BATCH_SIZE:-100}
|
||||
WORKFLOW_LOG_CLEANUP_SPECIFIC_WORKFLOW_IDS: ${WORKFLOW_LOG_CLEANUP_SPECIFIC_WORKFLOW_IDS:-}
|
||||
ALIYUN_SLS_ACCESS_KEY_ID: ${ALIYUN_SLS_ACCESS_KEY_ID:-}
|
||||
ALIYUN_SLS_ACCESS_KEY_SECRET: ${ALIYUN_SLS_ACCESS_KEY_SECRET:-}
|
||||
ALIYUN_SLS_ENDPOINT: ${ALIYUN_SLS_ENDPOINT:-}
|
||||
ALIYUN_SLS_REGION: ${ALIYUN_SLS_REGION:-}
|
||||
ALIYUN_SLS_PROJECT_NAME: ${ALIYUN_SLS_PROJECT_NAME:-}
|
||||
ALIYUN_SLS_LOGSTORE_TTL: ${ALIYUN_SLS_LOGSTORE_TTL:-365}
|
||||
LOGSTORE_DUAL_WRITE_ENABLED: ${LOGSTORE_DUAL_WRITE_ENABLED:-false}
|
||||
LOGSTORE_DUAL_READ_ENABLED: ${LOGSTORE_DUAL_READ_ENABLED:-true}
|
||||
LOGSTORE_ENABLE_PUT_GRAPH_FIELD: ${LOGSTORE_ENABLE_PUT_GRAPH_FIELD:-true}
|
||||
HTTP_REQUEST_NODE_MAX_BINARY_SIZE: ${HTTP_REQUEST_NODE_MAX_BINARY_SIZE:-10485760}
|
||||
HTTP_REQUEST_NODE_MAX_TEXT_SIZE: ${HTTP_REQUEST_NODE_MAX_TEXT_SIZE:-1048576}
|
||||
HTTP_REQUEST_NODE_SSL_VERIFY: ${HTTP_REQUEST_NODE_SSL_VERIFY:-True}
|
||||
HTTP_REQUEST_MAX_CONNECT_TIMEOUT: ${HTTP_REQUEST_MAX_CONNECT_TIMEOUT:-10}
|
||||
HTTP_REQUEST_MAX_READ_TIMEOUT: ${HTTP_REQUEST_MAX_READ_TIMEOUT:-600}
|
||||
HTTP_REQUEST_MAX_WRITE_TIMEOUT: ${HTTP_REQUEST_MAX_WRITE_TIMEOUT:-600}
|
||||
WEBHOOK_REQUEST_BODY_MAX_SIZE: ${WEBHOOK_REQUEST_BODY_MAX_SIZE:-10485760}
|
||||
RESPECT_XFORWARD_HEADERS_ENABLED: ${RESPECT_XFORWARD_HEADERS_ENABLED:-false}
|
||||
SSRF_PROXY_HTTP_URL: ${SSRF_PROXY_HTTP_URL:-http://ssrf_proxy:3128}
|
||||
SSRF_PROXY_HTTPS_URL: ${SSRF_PROXY_HTTPS_URL:-http://ssrf_proxy:3128}
|
||||
@@ -415,10 +498,8 @@ x-shared-env: &shared-api-worker-env
|
||||
TEXT_GENERATION_TIMEOUT_MS: ${TEXT_GENERATION_TIMEOUT_MS:-60000}
|
||||
ALLOW_UNSAFE_DATA_SCHEME: ${ALLOW_UNSAFE_DATA_SCHEME:-false}
|
||||
MAX_TREE_DEPTH: ${MAX_TREE_DEPTH:-50}
|
||||
POSTGRES_USER: ${POSTGRES_USER:-${DB_USERNAME}}
|
||||
POSTGRES_PASSWORD: ${POSTGRES_PASSWORD:-${DB_PASSWORD}}
|
||||
POSTGRES_DB: ${POSTGRES_DB:-${DB_DATABASE}}
|
||||
PGDATA: ${PGDATA:-/var/lib/postgresql/data/pgdata}
|
||||
MYSQL_HOST_VOLUME: ${MYSQL_HOST_VOLUME:-./volumes/mysql/data}
|
||||
SANDBOX_API_KEY: ${SANDBOX_API_KEY:-dify-sandbox}
|
||||
SANDBOX_GIN_MODE: ${SANDBOX_GIN_MODE:-release}
|
||||
SANDBOX_WORKER_TIMEOUT: ${SANDBOX_WORKER_TIMEOUT:-15}
|
||||
@@ -436,6 +517,10 @@ x-shared-env: &shared-api-worker-env
|
||||
WEAVIATE_AUTHENTICATION_APIKEY_USERS: ${WEAVIATE_AUTHENTICATION_APIKEY_USERS:-hello@dify.ai}
|
||||
WEAVIATE_AUTHORIZATION_ADMINLIST_ENABLED: ${WEAVIATE_AUTHORIZATION_ADMINLIST_ENABLED:-true}
|
||||
WEAVIATE_AUTHORIZATION_ADMINLIST_USERS: ${WEAVIATE_AUTHORIZATION_ADMINLIST_USERS:-hello@dify.ai}
|
||||
WEAVIATE_DISABLE_TELEMETRY: ${WEAVIATE_DISABLE_TELEMETRY:-false}
|
||||
WEAVIATE_ENABLE_TOKENIZER_GSE: ${WEAVIATE_ENABLE_TOKENIZER_GSE:-false}
|
||||
WEAVIATE_ENABLE_TOKENIZER_KAGOME_JA: ${WEAVIATE_ENABLE_TOKENIZER_KAGOME_JA:-false}
|
||||
WEAVIATE_ENABLE_TOKENIZER_KAGOME_KR: ${WEAVIATE_ENABLE_TOKENIZER_KAGOME_KR:-false}
|
||||
CHROMA_SERVER_AUTHN_CREDENTIALS: ${CHROMA_SERVER_AUTHN_CREDENTIALS:-difyai123456}
|
||||
CHROMA_SERVER_AUTHN_PROVIDER: ${CHROMA_SERVER_AUTHN_PROVIDER:-chromadb.auth.token_authn.TokenAuthenticationServerProvider}
|
||||
CHROMA_IS_PERSISTENT: ${CHROMA_IS_PERSISTENT:-TRUE}
|
||||
@@ -469,7 +554,7 @@ x-shared-env: &shared-api-worker-env
|
||||
NGINX_SSL_PORT: ${NGINX_SSL_PORT:-443}
|
||||
NGINX_SSL_CERT_FILENAME: ${NGINX_SSL_CERT_FILENAME:-dify.crt}
|
||||
NGINX_SSL_CERT_KEY_FILENAME: ${NGINX_SSL_CERT_KEY_FILENAME:-dify.key}
|
||||
NGINX_SSL_PROTOCOLS: ${NGINX_SSL_PROTOCOLS:-TLSv1.1 TLSv1.2 TLSv1.3}
|
||||
NGINX_SSL_PROTOCOLS: ${NGINX_SSL_PROTOCOLS:-TLSv1.2 TLSv1.3}
|
||||
NGINX_WORKER_PROCESSES: ${NGINX_WORKER_PROCESSES:-auto}
|
||||
NGINX_CLIENT_MAX_BODY_SIZE: ${NGINX_CLIENT_MAX_BODY_SIZE:-100M}
|
||||
NGINX_KEEPALIVE_TIMEOUT: ${NGINX_KEEPALIVE_TIMEOUT:-65}
|
||||
@@ -487,6 +572,9 @@ x-shared-env: &shared-api-worker-env
|
||||
SSRF_DEFAULT_CONNECT_TIME_OUT: ${SSRF_DEFAULT_CONNECT_TIME_OUT:-5}
|
||||
SSRF_DEFAULT_READ_TIME_OUT: ${SSRF_DEFAULT_READ_TIME_OUT:-5}
|
||||
SSRF_DEFAULT_WRITE_TIME_OUT: ${SSRF_DEFAULT_WRITE_TIME_OUT:-5}
|
||||
SSRF_POOL_MAX_CONNECTIONS: ${SSRF_POOL_MAX_CONNECTIONS:-100}
|
||||
SSRF_POOL_MAX_KEEPALIVE_CONNECTIONS: ${SSRF_POOL_MAX_KEEPALIVE_CONNECTIONS:-20}
|
||||
SSRF_POOL_KEEPALIVE_EXPIRY: ${SSRF_POOL_KEEPALIVE_EXPIRY:-5.0}
|
||||
EXPOSE_NGINX_PORT: ${EXPOSE_NGINX_PORT:-80}
|
||||
EXPOSE_NGINX_SSL_PORT: ${EXPOSE_NGINX_SSL_PORT:-443}
|
||||
POSITION_TOOL_PINS: ${POSITION_TOOL_PINS:-}
|
||||
@@ -505,6 +593,7 @@ x-shared-env: &shared-api-worker-env
|
||||
PLUGIN_DAEMON_KEY: ${PLUGIN_DAEMON_KEY:-lYkiYYT6owG+71oLerGzA7GXCgOT++6ovaezWAjpCjf+Sjc3ZtU+qUEi}
|
||||
PLUGIN_DAEMON_URL: ${PLUGIN_DAEMON_URL:-http://plugin_daemon:5002}
|
||||
PLUGIN_MAX_PACKAGE_SIZE: ${PLUGIN_MAX_PACKAGE_SIZE:-52428800}
|
||||
PLUGIN_MODEL_SCHEMA_CACHE_TTL: ${PLUGIN_MODEL_SCHEMA_CACHE_TTL:-3600}
|
||||
PLUGIN_PPROF_ENABLED: ${PLUGIN_PPROF_ENABLED:-false}
|
||||
PLUGIN_DEBUGGING_HOST: ${PLUGIN_DEBUGGING_HOST:-0.0.0.0}
|
||||
PLUGIN_DEBUGGING_PORT: ${PLUGIN_DEBUGGING_PORT:-5003}
|
||||
@@ -516,10 +605,12 @@ x-shared-env: &shared-api-worker-env
|
||||
MARKETPLACE_ENABLED: ${MARKETPLACE_ENABLED:-true}
|
||||
MARKETPLACE_API_URL: ${MARKETPLACE_API_URL:-https://marketplace.dify.ai}
|
||||
FORCE_VERIFYING_SIGNATURE: ${FORCE_VERIFYING_SIGNATURE:-true}
|
||||
ENFORCE_LANGGENIUS_PLUGIN_SIGNATURES: ${ENFORCE_LANGGENIUS_PLUGIN_SIGNATURES:-true}
|
||||
PLUGIN_STDIO_BUFFER_SIZE: ${PLUGIN_STDIO_BUFFER_SIZE:-1024}
|
||||
PLUGIN_STDIO_MAX_BUFFER_SIZE: ${PLUGIN_STDIO_MAX_BUFFER_SIZE:-5242880}
|
||||
PLUGIN_PYTHON_ENV_INIT_TIMEOUT: ${PLUGIN_PYTHON_ENV_INIT_TIMEOUT:-120}
|
||||
PLUGIN_MAX_EXECUTION_TIMEOUT: ${PLUGIN_MAX_EXECUTION_TIMEOUT:-600}
|
||||
PLUGIN_DAEMON_TIMEOUT: ${PLUGIN_DAEMON_TIMEOUT:-600.0}
|
||||
PIP_MIRROR_URL: ${PIP_MIRROR_URL:-}
|
||||
PLUGIN_STORAGE_TYPE: ${PLUGIN_STORAGE_TYPE:-local}
|
||||
PLUGIN_STORAGE_LOCAL_ROOT: ${PLUGIN_STORAGE_LOCAL_ROOT:-/app/storage}
|
||||
@@ -568,21 +659,65 @@ x-shared-env: &shared-api-worker-env
|
||||
QUEUE_MONITOR_THRESHOLD: ${QUEUE_MONITOR_THRESHOLD:-200}
|
||||
QUEUE_MONITOR_ALERT_EMAILS: ${QUEUE_MONITOR_ALERT_EMAILS:-}
|
||||
QUEUE_MONITOR_INTERVAL: ${QUEUE_MONITOR_INTERVAL:-30}
|
||||
SWAGGER_UI_ENABLED: ${SWAGGER_UI_ENABLED:-true}
|
||||
SWAGGER_UI_ENABLED: ${SWAGGER_UI_ENABLED:-false}
|
||||
SWAGGER_UI_PATH: ${SWAGGER_UI_PATH:-/swagger-ui.html}
|
||||
DSL_EXPORT_ENCRYPT_DATASET_ID: ${DSL_EXPORT_ENCRYPT_DATASET_ID:-true}
|
||||
DATASET_MAX_SEGMENTS_PER_REQUEST: ${DATASET_MAX_SEGMENTS_PER_REQUEST:-0}
|
||||
ENABLE_CLEAN_EMBEDDING_CACHE_TASK: ${ENABLE_CLEAN_EMBEDDING_CACHE_TASK:-false}
|
||||
ENABLE_CLEAN_UNUSED_DATASETS_TASK: ${ENABLE_CLEAN_UNUSED_DATASETS_TASK:-false}
|
||||
ENABLE_CREATE_TIDB_SERVERLESS_TASK: ${ENABLE_CREATE_TIDB_SERVERLESS_TASK:-false}
|
||||
ENABLE_UPDATE_TIDB_SERVERLESS_STATUS_TASK: ${ENABLE_UPDATE_TIDB_SERVERLESS_STATUS_TASK:-false}
|
||||
ENABLE_CLEAN_MESSAGES: ${ENABLE_CLEAN_MESSAGES:-false}
|
||||
ENABLE_WORKFLOW_RUN_CLEANUP_TASK: ${ENABLE_WORKFLOW_RUN_CLEANUP_TASK:-false}
|
||||
ENABLE_MAIL_CLEAN_DOCUMENT_NOTIFY_TASK: ${ENABLE_MAIL_CLEAN_DOCUMENT_NOTIFY_TASK:-false}
|
||||
ENABLE_DATASETS_QUEUE_MONITOR: ${ENABLE_DATASETS_QUEUE_MONITOR:-false}
|
||||
ENABLE_CHECK_UPGRADABLE_PLUGIN_TASK: ${ENABLE_CHECK_UPGRADABLE_PLUGIN_TASK:-true}
|
||||
ENABLE_WORKFLOW_SCHEDULE_POLLER_TASK: ${ENABLE_WORKFLOW_SCHEDULE_POLLER_TASK:-true}
|
||||
WORKFLOW_SCHEDULE_POLLER_INTERVAL: ${WORKFLOW_SCHEDULE_POLLER_INTERVAL:-1}
|
||||
WORKFLOW_SCHEDULE_POLLER_BATCH_SIZE: ${WORKFLOW_SCHEDULE_POLLER_BATCH_SIZE:-100}
|
||||
WORKFLOW_SCHEDULE_MAX_DISPATCH_PER_TICK: ${WORKFLOW_SCHEDULE_MAX_DISPATCH_PER_TICK:-0}
|
||||
TENANT_ISOLATED_TASK_CONCURRENCY: ${TENANT_ISOLATED_TASK_CONCURRENCY:-1}
|
||||
ANNOTATION_IMPORT_FILE_SIZE_LIMIT: ${ANNOTATION_IMPORT_FILE_SIZE_LIMIT:-2}
|
||||
ANNOTATION_IMPORT_MAX_RECORDS: ${ANNOTATION_IMPORT_MAX_RECORDS:-10000}
|
||||
ANNOTATION_IMPORT_MIN_RECORDS: ${ANNOTATION_IMPORT_MIN_RECORDS:-1}
|
||||
ANNOTATION_IMPORT_RATE_LIMIT_PER_MINUTE: ${ANNOTATION_IMPORT_RATE_LIMIT_PER_MINUTE:-5}
|
||||
ANNOTATION_IMPORT_RATE_LIMIT_PER_HOUR: ${ANNOTATION_IMPORT_RATE_LIMIT_PER_HOUR:-20}
|
||||
ANNOTATION_IMPORT_MAX_CONCURRENT: ${ANNOTATION_IMPORT_MAX_CONCURRENT:-5}
|
||||
AMPLITUDE_API_KEY: ${AMPLITUDE_API_KEY:-}
|
||||
SANDBOX_EXPIRED_RECORDS_CLEAN_GRACEFUL_PERIOD: ${SANDBOX_EXPIRED_RECORDS_CLEAN_GRACEFUL_PERIOD:-21}
|
||||
SANDBOX_EXPIRED_RECORDS_CLEAN_BATCH_SIZE: ${SANDBOX_EXPIRED_RECORDS_CLEAN_BATCH_SIZE:-1000}
|
||||
SANDBOX_EXPIRED_RECORDS_CLEAN_BATCH_MAX_INTERVAL: ${SANDBOX_EXPIRED_RECORDS_CLEAN_BATCH_MAX_INTERVAL:-200}
|
||||
SANDBOX_EXPIRED_RECORDS_RETENTION_DAYS: ${SANDBOX_EXPIRED_RECORDS_RETENTION_DAYS:-30}
|
||||
PUBSUB_REDIS_URL: ${PUBSUB_REDIS_URL:-}
|
||||
PUBSUB_REDIS_CHANNEL_TYPE: ${PUBSUB_REDIS_CHANNEL_TYPE:-pubsub}
|
||||
PUBSUB_REDIS_USE_CLUSTERS: ${PUBSUB_REDIS_USE_CLUSTERS:-false}
|
||||
ENABLE_HUMAN_INPUT_TIMEOUT_TASK: ${ENABLE_HUMAN_INPUT_TIMEOUT_TASK:-true}
|
||||
HUMAN_INPUT_TIMEOUT_TASK_INTERVAL: ${HUMAN_INPUT_TIMEOUT_TASK_INTERVAL:-1}
|
||||
SANDBOX_EXPIRED_RECORDS_CLEAN_TASK_LOCK_TTL: ${SANDBOX_EXPIRED_RECORDS_CLEAN_TASK_LOCK_TTL:-90000}
|
||||
|
||||
services:
|
||||
# Init container to fix permissions
|
||||
init_permissions:
|
||||
image: busybox:latest
|
||||
command:
|
||||
- sh
|
||||
- -c
|
||||
- |
|
||||
FLAG_FILE="/app/api/storage/.init_permissions"
|
||||
if [ -f "$${FLAG_FILE}" ]; then
|
||||
echo "Permissions already initialized. Exiting."
|
||||
exit 0
|
||||
fi
|
||||
echo "Initializing permissions for /app/api/storage"
|
||||
chown -R 1001:1001 /app/api/storage && touch "$${FLAG_FILE}"
|
||||
echo "Permissions initialized. Exiting."
|
||||
volumes:
|
||||
- ./volumes/app/storage:/app/api/storage
|
||||
restart: "no"
|
||||
|
||||
# API service
|
||||
api:
|
||||
image: langgenius/dify-api:1.8.0
|
||||
image: langgenius/dify-api:1.13.0
|
||||
restart: always
|
||||
environment:
|
||||
# Use the shared environment variables.
|
||||
@@ -595,10 +730,23 @@ services:
|
||||
PLUGIN_REMOTE_INSTALL_HOST: ${EXPOSE_PLUGIN_DEBUGGING_HOST:-localhost}
|
||||
PLUGIN_REMOTE_INSTALL_PORT: ${EXPOSE_PLUGIN_DEBUGGING_PORT:-5003}
|
||||
PLUGIN_MAX_PACKAGE_SIZE: ${PLUGIN_MAX_PACKAGE_SIZE:-52428800}
|
||||
PLUGIN_DAEMON_TIMEOUT: ${PLUGIN_DAEMON_TIMEOUT:-600.0}
|
||||
INNER_API_KEY_FOR_PLUGIN: ${PLUGIN_DIFY_INNER_API_KEY:-QaHbTe77CtuXmsfyhR7+vRjI/+XbV1AaFy691iy+kGDv2Jvy0/eAh8Y1}
|
||||
depends_on:
|
||||
db:
|
||||
init_permissions:
|
||||
condition: service_completed_successfully
|
||||
db_postgres:
|
||||
condition: service_healthy
|
||||
required: false
|
||||
db_mysql:
|
||||
condition: service_healthy
|
||||
required: false
|
||||
oceanbase:
|
||||
condition: service_healthy
|
||||
required: false
|
||||
seekdb:
|
||||
condition: service_healthy
|
||||
required: false
|
||||
redis:
|
||||
condition: service_started
|
||||
volumes:
|
||||
@@ -609,14 +757,14 @@ services:
|
||||
- default
|
||||
|
||||
# worker service
|
||||
# The Celery worker for processing the queue.
|
||||
# The Celery worker for processing all queues (dataset, workflow, mail, etc.)
|
||||
worker:
|
||||
image: langgenius/dify-api:1.8.0
|
||||
image: langgenius/dify-api:1.13.0
|
||||
restart: always
|
||||
environment:
|
||||
# Use the shared environment variables.
|
||||
<<: *shared-api-worker-env
|
||||
# Startup mode, 'worker' starts the Celery worker for processing the queue.
|
||||
# Startup mode, 'worker' starts the Celery worker for processing all queues.
|
||||
MODE: worker
|
||||
SENTRY_DSN: ${API_SENTRY_DSN:-}
|
||||
SENTRY_TRACES_SAMPLE_RATE: ${API_SENTRY_TRACES_SAMPLE_RATE:-1.0}
|
||||
@@ -624,8 +772,20 @@ services:
|
||||
PLUGIN_MAX_PACKAGE_SIZE: ${PLUGIN_MAX_PACKAGE_SIZE:-52428800}
|
||||
INNER_API_KEY_FOR_PLUGIN: ${PLUGIN_DIFY_INNER_API_KEY:-QaHbTe77CtuXmsfyhR7+vRjI/+XbV1AaFy691iy+kGDv2Jvy0/eAh8Y1}
|
||||
depends_on:
|
||||
db:
|
||||
init_permissions:
|
||||
condition: service_completed_successfully
|
||||
db_postgres:
|
||||
condition: service_healthy
|
||||
required: false
|
||||
db_mysql:
|
||||
condition: service_healthy
|
||||
required: false
|
||||
oceanbase:
|
||||
condition: service_healthy
|
||||
required: false
|
||||
seekdb:
|
||||
condition: service_healthy
|
||||
required: false
|
||||
redis:
|
||||
condition: service_started
|
||||
volumes:
|
||||
@@ -638,7 +798,7 @@ services:
|
||||
# worker_beat service
|
||||
# Celery beat for scheduling periodic tasks.
|
||||
worker_beat:
|
||||
image: langgenius/dify-api:1.8.0
|
||||
image: langgenius/dify-api:1.13.0
|
||||
restart: always
|
||||
environment:
|
||||
# Use the shared environment variables.
|
||||
@@ -646,8 +806,20 @@ services:
|
||||
# Startup mode, 'worker_beat' starts the Celery beat for scheduling periodic tasks.
|
||||
MODE: beat
|
||||
depends_on:
|
||||
db:
|
||||
init_permissions:
|
||||
condition: service_completed_successfully
|
||||
db_postgres:
|
||||
condition: service_healthy
|
||||
required: false
|
||||
db_mysql:
|
||||
condition: service_healthy
|
||||
required: false
|
||||
oceanbase:
|
||||
condition: service_healthy
|
||||
required: false
|
||||
seekdb:
|
||||
condition: service_healthy
|
||||
required: false
|
||||
redis:
|
||||
condition: service_started
|
||||
networks:
|
||||
@@ -656,11 +828,13 @@ services:
|
||||
|
||||
# Frontend web application.
|
||||
web:
|
||||
image: langgenius/dify-web:1.8.0
|
||||
image: langgenius/dify-web:1.13.0
|
||||
restart: always
|
||||
environment:
|
||||
CONSOLE_API_URL: ${CONSOLE_API_URL:-}
|
||||
APP_API_URL: ${APP_API_URL:-}
|
||||
AMPLITUDE_API_KEY: ${AMPLITUDE_API_KEY:-}
|
||||
NEXT_PUBLIC_COOKIE_DOMAIN: ${NEXT_PUBLIC_COOKIE_DOMAIN:-}
|
||||
SENTRY_DSN: ${WEB_SENTRY_DSN:-}
|
||||
NEXT_TELEMETRY_DISABLED: ${NEXT_TELEMETRY_DISABLED:-0}
|
||||
TEXT_GENERATION_TIMEOUT_MS: ${TEXT_GENERATION_TIMEOUT_MS:-60000}
|
||||
@@ -671,7 +845,6 @@ services:
|
||||
MARKETPLACE_URL: ${MARKETPLACE_URL:-https://marketplace.dify.ai}
|
||||
TOP_K_MAX_VALUE: ${TOP_K_MAX_VALUE:-}
|
||||
INDEXING_MAX_SEGMENTATION_TOKENS_LENGTH: ${INDEXING_MAX_SEGMENTATION_TOKENS_LENGTH:-}
|
||||
PM2_INSTANCES: ${PM2_INSTANCES:-2}
|
||||
LOOP_NODE_MAX_COUNT: ${LOOP_NODE_MAX_COUNT:-100}
|
||||
MAX_TOOLS_NUM: ${MAX_TOOLS_NUM:-10}
|
||||
MAX_PARALLEL_LIMIT: ${MAX_PARALLEL_LIMIT:-10}
|
||||
@@ -680,14 +853,17 @@ services:
|
||||
ENABLE_WEBSITE_JINAREADER: ${ENABLE_WEBSITE_JINAREADER:-true}
|
||||
ENABLE_WEBSITE_FIRECRAWL: ${ENABLE_WEBSITE_FIRECRAWL:-true}
|
||||
ENABLE_WEBSITE_WATERCRAWL: ${ENABLE_WEBSITE_WATERCRAWL:-true}
|
||||
# The postgres database.
|
||||
db:
|
||||
|
||||
# The PostgreSQL database.
|
||||
db_postgres:
|
||||
image: postgres:15-alpine
|
||||
profiles:
|
||||
- postgresql
|
||||
restart: always
|
||||
environment:
|
||||
POSTGRES_USER: ${POSTGRES_USER:-postgres}
|
||||
POSTGRES_PASSWORD: ${POSTGRES_PASSWORD:-difyai123456}
|
||||
POSTGRES_DB: ${POSTGRES_DB:-dify}
|
||||
POSTGRES_USER: ${DB_USERNAME:-postgres}
|
||||
POSTGRES_PASSWORD: ${DB_PASSWORD:-difyai123456}
|
||||
POSTGRES_DB: ${DB_DATABASE:-dify}
|
||||
PGDATA: ${PGDATA:-/var/lib/postgresql/data/pgdata}
|
||||
command: >
|
||||
postgres -c 'max_connections=${POSTGRES_MAX_CONNECTIONS:-100}'
|
||||
@@ -695,24 +871,56 @@ services:
|
||||
-c 'work_mem=${POSTGRES_WORK_MEM:-4MB}'
|
||||
-c 'maintenance_work_mem=${POSTGRES_MAINTENANCE_WORK_MEM:-64MB}'
|
||||
-c 'effective_cache_size=${POSTGRES_EFFECTIVE_CACHE_SIZE:-4096MB}'
|
||||
-c 'statement_timeout=${POSTGRES_STATEMENT_TIMEOUT:-0}'
|
||||
-c 'idle_in_transaction_session_timeout=${POSTGRES_IDLE_IN_TRANSACTION_SESSION_TIMEOUT:-0}'
|
||||
volumes:
|
||||
- ./volumes/db/data:/var/lib/postgresql/data
|
||||
healthcheck:
|
||||
test:
|
||||
[
|
||||
'CMD',
|
||||
'pg_isready',
|
||||
'-h',
|
||||
'db',
|
||||
'-U',
|
||||
'${PGUSER:-postgres}',
|
||||
'-d',
|
||||
'${POSTGRES_DB:-dify}'
|
||||
"CMD",
|
||||
"pg_isready",
|
||||
"-h",
|
||||
"db_postgres",
|
||||
"-U",
|
||||
"${DB_USERNAME:-postgres}",
|
||||
"-d",
|
||||
"${DB_DATABASE:-dify}"
|
||||
]
|
||||
interval: 1s
|
||||
timeout: 3s
|
||||
retries: 60
|
||||
|
||||
# The mysql database.
|
||||
db_mysql:
|
||||
image: mysql:8.0
|
||||
profiles:
|
||||
- mysql
|
||||
restart: always
|
||||
environment:
|
||||
MYSQL_ROOT_PASSWORD: ${DB_PASSWORD:-difyai123456}
|
||||
MYSQL_DATABASE: ${DB_DATABASE:-dify}
|
||||
command: >
|
||||
--max_connections=1000
|
||||
--innodb_buffer_pool_size=${MYSQL_INNODB_BUFFER_POOL_SIZE:-512M}
|
||||
--innodb_log_file_size=${MYSQL_INNODB_LOG_FILE_SIZE:-128M}
|
||||
--innodb_flush_log_at_trx_commit=${MYSQL_INNODB_FLUSH_LOG_AT_TRX_COMMIT:-2}
|
||||
volumes:
|
||||
- ${MYSQL_HOST_VOLUME:-./volumes/mysql/data}:/var/lib/mysql
|
||||
healthcheck:
|
||||
test:
|
||||
[
|
||||
"CMD",
|
||||
"mysqladmin",
|
||||
"ping",
|
||||
"-u",
|
||||
"root",
|
||||
"-p${DB_PASSWORD:-difyai123456}"
|
||||
]
|
||||
interval: 1s
|
||||
timeout: 3s
|
||||
retries: 30
|
||||
|
||||
# The redis cache.
|
||||
redis:
|
||||
image: redis:6-alpine
|
||||
@@ -725,7 +933,11 @@ services:
|
||||
# Set the redis password when startup redis server.
|
||||
command: redis-server --requirepass ${REDIS_PASSWORD:-difyai123456}
|
||||
healthcheck:
|
||||
test: [ 'CMD', 'redis-cli', 'ping' ]
|
||||
test:
|
||||
[
|
||||
"CMD-SHELL",
|
||||
"redis-cli -a ${REDIS_PASSWORD:-difyai123456} ping | grep -q PONG"
|
||||
]
|
||||
|
||||
# The DifySandbox
|
||||
sandbox:
|
||||
@@ -747,13 +959,13 @@ services:
|
||||
- ./volumes/sandbox/dependencies:/dependencies
|
||||
- ./volumes/sandbox/conf:/conf
|
||||
healthcheck:
|
||||
test: [ 'CMD', 'curl', '-f', 'http://localhost:8194/health' ]
|
||||
test: [ "CMD", "curl", "-f", "http://localhost:8194/health" ]
|
||||
networks:
|
||||
- ssrf_proxy_network
|
||||
|
||||
# plugin daemon
|
||||
plugin_daemon:
|
||||
image: langgenius/dify-plugin-daemon:0.2.0-local
|
||||
image: langgenius/dify-plugin-daemon:0.5.3-local
|
||||
restart: always
|
||||
environment:
|
||||
# Use the shared environment variables.
|
||||
@@ -807,8 +1019,18 @@ services:
|
||||
volumes:
|
||||
- ./volumes/plugin_daemon:/app/storage
|
||||
depends_on:
|
||||
db:
|
||||
db_postgres:
|
||||
condition: service_healthy
|
||||
required: false
|
||||
db_mysql:
|
||||
condition: service_healthy
|
||||
required: false
|
||||
oceanbase:
|
||||
condition: service_healthy
|
||||
required: false
|
||||
seekdb:
|
||||
condition: service_healthy
|
||||
required: false
|
||||
|
||||
# ssrf_proxy server
|
||||
# for more information, please refer to
|
||||
@@ -821,8 +1043,8 @@ services:
|
||||
- ./ssrf_proxy/docker-entrypoint.sh:/docker-entrypoint-mount.sh
|
||||
entrypoint:
|
||||
[
|
||||
'sh',
|
||||
'-c',
|
||||
"sh",
|
||||
"-c",
|
||||
"cp /docker-entrypoint-mount.sh /docker-entrypoint.sh && sed -i
|
||||
's/\r$$//' /docker-entrypoint.sh && chmod +x /docker-entrypoint.sh &&
|
||||
/docker-entrypoint.sh"
|
||||
@@ -855,8 +1077,8 @@ services:
|
||||
- CERTBOT_EMAIL=${CERTBOT_EMAIL}
|
||||
- CERTBOT_DOMAIN=${CERTBOT_DOMAIN}
|
||||
- CERTBOT_OPTIONS=${CERTBOT_OPTIONS:-}
|
||||
entrypoint: [ '/docker-entrypoint.sh' ]
|
||||
command: [ 'tail', '-f', '/dev/null' ]
|
||||
entrypoint: [ "/docker-entrypoint.sh" ]
|
||||
command: [ "tail", "-f", "/dev/null" ]
|
||||
|
||||
# The nginx reverse proxy.
|
||||
# used for reverse proxying the API service and Web service.
|
||||
@@ -875,8 +1097,8 @@ services:
|
||||
- ./volumes/certbot/www:/var/www/html
|
||||
entrypoint:
|
||||
[
|
||||
'sh',
|
||||
'-c',
|
||||
"sh",
|
||||
"-c",
|
||||
"cp /docker-entrypoint-mount.sh /docker-entrypoint.sh && sed -i
|
||||
's/\r$$//' /docker-entrypoint.sh && chmod +x /docker-entrypoint.sh &&
|
||||
/docker-entrypoint.sh"
|
||||
@@ -890,7 +1112,7 @@ services:
|
||||
# and modify the env vars below in .env if HTTPS_ENABLED is true.
|
||||
NGINX_SSL_CERT_FILENAME: ${NGINX_SSL_CERT_FILENAME:-dify.crt}
|
||||
NGINX_SSL_CERT_KEY_FILENAME: ${NGINX_SSL_CERT_KEY_FILENAME:-dify.key}
|
||||
NGINX_SSL_PROTOCOLS: ${NGINX_SSL_PROTOCOLS:-TLSv1.1 TLSv1.2 TLSv1.3}
|
||||
NGINX_SSL_PROTOCOLS: ${NGINX_SSL_PROTOCOLS:-TLSv1.2 TLSv1.3}
|
||||
NGINX_WORKER_PROCESSES: ${NGINX_WORKER_PROCESSES:-auto}
|
||||
NGINX_CLIENT_MAX_BODY_SIZE: ${NGINX_CLIENT_MAX_BODY_SIZE:-100M}
|
||||
NGINX_KEEPALIVE_TIMEOUT: ${NGINX_KEEPALIVE_TIMEOUT:-65}
|
||||
@@ -904,9 +1126,8 @@ services:
|
||||
|
||||
# The Weaviate vector store.
|
||||
weaviate:
|
||||
image: semitechnologies/weaviate:1.19.0
|
||||
image: semitechnologies/weaviate:1.27.0
|
||||
profiles:
|
||||
- ''
|
||||
- weaviate
|
||||
restart: always
|
||||
volumes:
|
||||
@@ -925,11 +1146,69 @@ services:
|
||||
AUTHENTICATION_APIKEY_USERS: ${WEAVIATE_AUTHENTICATION_APIKEY_USERS:-hello@dify.ai}
|
||||
AUTHORIZATION_ADMINLIST_ENABLED: ${WEAVIATE_AUTHORIZATION_ADMINLIST_ENABLED:-true}
|
||||
AUTHORIZATION_ADMINLIST_USERS: ${WEAVIATE_AUTHORIZATION_ADMINLIST_USERS:-hello@dify.ai}
|
||||
DISABLE_TELEMETRY: ${WEAVIATE_DISABLE_TELEMETRY:-false}
|
||||
ENABLE_TOKENIZER_GSE: ${WEAVIATE_ENABLE_TOKENIZER_GSE:-false}
|
||||
ENABLE_TOKENIZER_KAGOME_JA: ${WEAVIATE_ENABLE_TOKENIZER_KAGOME_JA:-false}
|
||||
ENABLE_TOKENIZER_KAGOME_KR: ${WEAVIATE_ENABLE_TOKENIZER_KAGOME_KR:-false}
|
||||
|
||||
# OceanBase vector database
|
||||
oceanbase:
|
||||
image: oceanbase/oceanbase-ce:4.3.5-lts
|
||||
profiles:
|
||||
- oceanbase
|
||||
restart: always
|
||||
volumes:
|
||||
- ./volumes/oceanbase/data:/root/ob
|
||||
- ./volumes/oceanbase/conf:/root/.obd/cluster
|
||||
- ./volumes/oceanbase/init.d:/root/boot/init.d
|
||||
environment:
|
||||
OB_MEMORY_LIMIT: ${OCEANBASE_MEMORY_LIMIT:-6G}
|
||||
OB_SYS_PASSWORD: ${OCEANBASE_VECTOR_PASSWORD:-difyai123456}
|
||||
OB_TENANT_PASSWORD: ${OCEANBASE_VECTOR_PASSWORD:-difyai123456}
|
||||
OB_CLUSTER_NAME: ${OCEANBASE_CLUSTER_NAME:-difyai}
|
||||
OB_SERVER_IP: 127.0.0.1
|
||||
MODE: mini
|
||||
LANG: C.UTF-8
|
||||
LC_ALL: C.UTF-8
|
||||
healthcheck:
|
||||
test:
|
||||
[
|
||||
"CMD-SHELL",
|
||||
'obclient -h127.0.0.1 -P2881 -uroot@test
|
||||
-p${OCEANBASE_VECTOR_PASSWORD:-difyai123456} -e "SELECT 1;"'
|
||||
]
|
||||
interval: 10s
|
||||
retries: 30
|
||||
start_period: 30s
|
||||
timeout: 10s
|
||||
|
||||
# seekdb vector database
|
||||
seekdb:
|
||||
image: oceanbase/seekdb:latest
|
||||
profiles:
|
||||
- seekdb
|
||||
restart: always
|
||||
volumes:
|
||||
- ./volumes/seekdb:/var/lib/oceanbase
|
||||
environment:
|
||||
ROOT_PASSWORD: ${OCEANBASE_VECTOR_PASSWORD:-difyai123456}
|
||||
MEMORY_LIMIT: ${SEEKDB_MEMORY_LIMIT:-2G}
|
||||
REPORTER: dify-ai-seekdb
|
||||
healthcheck:
|
||||
test:
|
||||
[
|
||||
"CMD-SHELL",
|
||||
'mysql -h127.0.0.1 -P2881 -uroot
|
||||
-p${OCEANBASE_VECTOR_PASSWORD:-difyai123456} -e "SELECT 1;"'
|
||||
]
|
||||
interval: 5s
|
||||
retries: 60
|
||||
timeout: 5s
|
||||
|
||||
# Qdrant vector store.
|
||||
# (if used, you need to set VECTOR_STORE to qdrant in the api & worker service.)
|
||||
qdrant:
|
||||
image: langgenius/qdrant:v1.7.3
|
||||
image: langgenius/qdrant:v1.8.3
|
||||
profiles:
|
||||
- qdrant
|
||||
restart: always
|
||||
@@ -996,9 +1275,9 @@ services:
|
||||
volumes:
|
||||
- ./volumes/pgvector/data:/var/lib/postgresql/data
|
||||
- ./pgvector/docker-entrypoint.sh:/docker-entrypoint.sh
|
||||
entrypoint: [ '/docker-entrypoint.sh' ]
|
||||
entrypoint: [ "/docker-entrypoint.sh" ]
|
||||
healthcheck:
|
||||
test: [ 'CMD', 'pg_isready' ]
|
||||
test: [ "CMD", "pg_isready" ]
|
||||
interval: 1s
|
||||
timeout: 3s
|
||||
retries: 30
|
||||
@@ -1020,7 +1299,7 @@ services:
|
||||
- ./vastbase/backup:/home/vastbase/backup
|
||||
- ./vastbase/backup_log:/home/vastbase/backup_log
|
||||
healthcheck:
|
||||
test: [ 'CMD', 'pg_isready' ]
|
||||
test: [ "CMD", "pg_isready" ]
|
||||
interval: 1s
|
||||
timeout: 3s
|
||||
retries: 30
|
||||
@@ -1042,7 +1321,7 @@ services:
|
||||
volumes:
|
||||
- ./volumes/pgvecto_rs/data:/var/lib/postgresql/data
|
||||
healthcheck:
|
||||
test: [ 'CMD', 'pg_isready' ]
|
||||
test: [ "CMD", "pg_isready" ]
|
||||
interval: 1s
|
||||
timeout: 3s
|
||||
retries: 30
|
||||
@@ -1060,34 +1339,22 @@ services:
|
||||
CHROMA_SERVER_AUTHN_PROVIDER: ${CHROMA_SERVER_AUTHN_PROVIDER:-chromadb.auth.token_authn.TokenAuthenticationServerProvider}
|
||||
IS_PERSISTENT: ${CHROMA_IS_PERSISTENT:-TRUE}
|
||||
|
||||
# OceanBase vector database
|
||||
oceanbase:
|
||||
image: oceanbase/oceanbase-ce:4.3.5-lts
|
||||
# InterSystems IRIS vector database
|
||||
iris:
|
||||
image: containers.intersystems.com/intersystems/iris-community:2025.3
|
||||
profiles:
|
||||
- oceanbase
|
||||
- iris
|
||||
restart: always
|
||||
init: true
|
||||
volumes:
|
||||
- ./volumes/oceanbase/data:/root/ob
|
||||
- ./volumes/oceanbase/conf:/root/.obd/cluster
|
||||
- ./volumes/oceanbase/init.d:/root/boot/init.d
|
||||
- ./volumes/iris:/durable
|
||||
- ./iris/iris-init.script:/iris-init.script
|
||||
- ./iris/docker-entrypoint.sh:/custom-entrypoint.sh
|
||||
entrypoint: [ "/custom-entrypoint.sh" ]
|
||||
tty: true
|
||||
environment:
|
||||
OB_MEMORY_LIMIT: ${OCEANBASE_MEMORY_LIMIT:-6G}
|
||||
OB_SYS_PASSWORD: ${OCEANBASE_VECTOR_PASSWORD:-difyai123456}
|
||||
OB_TENANT_PASSWORD: ${OCEANBASE_VECTOR_PASSWORD:-difyai123456}
|
||||
OB_CLUSTER_NAME: ${OCEANBASE_CLUSTER_NAME:-difyai}
|
||||
OB_SERVER_IP: 127.0.0.1
|
||||
MODE: mini
|
||||
healthcheck:
|
||||
test:
|
||||
[
|
||||
'CMD-SHELL',
|
||||
'obclient -h127.0.0.1 -P2881 -uroot@test -p$${OB_TENANT_PASSWORD} -e
|
||||
"SELECT 1;"'
|
||||
]
|
||||
interval: 10s
|
||||
retries: 30
|
||||
start_period: 30s
|
||||
timeout: 10s
|
||||
TZ: ${IRIS_TIMEZONE:-UTC}
|
||||
ISC_DATA_DIRECTORY: /durable/iris
|
||||
|
||||
# Oracle vector database
|
||||
oracle:
|
||||
@@ -1119,7 +1386,7 @@ services:
|
||||
command: etcd -advertise-client-urls=http://127.0.0.1:2379 -listen-client-urls
|
||||
http://0.0.0.0:2379 --data-dir /etcd
|
||||
healthcheck:
|
||||
test: [ 'CMD', 'etcdctl', 'endpoint', 'health' ]
|
||||
test: [ "CMD", "etcdctl", "endpoint", "health" ]
|
||||
interval: 30s
|
||||
timeout: 20s
|
||||
retries: 3
|
||||
@@ -1137,7 +1404,7 @@ services:
|
||||
- ./volumes/milvus/minio:/minio_data
|
||||
command: minio server /minio_data --console-address ":9001"
|
||||
healthcheck:
|
||||
test: [ 'CMD', 'curl', '-f', 'http://localhost:9000/minio/health/live' ]
|
||||
test: [ "CMD", "curl", "-f", "http://localhost:9000/minio/health/live" ]
|
||||
interval: 30s
|
||||
timeout: 20s
|
||||
retries: 3
|
||||
@@ -1145,10 +1412,10 @@ services:
|
||||
- milvus
|
||||
|
||||
milvus-standalone:
|
||||
image: milvusdb/milvus:v2.5.15
|
||||
image: milvusdb/milvus:v2.6.3
|
||||
profiles:
|
||||
- milvus
|
||||
command: [ 'milvus', 'run', 'standalone' ]
|
||||
command: [ "milvus", "run", "standalone" ]
|
||||
environment:
|
||||
ETCD_ENDPOINTS: ${ETCD_ENDPOINTS:-etcd:2379}
|
||||
MINIO_ADDRESS: ${MINIO_ADDRESS:-minio:9000}
|
||||
@@ -1156,7 +1423,7 @@ services:
|
||||
volumes:
|
||||
- ./volumes/milvus/milvus:/var/lib/milvus
|
||||
healthcheck:
|
||||
test: [ 'CMD', 'curl', '-f', 'http://localhost:9091/healthz' ]
|
||||
test: [ "CMD", "curl", "-f", "http://localhost:9091/healthz" ]
|
||||
interval: 30s
|
||||
start_period: 90s
|
||||
timeout: 20s
|
||||
@@ -1263,16 +1530,16 @@ services:
|
||||
node.name: dify-es0
|
||||
discovery.type: single-node
|
||||
xpack.license.self_generated.type: basic
|
||||
xpack.security.enabled: 'true'
|
||||
xpack.security.enrollment.enabled: 'false'
|
||||
xpack.security.http.ssl.enabled: 'false'
|
||||
xpack.security.enabled: "true"
|
||||
xpack.security.enrollment.enabled: "false"
|
||||
xpack.security.http.ssl.enabled: "false"
|
||||
deploy:
|
||||
resources:
|
||||
limits:
|
||||
memory: 2g
|
||||
entrypoint: [ 'sh', '-c', "sh /docker-entrypoint-mount.sh" ]
|
||||
entrypoint: [ "sh", "-c", "sh /docker-entrypoint-mount.sh" ]
|
||||
healthcheck:
|
||||
test: [ 'CMD', 'curl', '-s', 'http://localhost:9200/_cluster/health?pretty' ]
|
||||
test: [ "CMD", "curl", "-s", "http://localhost:9200/_cluster/health?pretty" ]
|
||||
interval: 30s
|
||||
timeout: 10s
|
||||
retries: 50
|
||||
@@ -1289,15 +1556,15 @@ services:
|
||||
environment:
|
||||
XPACK_ENCRYPTEDSAVEDOBJECTS_ENCRYPTIONKEY: d1a66dfd-c4d3-4a0a-8290-2abcb83ab3aa
|
||||
NO_PROXY: localhost,127.0.0.1,elasticsearch,kibana
|
||||
XPACK_SECURITY_ENABLED: 'true'
|
||||
XPACK_SECURITY_ENROLLMENT_ENABLED: 'false'
|
||||
XPACK_SECURITY_HTTP_SSL_ENABLED: 'false'
|
||||
XPACK_FLEET_ISAIRGAPPED: 'true'
|
||||
XPACK_SECURITY_ENABLED: "true"
|
||||
XPACK_SECURITY_ENROLLMENT_ENABLED: "false"
|
||||
XPACK_SECURITY_HTTP_SSL_ENABLED: "false"
|
||||
XPACK_FLEET_ISAIRGAPPED: "true"
|
||||
I18N_LOCALE: zh-CN
|
||||
SERVER_PORT: '5601'
|
||||
SERVER_PORT: "5601"
|
||||
ELASTICSEARCH_HOSTS: http://elasticsearch:9200
|
||||
healthcheck:
|
||||
test: [ 'CMD-SHELL', 'curl -s http://localhost:5601 >/dev/null || exit 1' ]
|
||||
test: [ "CMD-SHELL", "curl -s http://localhost:5601 >/dev/null || exit 1" ]
|
||||
interval: 30s
|
||||
timeout: 10s
|
||||
retries: 3
|
||||
|
||||
@@ -9,7 +9,7 @@ def parse_env_example(file_path):
|
||||
Parses the .env.example file and returns a dictionary with variable names as keys and default values as values.
|
||||
"""
|
||||
env_vars = {}
|
||||
with open(file_path, "r") as f:
|
||||
with open(file_path, "r", encoding="utf-8") as f:
|
||||
for line_number, line in enumerate(f, 1):
|
||||
line = line.strip()
|
||||
# Ignore empty lines and comments
|
||||
@@ -55,7 +55,7 @@ def insert_shared_env(template_path, output_path, shared_env_block, header_comme
|
||||
Inserts the shared environment variables block and header comments into the template file,
|
||||
removing any existing x-shared-env anchors, and generates the final docker-compose.yaml file.
|
||||
"""
|
||||
with open(template_path, "r") as f:
|
||||
with open(template_path, "r", encoding="utf-8") as f:
|
||||
template_content = f.read()
|
||||
|
||||
# Remove existing x-shared-env: &shared-api-worker-env lines
|
||||
@@ -69,7 +69,7 @@ def insert_shared_env(template_path, output_path, shared_env_block, header_comme
|
||||
# Prepare the final content with header comments and shared env block
|
||||
final_content = f"{header_comments}\n{shared_env_block}\n\n{template_content}"
|
||||
|
||||
with open(output_path, "w") as f:
|
||||
with open(output_path, "w", encoding="utf-8") as f:
|
||||
f.write(final_content)
|
||||
print(f"Generated {output_path}")
|
||||
|
||||
|
||||
Executable
+56
@@ -0,0 +1,56 @@
|
||||
#!/bin/bash
|
||||
set -e
|
||||
|
||||
# IRIS configuration flag file (stored in durable directory to persist with data)
|
||||
IRIS_CONFIG_DONE="/durable/.iris-configured"
|
||||
|
||||
# Function to wait for IRIS to be ready
|
||||
wait_for_iris() {
|
||||
echo "Waiting for IRIS to be ready..."
|
||||
local max_attempts=30
|
||||
local attempt=1
|
||||
while [ "$attempt" -le "$max_attempts" ]; do
|
||||
if iris qlist IRIS 2>/dev/null | grep -q "running"; then
|
||||
echo "IRIS is ready."
|
||||
return 0
|
||||
fi
|
||||
echo "Attempt $attempt/$max_attempts: IRIS not ready yet, waiting..."
|
||||
sleep 2
|
||||
attempt=$((attempt + 1))
|
||||
done
|
||||
echo "ERROR: IRIS failed to start within expected time." >&2
|
||||
return 1
|
||||
}
|
||||
|
||||
# Function to configure IRIS
|
||||
configure_iris() {
|
||||
echo "Configuring IRIS for first-time setup..."
|
||||
|
||||
# Wait for IRIS to be fully started
|
||||
wait_for_iris
|
||||
|
||||
# Execute the initialization script
|
||||
iris session IRIS < /iris-init.script
|
||||
|
||||
# Mark configuration as done
|
||||
touch "$IRIS_CONFIG_DONE"
|
||||
|
||||
echo "IRIS configuration completed."
|
||||
}
|
||||
|
||||
# Start IRIS in background for initial configuration if not already configured
|
||||
if [ ! -f "$IRIS_CONFIG_DONE" ]; then
|
||||
echo "First-time IRIS setup detected. Starting IRIS for configuration..."
|
||||
|
||||
# Start IRIS
|
||||
iris start IRIS
|
||||
|
||||
# Configure IRIS
|
||||
configure_iris
|
||||
|
||||
# Stop IRIS
|
||||
iris stop IRIS quietly
|
||||
fi
|
||||
|
||||
# Run the original IRIS entrypoint
|
||||
exec /iris-main "$@"
|
||||
@@ -0,0 +1,11 @@
|
||||
// Switch to the %SYS namespace to modify system settings
|
||||
set $namespace="%SYS"
|
||||
|
||||
// Set predefined user passwords to never expire (default password: SYS)
|
||||
Do ##class(Security.Users).UnExpireUserPasswords("*")
|
||||
|
||||
// Change the default password
|
||||
Do $SYSTEM.Security.ChangePassword("_SYSTEM","Dify@1234")
|
||||
|
||||
// Install the Japanese locale (default is English since the container is Ubuntu-based)
|
||||
// Do ##class(Config.NLS.Locales).Install("jpuw")
|
||||
@@ -1,11 +1,17 @@
|
||||
# ------------------------------
|
||||
# Environment Variables for db Service
|
||||
# ------------------------------
|
||||
POSTGRES_USER=postgres
|
||||
# The password for the default postgres user.
|
||||
POSTGRES_PASSWORD=difyai123456
|
||||
# The name of the default postgres database.
|
||||
POSTGRES_DB=dify
|
||||
# Database Configuration
|
||||
# Database type, supported values are `postgresql` and `mysql`
|
||||
DB_TYPE=postgresql
|
||||
# For MySQL, only `root` user is supported for now
|
||||
DB_USERNAME=postgres
|
||||
DB_PASSWORD=difyai123456
|
||||
DB_HOST=db_postgres
|
||||
DB_PORT=5432
|
||||
DB_DATABASE=dify
|
||||
|
||||
# PostgreSQL Configuration
|
||||
# postgres data directory
|
||||
PGDATA=/var/lib/postgresql/data/pgdata
|
||||
PGDATA_HOST_VOLUME=./volumes/db/data
|
||||
@@ -40,11 +46,54 @@ POSTGRES_MAINTENANCE_WORK_MEM=64MB
|
||||
# Reference: https://www.postgresql.org/docs/current/runtime-config-query.html#GUC-EFFECTIVE-CACHE-SIZE
|
||||
POSTGRES_EFFECTIVE_CACHE_SIZE=4096MB
|
||||
|
||||
# Sets the maximum allowed duration of any statement before termination.
|
||||
# Default is 0 (no timeout).
|
||||
#
|
||||
# Reference: https://www.postgresql.org/docs/current/runtime-config-client.html#GUC-STATEMENT-TIMEOUT
|
||||
# A value of 0 prevents the server from timing out statements.
|
||||
POSTGRES_STATEMENT_TIMEOUT=0
|
||||
|
||||
# Sets the maximum allowed duration of any idle in-transaction session before termination.
|
||||
# Default is 0 (no timeout).
|
||||
#
|
||||
# Reference: https://www.postgresql.org/docs/current/runtime-config-client.html#GUC-IDLE-IN-TRANSACTION-SESSION-TIMEOUT
|
||||
# A value of 0 prevents the server from terminating idle sessions.
|
||||
POSTGRES_IDLE_IN_TRANSACTION_SESSION_TIMEOUT=0
|
||||
|
||||
# MySQL Configuration
|
||||
# MySQL data directory host volume
|
||||
MYSQL_HOST_VOLUME=./volumes/mysql/data
|
||||
|
||||
# MySQL Performance Configuration
|
||||
# Maximum number of connections to MySQL
|
||||
# Default is 1000
|
||||
MYSQL_MAX_CONNECTIONS=1000
|
||||
|
||||
# InnoDB buffer pool size
|
||||
# Default is 512M
|
||||
# Recommended value: 70-80% of available memory for dedicated MySQL server
|
||||
# Reference: https://dev.mysql.com/doc/refman/8.0/en/innodb-parameters.html#sysvar_innodb_buffer_pool_size
|
||||
MYSQL_INNODB_BUFFER_POOL_SIZE=512M
|
||||
|
||||
# InnoDB log file size
|
||||
# Default is 128M
|
||||
# Reference: https://dev.mysql.com/doc/refman/8.0/en/innodb-parameters.html#sysvar_innodb_log_file_size
|
||||
MYSQL_INNODB_LOG_FILE_SIZE=128M
|
||||
|
||||
# InnoDB flush log at transaction commit
|
||||
# Default is 2 (flush to OS cache, sync every second)
|
||||
# Options: 0 (no flush), 1 (flush and sync), 2 (flush to OS cache)
|
||||
# Reference: https://dev.mysql.com/doc/refman/8.0/en/innodb-parameters.html#sysvar_innodb_flush_log_at_trx_commit
|
||||
MYSQL_INNODB_FLUSH_LOG_AT_TRX_COMMIT=2
|
||||
|
||||
# -----------------------------
|
||||
# Environment Variables for redis Service
|
||||
# -----------------------------
|
||||
REDIS_HOST_VOLUME=./volumes/redis/data
|
||||
REDIS_PASSWORD=difyai123456
|
||||
# Optional: limit total Redis connections used by API/Worker (unset for default)
|
||||
# Align with API's REDIS_MAX_CONNECTIONS in configs
|
||||
REDIS_MAX_CONNECTIONS=
|
||||
|
||||
# ------------------------------
|
||||
# Environment Variables for sandbox Service
|
||||
@@ -77,12 +126,21 @@ WEAVIATE_AUTHENTICATION_APIKEY_ALLOWED_KEYS=WVF5YThaHlkYwhGUSmCRgsX3tD5ngdN8pkih
|
||||
WEAVIATE_AUTHENTICATION_APIKEY_USERS=hello@dify.ai
|
||||
WEAVIATE_AUTHORIZATION_ADMINLIST_ENABLED=true
|
||||
WEAVIATE_AUTHORIZATION_ADMINLIST_USERS=hello@dify.ai
|
||||
WEAVIATE_DISABLE_TELEMETRY=false
|
||||
WEAVIATE_HOST_VOLUME=./volumes/weaviate
|
||||
|
||||
# ------------------------------
|
||||
# Docker Compose profile configuration
|
||||
# ------------------------------
|
||||
# Loaded automatically when running `docker compose --env-file middleware.env ...`.
|
||||
# Controls which DB/vector services start, so no extra `--profile` flag is needed.
|
||||
COMPOSE_PROFILES=${DB_TYPE:-postgresql},weaviate
|
||||
|
||||
# ------------------------------
|
||||
# Docker Compose Service Expose Host Port Configurations
|
||||
# ------------------------------
|
||||
EXPOSE_POSTGRES_PORT=5432
|
||||
EXPOSE_MYSQL_PORT=3306
|
||||
EXPOSE_REDIS_PORT=6379
|
||||
EXPOSE_SANDBOX_PORT=8194
|
||||
EXPOSE_SSRF_PROXY_PORT=3128
|
||||
@@ -158,3 +216,28 @@ PLUGIN_VOLCENGINE_TOS_ENDPOINT=
|
||||
PLUGIN_VOLCENGINE_TOS_ACCESS_KEY=
|
||||
PLUGIN_VOLCENGINE_TOS_SECRET_KEY=
|
||||
PLUGIN_VOLCENGINE_TOS_REGION=
|
||||
|
||||
# ------------------------------
|
||||
# Environment Variables for Aliyun SLS (Simple Log Service)
|
||||
# ------------------------------
|
||||
# Aliyun SLS Access Key ID
|
||||
ALIYUN_SLS_ACCESS_KEY_ID=
|
||||
# Aliyun SLS Access Key Secret
|
||||
ALIYUN_SLS_ACCESS_KEY_SECRET=
|
||||
# Aliyun SLS Endpoint (e.g., cn-hangzhou.log.aliyuncs.com)
|
||||
ALIYUN_SLS_ENDPOINT=
|
||||
# Aliyun SLS Region (e.g., cn-hangzhou)
|
||||
ALIYUN_SLS_REGION=
|
||||
# Aliyun SLS Project Name
|
||||
ALIYUN_SLS_PROJECT_NAME=
|
||||
# Aliyun SLS Logstore TTL (default: 365 days, 3650 for permanent storage)
|
||||
ALIYUN_SLS_LOGSTORE_TTL=365
|
||||
# Enable dual-write to both LogStore and SQL database (default: true)
|
||||
LOGSTORE_DUAL_WRITE_ENABLED=true
|
||||
# Enable dual-read fallback to SQL database when LogStore returns no results (default: true)
|
||||
# Useful for migration scenarios where historical data exists only in SQL database
|
||||
LOGSTORE_DUAL_READ_ENABLED=true
|
||||
# Control flag for whether to write the `graph` field to LogStore.
|
||||
# If LOGSTORE_ENABLE_PUT_GRAPH_FIELD is "true", write the full `graph` field;
|
||||
# otherwise write an empty {} instead. Defaults to writing the `graph` field.
|
||||
LOGSTORE_ENABLE_PUT_GRAPH_FIELD=true
|
||||
@@ -39,10 +39,17 @@ server {
|
||||
proxy_pass http://web:3000;
|
||||
include proxy.conf;
|
||||
}
|
||||
|
||||
location /mcp {
|
||||
proxy_pass http://api:5001;
|
||||
include proxy.conf;
|
||||
}
|
||||
|
||||
location /triggers {
|
||||
proxy_pass http://api:5001;
|
||||
include proxy.conf;
|
||||
}
|
||||
|
||||
# placeholder for acme challenge location
|
||||
${ACME_CHALLENGE_LOCATION}
|
||||
|
||||
|
||||
@@ -54,3 +54,52 @@ http_access allow src_all
|
||||
|
||||
# Unless the option's size is increased, an error will occur when uploading more than two files.
|
||||
client_request_buffer_max_size 100 MB
|
||||
|
||||
################################## Performance & Concurrency ###############################
|
||||
# Increase file descriptor limit for high concurrency
|
||||
max_filedescriptors 65536
|
||||
|
||||
# Timeout configurations for image requests
|
||||
connect_timeout 30 seconds
|
||||
request_timeout 2 minutes
|
||||
read_timeout 2 minutes
|
||||
client_lifetime 5 minutes
|
||||
shutdown_lifetime 30 seconds
|
||||
|
||||
# Persistent connections - improve performance for multiple requests
|
||||
server_persistent_connections on
|
||||
client_persistent_connections on
|
||||
persistent_request_timeout 30 seconds
|
||||
pconn_timeout 1 minute
|
||||
|
||||
# Connection pool and concurrency limits
|
||||
client_db on
|
||||
server_idle_pconn_timeout 2 minutes
|
||||
client_idle_pconn_timeout 2 minutes
|
||||
|
||||
# Quick abort settings - don't abort requests that are mostly done
|
||||
quick_abort_min 16 KB
|
||||
quick_abort_max 16 MB
|
||||
quick_abort_pct 95
|
||||
|
||||
# Memory and cache optimization
|
||||
memory_cache_mode disk
|
||||
cache_mem 256 MB
|
||||
maximum_object_size_in_memory 512 KB
|
||||
|
||||
# DNS resolver settings for better performance
|
||||
dns_timeout 30 seconds
|
||||
dns_retransmit_interval 5 seconds
|
||||
# By default, Squid uses the system's configured DNS resolvers.
|
||||
# If you need to override them, set dns_nameservers to appropriate servers
|
||||
# for your environment (for example, internal/corporate DNS). The following
|
||||
# is an example using public DNS and SHOULD be customized before use:
|
||||
# dns_nameservers 8.8.8.8 8.8.4.4
|
||||
|
||||
# Logging format for better debugging
|
||||
logformat dify_log %ts.%03tu %6tr %>a %Ss/%03>Hs %<st %rm %ru %[un %Sh/%<a %mt
|
||||
access_log daemon:/var/log/squid/access.log dify_log
|
||||
|
||||
# Access log to track concurrent requests and timeouts
|
||||
logfile_rotate 10
|
||||
|
||||
|
||||
@@ -55,7 +55,8 @@ services:
|
||||
- ./volumes/data:/data
|
||||
- ./volumes/logs:/logs
|
||||
command:
|
||||
- --config=/tiflash.toml
|
||||
- server
|
||||
- --config-file=/tiflash.toml
|
||||
depends_on:
|
||||
- "tikv"
|
||||
- "tidb"
|
||||
|
||||
@@ -1,6 +1,5 @@
|
||||
APP_DOMAIN=$(PRIMARY_DOMAIN)
|
||||
APP_RELEASE=v0.28.0
|
||||
SSL=false
|
||||
APP_RELEASE=v1.2.3
|
||||
|
||||
WEB_REPLICAS=1
|
||||
SPACE_REPLICAS=1
|
||||
@@ -77,6 +76,10 @@ MINIO_ENDPOINT_SSL=0
|
||||
|
||||
# API key rate limit
|
||||
API_KEY_RATE_LIMIT=60/minute
|
||||
|
||||
# Live server environment variables
|
||||
# WARNING: You must set a secure value for LIVE_SERVER_SECRET_KEY in production environments.
|
||||
LIVE_SERVER_SECRET_KEY=
|
||||
DOCKERHUB_USER=artifacts.plane.so/makeplane
|
||||
PULL_POLICY=if_not_present
|
||||
CUSTOM_BUILD=false
|
||||
|
||||
@@ -24,7 +24,6 @@ x-aws-s3-env: &aws-s3-env
|
||||
AWS_S3_BUCKET_NAME: ${AWS_S3_BUCKET_NAME:-uploads}
|
||||
|
||||
x-proxy-env: &proxy-env
|
||||
SSL: ${SSL:-false}
|
||||
APP_DOMAIN: ${APP_DOMAIN:-localhost}
|
||||
FILE_SIZE_LIMIT: ${FILE_SIZE_LIMIT:-5242880}
|
||||
CERT_EMAIL: ${CERT_EMAIL}
|
||||
@@ -47,6 +46,7 @@ x-mq-env:
|
||||
|
||||
x-live-env: &live-env
|
||||
API_BASE_URL: ${API_BASE_URL:-http://api:8000}
|
||||
LIVE_SERVER_SECRET_KEY: ${LIVE_SERVER_SECRET_KEY:-2FiJk1U2aiVPEQtzLehYGlTSnTnrs7LW}
|
||||
|
||||
x-app-env: &app-env
|
||||
WEB_URL: ${WEB_URL:-http://localhost}
|
||||
@@ -59,58 +59,59 @@ x-app-env: &app-env
|
||||
AMQP_URL: ${AMQP_URL:-amqp://plane:plane@plane-mq:5672/plane}
|
||||
API_KEY_RATE_LIMIT: ${API_KEY_RATE_LIMIT:-60/minute}
|
||||
MINIO_ENDPOINT_SSL: ${MINIO_ENDPOINT_SSL:-0}
|
||||
LIVE_SERVER_SECRET_KEY: ${LIVE_SERVER_SECRET_KEY:-2FiJk1U2aiVPEQtzLehYGlTSnTnrs7LW}
|
||||
|
||||
services:
|
||||
web:
|
||||
image: artifacts.plane.so/makeplane/plane-frontend:${APP_RELEASE:-v0.28.0}
|
||||
image: artifacts.plane.so/makeplane/plane-frontend:${APP_RELEASE:-v1.2.3}
|
||||
deploy:
|
||||
replicas: ${WEB_REPLICAS:-1}
|
||||
restart_policy:
|
||||
condition: on-failure
|
||||
condition: any
|
||||
depends_on:
|
||||
- api
|
||||
- worker
|
||||
|
||||
space:
|
||||
image: artifacts.plane.so/makeplane/plane-space:${APP_RELEASE:-v0.28.0}
|
||||
image: artifacts.plane.so/makeplane/plane-space:${APP_RELEASE:-v1.2.3}
|
||||
deploy:
|
||||
replicas: ${SPACE_REPLICAS:-1}
|
||||
restart_policy:
|
||||
condition: on-failure
|
||||
condition: any
|
||||
depends_on:
|
||||
- api
|
||||
- worker
|
||||
- web
|
||||
|
||||
admin:
|
||||
image: artifacts.plane.so/makeplane/plane-admin:${APP_RELEASE:-v0.28.0}
|
||||
image: artifacts.plane.so/makeplane/plane-admin:${APP_RELEASE:-v1.2.3}
|
||||
deploy:
|
||||
replicas: ${ADMIN_REPLICAS:-1}
|
||||
restart_policy:
|
||||
condition: on-failure
|
||||
condition: any
|
||||
depends_on:
|
||||
- api
|
||||
- web
|
||||
|
||||
live:
|
||||
image: artifacts.plane.so/makeplane/plane-live:${APP_RELEASE:-v0.28.0}
|
||||
image: artifacts.plane.so/makeplane/plane-live:${APP_RELEASE:-v1.2.3}
|
||||
environment:
|
||||
<<: [ *live-env ]
|
||||
<<: [ *live-env, *redis-env ]
|
||||
deploy:
|
||||
replicas: ${LIVE_REPLICAS:-1}
|
||||
restart_policy:
|
||||
condition: on-failure
|
||||
condition: any
|
||||
depends_on:
|
||||
- api
|
||||
- web
|
||||
|
||||
api:
|
||||
image: artifacts.plane.so/makeplane/plane-backend:${APP_RELEASE:-v0.28.0}
|
||||
image: artifacts.plane.so/makeplane/plane-backend:${APP_RELEASE:-v1.2.3}
|
||||
command: ./bin/docker-entrypoint-api.sh
|
||||
deploy:
|
||||
replicas: ${API_REPLICAS:-1}
|
||||
restart_policy:
|
||||
condition: on-failure
|
||||
condition: any
|
||||
volumes:
|
||||
- logs_api:/code/plane/logs
|
||||
environment:
|
||||
@@ -121,12 +122,12 @@ services:
|
||||
- plane-mq
|
||||
|
||||
worker:
|
||||
image: artifacts.plane.so/makeplane/plane-backend:${APP_RELEASE:-v0.28.0}
|
||||
image: artifacts.plane.so/makeplane/plane-backend:${APP_RELEASE:-v1.2.3}
|
||||
command: ./bin/docker-entrypoint-worker.sh
|
||||
deploy:
|
||||
replicas: ${WORKER_REPLICAS:-1}
|
||||
restart_policy:
|
||||
condition: on-failure
|
||||
condition: any
|
||||
volumes:
|
||||
- logs_worker:/code/plane/logs
|
||||
environment:
|
||||
@@ -138,12 +139,12 @@ services:
|
||||
- plane-mq
|
||||
|
||||
beat-worker:
|
||||
image: artifacts.plane.so/makeplane/plane-backend:${APP_RELEASE:-v0.28.0}
|
||||
image: artifacts.plane.so/makeplane/plane-backend:${APP_RELEASE:-v1.2.3}
|
||||
command: ./bin/docker-entrypoint-beat.sh
|
||||
deploy:
|
||||
replicas: ${BEAT_WORKER_REPLICAS:-1}
|
||||
restart_policy:
|
||||
condition: on-failure
|
||||
condition: any
|
||||
volumes:
|
||||
- logs_beat-worker:/code/plane/logs
|
||||
environment:
|
||||
@@ -155,7 +156,7 @@ services:
|
||||
- plane-mq
|
||||
|
||||
migrator:
|
||||
image: artifacts.plane.so/makeplane/plane-backend:${APP_RELEASE:-v0.28.0}
|
||||
image: artifacts.plane.so/makeplane/plane-backend:${APP_RELEASE:-v1.2.3}
|
||||
command: ./bin/docker-entrypoint-migrator.sh
|
||||
deploy:
|
||||
replicas: 1
|
||||
@@ -176,18 +177,18 @@ services:
|
||||
deploy:
|
||||
replicas: 1
|
||||
restart_policy:
|
||||
condition: on-failure
|
||||
condition: any
|
||||
environment:
|
||||
<<: *db-env
|
||||
volumes:
|
||||
- pgdata:/var/lib/postgresql/data
|
||||
|
||||
plane-redis:
|
||||
image: valkey/valkey:7.2.5-alpine
|
||||
image: valkey/valkey:7.2.11-alpine
|
||||
deploy:
|
||||
replicas: 1
|
||||
restart_policy:
|
||||
condition: on-failure
|
||||
condition: any
|
||||
volumes:
|
||||
- redisdata:/data
|
||||
|
||||
@@ -196,7 +197,7 @@ services:
|
||||
deploy:
|
||||
replicas: 1
|
||||
restart_policy:
|
||||
condition: on-failure
|
||||
condition: any
|
||||
environment:
|
||||
<<: *mq-env
|
||||
volumes:
|
||||
@@ -209,7 +210,7 @@ services:
|
||||
deploy:
|
||||
replicas: 1
|
||||
restart_policy:
|
||||
condition: on-failure
|
||||
condition: any
|
||||
environment:
|
||||
<<: *minio-env
|
||||
volumes:
|
||||
@@ -217,20 +218,11 @@ services:
|
||||
|
||||
# Comment this if you already have a reverse proxy running
|
||||
proxy:
|
||||
image: artifacts.plane.so/makeplane/plane-proxy:${APP_RELEASE:-v0.28.0}
|
||||
command:
|
||||
[
|
||||
"caddy",
|
||||
"run",
|
||||
"--config",
|
||||
"/etc/caddy/Caddyfile",
|
||||
"--adapter",
|
||||
"caddyfile"
|
||||
]
|
||||
image: artifacts.plane.so/makeplane/plane-proxy:${APP_RELEASE:-v1.2.3}
|
||||
deploy:
|
||||
replicas: 1
|
||||
restart_policy:
|
||||
condition: on-failure
|
||||
condition: any
|
||||
environment:
|
||||
<<: *proxy-env
|
||||
volumes:
|
||||
|
||||
Regular → Executable
+197
-39
@@ -1,69 +1,126 @@
|
||||
############
|
||||
# Secrets
|
||||
# YOU MUST CHANGE THESE BEFORE GOING INTO PRODUCTION
|
||||
#
|
||||
# YOU MUST CHANGE ALL THE DEFAULT VALUES BELOW BEFORE STARTING
|
||||
# THE CONTAINERS FOR THE FIRST TIME!
|
||||
#
|
||||
# Documentation:
|
||||
# https://supabase.com/docs/guides/self-hosting/docker#configuring-and-securing-supabase
|
||||
#
|
||||
# To generate secrets and API keys:
|
||||
# sh ./utils/generate-keys.sh
|
||||
#
|
||||
############
|
||||
|
||||
# Postgres
|
||||
POSTGRES_PASSWORD=your-super-secret-and-long-postgres-password
|
||||
|
||||
# Symmetric encryption key and JWT API keys
|
||||
JWT_SECRET=your-super-secret-jwt-token-with-at-least-32-characters-long
|
||||
ANON_KEY=eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyAgCiAgICAicm9sZSI6ICJhbm9uIiwKICAgICJpc3MiOiAic3VwYWJhc2UtZGVtbyIsCiAgICAiaWF0IjogMTY0MTc2OTIwMCwKICAgICJleHAiOiAxNzk5NTM1NjAwCn0.dc_X5iR_VP_qT0zsiyj_I_OZ2T9FtRU2BBNWN8Bu4GE
|
||||
SERVICE_ROLE_KEY=eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyAgCiAgICAicm9sZSI6ICJzZXJ2aWNlX3JvbGUiLAogICAgImlzcyI6ICJzdXBhYmFzZS1kZW1vIiwKICAgICJpYXQiOiAxNjQxNzY5MjAwLAogICAgImV4cCI6IDE3OTk1MzU2MDAKfQ.DaYlNEoUrrEn2Ig7tqibS-PHK5vgusbcbo7X36XVt4Q
|
||||
|
||||
# Access to Dashboard
|
||||
DASHBOARD_USERNAME=supabase
|
||||
DASHBOARD_PASSWORD=this_password_is_insecure_and_should_be_updated
|
||||
|
||||
# Used by Realtime and Supavisor
|
||||
SECRET_KEY_BASE=UpNVntn3cDxHJpq99YMc1T1AQgQpc8kfYTuRgBiYa15BLrx8etQoXz3gZv1/u2oq
|
||||
VAULT_ENC_KEY=your-encryption-key-32-chars-min
|
||||
|
||||
# Used by Supavisor
|
||||
VAULT_ENC_KEY=your-32-character-encryption-key
|
||||
|
||||
# Used by Studio to access Postgres via postgres-meta
|
||||
PG_META_CRYPTO_KEY=your-encryption-key-32-chars-min
|
||||
|
||||
# Analytics - API tokens for log ingestion/querying, and for management
|
||||
LOGFLARE_PUBLIC_ACCESS_TOKEN=your-super-secret-and-long-logflare-key-public
|
||||
LOGFLARE_PRIVATE_ACCESS_TOKEN=your-super-secret-and-long-logflare-key-private
|
||||
|
||||
# Access to Storage via S3 protocol endpoint (see below)
|
||||
S3_PROTOCOL_ACCESS_KEY_ID=625729a08b95bf1b7ff351a663f3a23c
|
||||
S3_PROTOCOL_ACCESS_KEY_SECRET=850181e4652dd023b7a98c58ae0d2d34bd487ee0cc3254aed6eda37307425907
|
||||
|
||||
|
||||
############
|
||||
# Database - You can change these to any PostgreSQL database that has logical replication enabled.
|
||||
# URLs - Configure hostnames below to reflect your actual domain name
|
||||
############
|
||||
|
||||
# Access to Dashboard and REST API
|
||||
SUPABASE_PUBLIC_URL=http://localhost:8000
|
||||
|
||||
# Full external URL of the Auth service, used to construct OAuth callbacks,
|
||||
# SAML endpoints, and email links
|
||||
API_EXTERNAL_URL=http://localhost:8000
|
||||
|
||||
# See also the Auth section below for Site URL and Redirect URLs configuration
|
||||
|
||||
|
||||
############
|
||||
# Database - Postgres configuration
|
||||
############
|
||||
|
||||
# Using default user (postgres)
|
||||
POSTGRES_HOST=db
|
||||
POSTGRES_DB=postgres
|
||||
|
||||
# Default configuration includes Supavisor exposing POSTGRES_PORT
|
||||
# Postgres uses POSTGRES_PORT inside the container
|
||||
# Documentation:
|
||||
# https://supabase.com/docs/guides/self-hosting/docker#accessing-postgres-through-supavisor
|
||||
POSTGRES_PORT=5432
|
||||
# default user is postgres
|
||||
|
||||
|
||||
############
|
||||
# Supavisor -- Database pooler
|
||||
# Supavisor - Database pooler
|
||||
############
|
||||
# Port Supavisor listens on for transaction pooling connections
|
||||
|
||||
# Supavisor exposes POSTGRES_PORT and POOLER_PROXY_PORT_TRANSACTION,
|
||||
# POSTGRES_PORT is used for session mode pooling
|
||||
#
|
||||
# Port to use for transaction mode pooling connections
|
||||
POOLER_PROXY_PORT_TRANSACTION=6543
|
||||
|
||||
# Maximum number of PostgreSQL connections Supavisor opens per pool
|
||||
POOLER_DEFAULT_POOL_SIZE=20
|
||||
|
||||
# Maximum number of client connections Supavisor accepts per pool
|
||||
POOLER_MAX_CLIENT_CONN=100
|
||||
# Unique tenant identifier
|
||||
|
||||
# Unique Supavisor tenant identifier
|
||||
# Documentation:
|
||||
# https://supabase.com/docs/guides/self-hosting/docker#accessing-postgres
|
||||
POOLER_TENANT_ID=your-tenant-id
|
||||
|
||||
# Pool size for internal metadata storage used by Supavisor
|
||||
# This is separate from client connections and used only by Supavisor itself
|
||||
POOLER_DB_POOL_SIZE=5
|
||||
|
||||
|
||||
############
|
||||
# API Proxy - Configuration for the Kong Reverse proxy.
|
||||
# Studio - Configuration for the Dashboard
|
||||
############
|
||||
|
||||
KONG_HTTP_PORT=8000
|
||||
KONG_HTTPS_PORT=8443
|
||||
STUDIO_DEFAULT_ORGANIZATION=Default Organization
|
||||
STUDIO_DEFAULT_PROJECT=Default Project
|
||||
|
||||
# Add your OpenAI API key to enable AI Assistant
|
||||
OPENAI_API_KEY=sk-proj-xxxxxxxx
|
||||
|
||||
|
||||
############
|
||||
# API - Configuration for PostgREST.
|
||||
# Auth - Configuration for the authentication server
|
||||
############
|
||||
|
||||
PGRST_DB_SCHEMAS=public,storage,graphql_public
|
||||
## General settings
|
||||
|
||||
|
||||
############
|
||||
# Auth - Configuration for the GoTrue authentication server.
|
||||
############
|
||||
|
||||
## General
|
||||
# Equivalent to "Site URL" and "Redirect URLs" platform configuration options
|
||||
# Documentation: https://supabase.com/docs/guides/auth/redirect-urls
|
||||
SITE_URL=https://$(PRIMARY_DOMAIN)
|
||||
ADDITIONAL_REDIRECT_URLS=
|
||||
|
||||
JWT_EXPIRY=3600
|
||||
DISABLE_SIGNUP=false
|
||||
API_EXTERNAL_URL=http://localhost:8000
|
||||
|
||||
## Mailer Config
|
||||
MAILER_URLPATHS_CONFIRMATION="/auth/v1/verify"
|
||||
@@ -86,41 +143,107 @@ ENABLE_ANONYMOUS_USERS=false
|
||||
ENABLE_PHONE_SIGNUP=true
|
||||
ENABLE_PHONE_AUTOCONFIRM=true
|
||||
|
||||
## OAuth / Social login providers
|
||||
|
||||
############
|
||||
# Studio - Configuration for the Dashboard
|
||||
############
|
||||
# Uncomment and fill in the providers you want to enable.
|
||||
# You must ALSO uncomment the matching GOTRUE_EXTERNAL_* lines in docker-compose.yml.
|
||||
# Documentation: https://supabase.com/docs/guides/self-hosting/self-hosted-oauth
|
||||
# GOOGLE_ENABLED=false
|
||||
# GOOGLE_CLIENT_ID=
|
||||
# GOOGLE_SECRET=
|
||||
|
||||
STUDIO_DEFAULT_ORGANIZATION=Default Organization
|
||||
STUDIO_DEFAULT_PROJECT=Default Project
|
||||
# GITHUB_ENABLED=false
|
||||
# GITHUB_CLIENT_ID=
|
||||
# GITHUB_SECRET=
|
||||
|
||||
STUDIO_PORT=3000
|
||||
# replace if you intend to use Studio outside of localhost
|
||||
SUPABASE_PUBLIC_URL=http://localhost:8000
|
||||
# AZURE_ENABLED=false
|
||||
# AZURE_CLIENT_ID=
|
||||
# AZURE_SECRET=
|
||||
|
||||
# Enable webp support
|
||||
IMGPROXY_ENABLE_WEBP_DETECTION=true
|
||||
# Phone / SMS provider configuration
|
||||
# Uncomment to configure SMS delivery for phone auth and phone MFA.
|
||||
# You must ALSO uncomment the matching GOTRUE_SMS_* lines in docker-compose.yml.
|
||||
# Documentation: https://supabase.com/docs/guides/self-hosting/self-hosted-phone-mfa
|
||||
# SMS_PROVIDER=twilio
|
||||
# SMS_OTP_EXP=60
|
||||
# SMS_OTP_LENGTH=6
|
||||
# SMS_MAX_FREQUENCY=60s
|
||||
# SMS_TEMPLATE=Your code is {{ .Code }}
|
||||
|
||||
# Add your OpenAI API key to enable SQL Editor Assistant
|
||||
OPENAI_API_KEY=
|
||||
# SMS_TWILIO_ACCOUNT_SID=
|
||||
# SMS_TWILIO_AUTH_TOKEN=
|
||||
# SMS_TWILIO_MESSAGE_SERVICE_SID=
|
||||
|
||||
# Test OTP: map phone numbers to fixed OTP codes for development
|
||||
# Format: phone1:code1,phone2:code2
|
||||
# SMS_TEST_OTP=
|
||||
|
||||
# Multi-factor authentication (MFA)
|
||||
# Uncomment to change MFA defaults.
|
||||
# You must ALSO uncomment the matching GOTRUE_MFA_* lines in docker-compose.yml.
|
||||
|
||||
# App Authenticator (TOTP) - enabled by default
|
||||
# MFA_TOTP_ENROLL_ENABLED=true
|
||||
# MFA_TOTP_VERIFY_ENABLED=true
|
||||
|
||||
# Phone MFA - disabled by default (opt-in)
|
||||
# MFA_PHONE_ENROLL_ENABLED=false
|
||||
# MFA_PHONE_VERIFY_ENABLED=false
|
||||
|
||||
## Maximum MFA factors a user can enroll
|
||||
# MFA_MAX_ENROLLED_FACTORS=10
|
||||
|
||||
|
||||
############
|
||||
# Functions - Configuration for Functions
|
||||
# Storage - Configuration for Storage
|
||||
############
|
||||
# NOTE: VERIFY_JWT applies to all functions. Per-function VERIFY_JWT is not supported yet.
|
||||
|
||||
# Check the S3_PROTOCOL_ACCESS_KEY_ID/SECRET above, and
|
||||
# refer to the documentation at:
|
||||
# https://supabase.com/docs/guides/self-hosting/self-hosted-s3
|
||||
# to learn how to configure the S3 protocol endpoint
|
||||
|
||||
# S3 bucket when using S3 backend, directory name when using 'file'
|
||||
GLOBAL_S3_BUCKET=stub
|
||||
|
||||
# Used for S3 protocol endpoint configuration
|
||||
REGION=stub
|
||||
|
||||
# Used by MinIO when added via:
|
||||
# docker compose -f docker-compose.yml -f docker-compose.s3.yml up -d
|
||||
MINIO_ROOT_USER=supa-storage
|
||||
MINIO_ROOT_PASSWORD=secret1234
|
||||
|
||||
# Equivalent to project_ref as described here:
|
||||
# https://supabase.com/docs/guides/storage/s3/authentication#session-token
|
||||
STORAGE_TENANT_ID=stub
|
||||
|
||||
|
||||
############
|
||||
# Functions - Configuration for Edge functions
|
||||
############
|
||||
|
||||
# Documentation:
|
||||
# https://supabase.com/docs/guides/self-hosting/self-hosted-functions
|
||||
|
||||
# NOTE: VERIFY_JWT applies to all functions
|
||||
FUNCTIONS_VERIFY_JWT=false
|
||||
|
||||
|
||||
############
|
||||
# Logs - Configuration for Analytics
|
||||
# Please refer to https://supabase.com/docs/reference/self-hosting-analytics/introduction
|
||||
# API - Configuration for PostgREST
|
||||
############
|
||||
|
||||
# Change vector.toml sinks to reflect this change
|
||||
# these cannot be the same value
|
||||
LOGFLARE_PUBLIC_ACCESS_TOKEN=your-super-secret-and-long-logflare-key-public
|
||||
LOGFLARE_PRIVATE_ACCESS_TOKEN=your-super-secret-and-long-logflare-key-private
|
||||
# Postgres schemas exposed via the REST API
|
||||
PGRST_DB_SCHEMAS=public,storage,graphql_public
|
||||
|
||||
|
||||
############
|
||||
# Analytics - Configuration for Logflare
|
||||
############
|
||||
|
||||
# Check the LOGFLARE_* access token configuration above.
|
||||
# If Logflare is externally exposed, configure securely!
|
||||
|
||||
# Docker socket location - this value will differ depending on your OS
|
||||
DOCKER_SOCKET_LOCATION=/var/run/docker.sock
|
||||
@@ -128,3 +251,38 @@ DOCKER_SOCKET_LOCATION=/var/run/docker.sock
|
||||
# Google Cloud Project details
|
||||
GOOGLE_PROJECT_ID=GOOGLE_PROJECT_ID
|
||||
GOOGLE_PROJECT_NUMBER=GOOGLE_PROJECT_NUMBER
|
||||
|
||||
|
||||
############
|
||||
# API Proxy - Configuration for the Kong API gateway
|
||||
############
|
||||
|
||||
KONG_HTTP_PORT=8000
|
||||
KONG_HTTPS_PORT=8443
|
||||
|
||||
|
||||
############
|
||||
# imgproxy
|
||||
############
|
||||
|
||||
# Enable webp support
|
||||
IMGPROXY_ENABLE_WEBP_DETECTION=true
|
||||
|
||||
|
||||
############
|
||||
# TLS Proxy - Optional Caddy or Nginx reverse proxy with Let's Encrypt
|
||||
############
|
||||
|
||||
# Documentation:
|
||||
# https://supabase.com/docs/guides/self-hosting/self-hosted-proxy-https
|
||||
|
||||
# Usage:
|
||||
# docker compose -f docker-compose.yml -f docker-compose.caddy.yml up -d
|
||||
# docker compose -f docker-compose.yml -f docker-compose.nginx.yml up -d
|
||||
|
||||
# Domain name for the proxy (must point to your server)
|
||||
PROXY_DOMAIN=your-domain.example.com
|
||||
|
||||
# Email for Let's Encrypt certificate notifications (nginx only, Caddy uses PROXY_DOMAIN).
|
||||
# This should be a valid email, not a placehoder (otherwise Certbot may fail to start).
|
||||
CERTBOT_EMAIL=admin@example.com
|
||||
|
||||
@@ -0,0 +1,383 @@
|
||||
# Changelog
|
||||
|
||||
All notable changes to the Supabase self-hosted Docker configuration.
|
||||
|
||||
Changes are grouped by service rather than by change type. See [versions.md](./versions.md)
|
||||
for complete image version history and rollback information.
|
||||
|
||||
Check updates for each service to learn more.
|
||||
|
||||
**Note:** Configuration updates marked with "requires [...] update" are already included in the latest version of the repository. Pull the latest changes or refer to the linked PR for manual updates. After updating `docker-compose.yml`, pull latest images and recreate containers - use `docker compose pull && docker compose down && docker compose up -d`.
|
||||
|
||||
---
|
||||
|
||||
## Unreleased
|
||||
|
||||
---
|
||||
|
||||
## [2026-02-18]
|
||||
|
||||
### Storage
|
||||
- Updated `supabase/storage-api` to `v1.37.8` in `docker-compose.s3.yml`
|
||||
- Changed MinIO image in `docker-compose.s3.yml` to use Chainguard [minio](https://images.chainguard.dev/directory/image/minio/overview) and [minio-client](https://images.chainguard.dev/directory/image/minio-client/overview) (requires `docker-compose.s3.yml` update) - PR [#42942](https://github.com/supabase/supabase/pull/42942)
|
||||
- Removed `imgproxy` service from `docker-compose.s3.yml` to minimize redundancy - PR [#42942](https://github.com/supabase/supabase/pull/42942)
|
||||
- Fixed inconsistent `storage` service entry ordering in `docker-compose.yml` and `docker-compose.s3.yml` to improve diff readability (requires `docker-compose.yml` and `docker-compose.s3.yml` update) - PR [#42942](https://github.com/supabase/supabase/pull/42942)
|
||||
|
||||
### Edge Runtime
|
||||
|
||||
- Added a `deno-cache` named volume to to avoid re-downloading dependencies (requires `docker-compose.yml` and `volumes/functions/*` update) - PR [#40822](https://github.com/supabase/supabase/pull/40822)
|
||||
|
||||
---
|
||||
|
||||
## [2026-02-16]
|
||||
|
||||
⚠️ **Note:** This update includes several breaking changes, including a security fix for Analytics. Please check the details below. The following configuration files have been updated: `docker-compose.yml`, `.env.example`, `docker-compose.s3.yml`, `volumes/api/kong.yml`, and `volumes/logs/vector.yml`.
|
||||
|
||||
### Studio
|
||||
- Updated to `2026.02.16-sha-26c615c`
|
||||
- Added Edge Functions management UI (requires `docker-compose.yml` update) - PR [#40690](https://github.com/supabase/supabase/pull/40690), PR [#42322](https://github.com/supabase/supabase/pull/42322), PR [#42349](https://github.com/supabase/supabase/pull/42349), PR [#42350](https://github.com/supabase/supabase/pull/42350)
|
||||
|
||||
### MCP Server
|
||||
- Updated to `v0.6.3` - [Release](https://github.com/supabase-community/supabase-mcp/releases/tag/v0.6.3)
|
||||
|
||||
### Auth
|
||||
|
||||
- Updated to `v2.186.0` - [Changelog](https://github.com/supabase/auth/blob/master/CHANGELOG.md) | [Release](https://github.com/supabase/auth/releases/tag/v2.186.0)
|
||||
|
||||
### PostgREST
|
||||
|
||||
- Updated to `v14.5` - [Changelog](https://github.com/PostgREST/postgrest/blob/main/CHANGELOG.md) | [Release](https://github.com/PostgREST/postgrest/releases/tag/v14.5)
|
||||
|
||||
### Realtime
|
||||
|
||||
- Updated to `v2.76.5` - [Release](https://github.com/supabase/realtime/releases/tag/v2.76.5)
|
||||
|
||||
### Storage
|
||||
|
||||
- Updated to `v1.37.8` - [Release](https://github.com/supabase/storage/releases/tag/v1.37.8)
|
||||
- ⚠️ Added configuration to access buckets via `/storage/v1/s3` endpoint (requires `docker-compose.s3.yml` update) - PR [#37185](https://github.com/supabase/supabase/pull/37185)
|
||||
- ⚠️ Changed environment variable configuration for Storage (requires `docker-compose.yml`, `.env.example` and `.env` update) - PR [#37185](https://github.com/supabase/supabase/pull/37185), PR [#42862](https://github.com/supabase/supabase/pull/42862)
|
||||
|
||||
### Edge Runtime
|
||||
|
||||
- Updated to `v1.70.3` - [Release](https://github.com/supabase/edge-runtime/releases/tag/v1.70.3)
|
||||
|
||||
### Analytics (Logflare)
|
||||
|
||||
- Updated to `v1.31.2` - [Release](https://github.com/Logflare/logflare/releases/tag/v1.31.2)
|
||||
- ⚠️ Changed default configuration to disable Logflare on `0.0.0.0:4000` to prevent access to `/dashboard` (requires `docker-compose.yml` update). Read more in "Production Recommendations" section of Logflare [documentation](https://supabase.com/docs/reference/self-hosting-analytics/introduction) - PR [#42857](https://github.com/supabase/supabase/pull/42857)
|
||||
- ⚠️ Changed Kong routes to not include `/analytics/v1` by default (requires `/volumes/api/kong.yml` update) - PR [#42857](https://github.com/supabase/supabase/pull/42857)
|
||||
|
||||
### Vector
|
||||
|
||||
- Updated to `0.53.0-alpine` - [Changelog](https://vector.dev/releases/0.53.0/) | [Release](https://github.com/vectordotdev/vector/releases/tag/v0.53.0)
|
||||
- ⚠️ Major version jump from `0.28.1` (requires `volumes/logs/vector.yml` update) - PR [#42525](https://github.com/supabase/supabase/pull/42525)
|
||||
- ⚠️ Changed Postgres sink configuration to bypass Kong (requires `volumes/logs/vector.yml` update) - PR [#42857](https://github.com/supabase/supabase/pull/42857)
|
||||
- ⚠️ Changed retry settings for all sinks to increase timeouts (requires `volumes/logs/vector.yml` update) - PR [#42857](https://github.com/supabase/supabase/pull/42857)
|
||||
|
||||
---
|
||||
|
||||
## [2026-02-05]
|
||||
|
||||
### Storage
|
||||
- Updated to `v1.37.1` - [Release](https://github.com/supabase/storage/releases/tag/v1.37.1)
|
||||
- Fixed an issue with Storage not starting because of an issue with migrations - PR [storage#845](https://github.com/supabase/storage/pull/845)
|
||||
|
||||
---
|
||||
|
||||
## [2026-01-27]
|
||||
|
||||
### Studio
|
||||
- Updated to `2026.01.27-sha-6aa59ff`
|
||||
- Added SQL snippets (requires `docker-compose.yml` update) - PR [#41112](https://github.com/supabase/supabase/pull/41112), PR [#41557](https://github.com/supabase/supabase/pull/41557)
|
||||
- Fixed type generator - PR [#40481](https://github.com/supabase/supabase/pull/40481)
|
||||
- Fixed minor UI discrepancies - PR [#40579](https://github.com/supabase/supabase/pull/40579), PR [#41936](https://github.com/supabase/supabase/pull/41936), PR [#41970](https://github.com/supabase/supabase/pull/41970), PR [#41971](https://github.com/supabase/supabase/pull/41971), PR [#41972](https://github.com/supabase/supabase/pull/41972), PR [#42015](https://github.com/supabase/supabase/pull/42015)
|
||||
|
||||
### Auth
|
||||
- Updated to `v2.185.0` - [Changelog](https://github.com/supabase/auth/blob/master/CHANGELOG.md) | [Release](https://github.com/supabase/auth/releases/tag/v2.185.0)
|
||||
- ⚠️ Fixed security related issues
|
||||
|
||||
### PostgREST
|
||||
- Updated to `v14.3` - [Changelog](https://github.com/PostgREST/postgrest/blob/main/CHANGELOG.md) | [Release](https://github.com/PostgREST/postgrest/releases/tag/v14.3)
|
||||
|
||||
### Realtime
|
||||
- Updated to `v2.72.0` - [Release](https://github.com/supabase/realtime/releases/tag/v2.72.0)
|
||||
- Changed healthchecks logging to off by default (requires `docker-compose.yml` update) - PR [realtime#1677](https://github.com/supabase/realtime/pull/1677), PR [#42156](https://github.com/supabase/supabase/pull/42156)
|
||||
- Changed logging configuration and healthcheck frequency to reduce log volume (requires `docker-compose.yml` update) - PR [#42112](https://github.com/supabase/supabase/pull/42112)
|
||||
|
||||
### Storage
|
||||
- Updated to `v1.33.5` - [Release](https://github.com/supabase/storage/releases/tag/v1.33.5)
|
||||
|
||||
### imgproxy
|
||||
- Updated to `v3.30.1` - [Changelog](https://github.com/imgproxy/imgproxy/blob/master/CHANGELOG.md) | [Release](https://github.com/imgproxy/imgproxy/releases/tag/v3.30.1)
|
||||
|
||||
### Postgres Meta
|
||||
- Updated to `v0.95.2` - [Release](https://github.com/supabase/postgres-meta/releases/tag/v0.95.2)
|
||||
|
||||
### Edge Runtime
|
||||
- Updated to `v1.70.0` - [Release](https://github.com/supabase/edge-runtime/releases/tag/v1.70.0)
|
||||
|
||||
### Analytics (Logflare)
|
||||
- Updated to `v1.30.3` - [Release](https://github.com/Logflare/logflare/releases/tag/v1.30.3)
|
||||
|
||||
### Postgres
|
||||
- No image update
|
||||
- Fixed Postgres logging configuration (requires `volumes/logs/vector.yml` update) - PR [#41800](https://github.com/supabase/supabase/pull/41800)
|
||||
|
||||
---
|
||||
|
||||
## [2025-12-18]
|
||||
|
||||
### Documentation
|
||||
- Updated self-hosting installation and configuration guide - PR [#40901](https://github.com/supabase/supabase/pull/40901), PR [#41438](https://github.com/supabase/supabase/pull/41438)
|
||||
|
||||
### Utils
|
||||
- Added `generate-keys.sh` - PR [#41363](https://github.com/supabase/supabase/pull/41363)
|
||||
- Added `db-passwd.sh` - PR [#41432](https://github.com/supabase/supabase/pull/41432)
|
||||
- Changed `reset.sh` to POSIX and added more checks - PR [#41361](https://github.com/supabase/supabase/pull/41361)
|
||||
|
||||
### Studio
|
||||
- Updated to `2025.12.17-sha-43f4f7f`
|
||||
- ⚠️ Fixed additional issues related to [React2Shell](https://vercel.com/kb/bulletin/react2shell)
|
||||
- Fixed an issue with the Users page not being updated on changes - PR [#41254](https://github.com/supabase/supabase/pull/41254)
|
||||
|
||||
### MCP Server
|
||||
- Updated to `v0.5.10` - [Release](https://github.com/supabase-community/supabase-mcp/releases/tag/v0.5.10)
|
||||
|
||||
### Auth
|
||||
- Updated to `v2.184.0` - [Changelog](https://github.com/supabase/auth/blob/master/CHANGELOG.md) | [Release](https://github.com/supabase/auth/releases/tag/v2.184.0)
|
||||
|
||||
### Postgres Meta
|
||||
- Updated to `v0.95.1` - [Release](https://github.com/supabase/postgres-meta/releases/tag/v0.95.1)
|
||||
|
||||
### Analytics (Logflare)
|
||||
- Updated to `v1.27.0` - [Release](https://github.com/Logflare/logflare/releases/tag/v1.27.0)
|
||||
- Fixed multiple issues, including a race condition
|
||||
|
||||
---
|
||||
|
||||
## [2025-12-10]
|
||||
|
||||
### Studio
|
||||
|
||||
- Updated to `2025.12.09-sha-434634f`
|
||||
- ⚠️ Fixed security issues related to [React2Shell](https://vercel.com/kb/bulletin/react2shell)
|
||||
|
||||
### MCP Server
|
||||
|
||||
- Updated to `v0.5.9` - [Release](https://github.com/supabase-community/supabase-mcp/releases/tag/v0.5.9)
|
||||
- ⚠️ Changed MCP tool `get_anon_key` to `get_publishable_keys`
|
||||
|
||||
### PostgREST
|
||||
|
||||
- Updated to `v14.1` - [Changelog](https://github.com/PostgREST/postgrest/blob/main/CHANGELOG.md) | [Release](https://github.com/PostgREST/postgrest/releases/tag/v14.1)
|
||||
- ⚠️ **Major upgrade from v13.x to v14.x** - please report any unexpected behavior
|
||||
|
||||
### Realtime
|
||||
|
||||
- Updated to `v2.68.0` - [Releases](https://github.com/supabase/realtime/releases/tag/v2.68.0)
|
||||
|
||||
### Storage
|
||||
|
||||
- Updated to `v1.33.0` - [Release](https://github.com/supabase/storage/releases/tag/v1.33.0)
|
||||
|
||||
### Edge Runtime
|
||||
|
||||
- Updated to `v1.69.28` - [Release](https://github.com/supabase/edge-runtime/releases/tag/v1.69.28)
|
||||
|
||||
### Analytics (Logflare)
|
||||
|
||||
- Updated to `v1.26.25` - [Release](https://github.com/Logflare/logflare/releases/tag/v1.26.25)
|
||||
|
||||
---
|
||||
|
||||
## [2025-12-08]
|
||||
|
||||
### Realtime
|
||||
- No image update
|
||||
- Changed boolean values to strings in Docker Compose for better compatibility with Podman - PR [#40994](https://github.com/supabase/supabase/pull/40994), also PR [realtime#1614](https://github.com/supabase/realtime/pull/1614)
|
||||
- Changed healthcheck in Docker Compose for better compatibility with Podman - PR [#41159](https://github.com/supabase/supabase/pull/41159)
|
||||
|
||||
---
|
||||
|
||||
## [2025-11-26]
|
||||
|
||||
### Studio
|
||||
- Updated to `2025.11.26-sha-8f096b5`
|
||||
- Fixed MCP `get_advisors` tool - PR [#40783](https://github.com/supabase/supabase/pull/40783)
|
||||
- Fixed AI Assistant request schema - PR [#40830](https://github.com/supabase/supabase/pull/40830)
|
||||
- Fixed log drains page - PR [#40835](https://github.com/supabase/supabase/pull/40835)
|
||||
|
||||
### Realtime
|
||||
- Updated to `v2.65.3` - [Release](https://github.com/supabase/realtime/releases/tag/v2.65.3)
|
||||
|
||||
### Analytics (Logflare)
|
||||
- Updated to `v1.26.13` - [Release](https://github.com/Logflare/logflare/releases/tag/v1.26.13)
|
||||
- Fixed crashdump when `POSTGRES_BACKEND_URL` is malformed - PR [logflare#2954](https://github.com/Logflare/logflare/pull/2954)
|
||||
|
||||
---
|
||||
|
||||
## [2025-11-25]
|
||||
|
||||
### Studio
|
||||
- Updated to `2025.11.24-sha-d990ae8` - [Dashboard updates](https://github.com/orgs/supabase/discussions/40734)
|
||||
- Fixed Queues configuration UI and added [documentation for exposed queue schema](https://supabase.com/docs/guides/queues/expose-self-hosted-queues) - PR [#40078](https://github.com/supabase/supabase/pull/40078)
|
||||
- Fixed parameterized SQL queries in MCP tools - PR [#40499](https://github.com/supabase/supabase/pull/40499)
|
||||
- Fixed Studio showing paid options for log drains - PR [#40510](https://github.com/supabase/supabase/pull/40510)
|
||||
- Fixed AI Assistant authentication - PR [#40654](https://github.com/supabase/supabase/pull/40654)
|
||||
|
||||
### Auth
|
||||
- Updated to `v2.183.0` - [Changelog](https://github.com/supabase/auth/blob/master/CHANGELOG.md) | [Release](https://github.com/supabase/auth/releases/tag/v2.183.0)
|
||||
|
||||
### Realtime
|
||||
- Updated to `v2.65.2` - [Release](https://github.com/supabase/realtime/releases/tag/v2.65.2)
|
||||
- Fixed handling of boolean configurations options - PR [realtime#1614](https://github.com/supabase/realtime/pull/1614)
|
||||
|
||||
### Storage
|
||||
- Updated to `v1.32.0` - [Release](https://github.com/supabase/storage/releases/tag/v1.32.0)
|
||||
|
||||
### Edge Runtime
|
||||
- Updated to `v1.69.25` - [Release](https://github.com/supabase/edge-runtime/releases/tag/v1.69.25)
|
||||
|
||||
### Analytics (Logflare)
|
||||
- Updated to `v1.26.12` - [Release](https://github.com/Logflare/logflare/releases/tag/v1.26.12)
|
||||
- Fixed Auth logs query - PR [logflare#2936](https://github.com/Logflare/logflare/pull/2936)
|
||||
- Fixed build configuration to prevent crashes with "Illegal instruction (core dumped)" - PR [logflare#2942](https://github.com/Logflare/logflare/pull/2942)
|
||||
|
||||
---
|
||||
|
||||
## [2025-11-17]
|
||||
|
||||
### Storage
|
||||
- No image update
|
||||
- Fixed resumable uploads for files larger than 6MB (requires `docker-compose.yml` update) - PR [#40500](https://github.com/supabase/supabase/pull/40500)
|
||||
|
||||
---
|
||||
|
||||
## [2025-11-12]
|
||||
|
||||
### Studio
|
||||
- Updated to `2025.11.10-sha-5291fe3` - [Dashboard updates](https://github.com/orgs/supabase/discussions/40083)
|
||||
- Added log drains - PR [#28297](https://github.com/supabase/supabase/pull/28297)
|
||||
- Fixed Studio using `postgres` role instead of `supabase_admin` - PR [#39946](https://github.com/supabase/supabase/pull/39946)
|
||||
|
||||
### Auth
|
||||
- Updated to `v2.182.1` - [Changelog](https://github.com/supabase/auth/blob/master/CHANGELOG.md#21821-2025-11-05) | [Release](https://github.com/supabase/auth/releases/tag/v2.182.1)
|
||||
|
||||
### Realtime
|
||||
- Updated to `v2.63.0` - [Release](https://github.com/supabase/realtime/releases/tag/v2.63.0)
|
||||
|
||||
### Storage
|
||||
- Updated to `v1.29.0` - [Release](https://github.com/supabase/storage/releases/tag/v1.29.0)
|
||||
|
||||
### Edge Runtime
|
||||
- Updated to `v1.69.23` - [Release](https://github.com/supabase/edge-runtime/releases/tag/v1.69.23)
|
||||
|
||||
### Supavisor
|
||||
- Updated to `v2.7.4` - [Release](https://github.com/supabase/supavisor/releases/tag/v2.7.4)
|
||||
|
||||
---
|
||||
|
||||
## [2025-11-05]
|
||||
|
||||
### Studio
|
||||
- No image update
|
||||
- Fixed Studio failing to connect to Postgres with non-default settings (requires `docker-compose.yml` update) - PR [#40169](https://github.com/supabase/supabase/pull/40169)
|
||||
|
||||
### Realtime
|
||||
- No image update
|
||||
- Fixed realtime logs not showing in Studio (requires `volumes/logs/vector.yml` update) - PR [#39963](https://github.com/supabase/supabase/pull/39963)
|
||||
|
||||
---
|
||||
|
||||
## [2025-10-28]
|
||||
|
||||
### Studio
|
||||
- Updated to `2025.10.27-sha-85b84e0` - [Dashboard updates](https://github.com/orgs/supabase/discussions/40083)
|
||||
- Fixed broken authentication when uploading files to Storage - PR [#39829](https://github.com/supabase/supabase/pull/39829)
|
||||
|
||||
### Realtime
|
||||
- Updated to `v2.57.2` - [Release](https://github.com/supabase/realtime/releases/tag/v2.57.2)
|
||||
|
||||
### Storage
|
||||
- Updated to `v1.28.2` - [Release](https://github.com/supabase/storage/releases/tag/v1.28.2)
|
||||
|
||||
### Postgres Meta
|
||||
- Updated to `v0.93.1` - [Release](https://github.com/supabase/postgres-meta/releases/tag/v0.93.1)
|
||||
|
||||
### Edge Runtime
|
||||
- Updated to `v1.69.15` - [Release](https://github.com/supabase/edge-runtime/releases/tag/v1.69.15)
|
||||
|
||||
---
|
||||
|
||||
## [2025-10-27]
|
||||
|
||||
### Studio
|
||||
- No image update
|
||||
- Added Kong configuration for MCP server routes (requires `volumes/api/kong.yml` update) - PR [#39849](https://github.com/supabase/supabase/pull/39849)
|
||||
- Added [documentation page](https://supabase.com/docs/guides/self-hosting/enable-mcp) for MCP server configuration - PR [#39952](https://github.com/supabase/supabase/pull/39952)
|
||||
|
||||
---
|
||||
|
||||
## [2025-10-21]
|
||||
|
||||
### Studio
|
||||
- Updated to `2025.10.20-sha-5005fc6` - [Dashboard updates](https://github.com/orgs/supabase/discussions/39709)
|
||||
- Fixed issues with Edge Functions and cron logs not being visible in Studio - PR [#39388](https://github.com/supabase/supabase/pull/39388), PR [#39704](https://github.com/supabase/supabase/pull/39704), PR [#39711](https://github.com/supabase/supabase/pull/39711)
|
||||
|
||||
### Realtime
|
||||
- Updated to `v2.56.0` - [Release](https://github.com/supabase/realtime/releases/tag/v2.56.0)
|
||||
|
||||
### Storage
|
||||
- Updated to `v1.28.1` - [Release](https://github.com/supabase/storage/releases/tag/v1.28.1)
|
||||
|
||||
### Postgres Meta
|
||||
- Updated to `v0.93.0` - [Release](https://github.com/supabase/postgres-meta/releases/tag/v0.93.0)
|
||||
|
||||
### Edge Runtime
|
||||
- Updated to `v1.69.14` - [Release](https://github.com/supabase/edge-runtime/releases/tag/v1.69.14)
|
||||
|
||||
### Supavisor
|
||||
- Updated to `v2.7.3` - [Release](https://github.com/supabase/supavisor/releases/tag/v2.7.3)
|
||||
|
||||
---
|
||||
|
||||
## [2025-10-13]
|
||||
|
||||
### Analytics (Logflare)
|
||||
- Updated to `v1.22.6` - [Release](https://github.com/Logflare/logflare/releases/tag/v1.22.6)
|
||||
|
||||
---
|
||||
|
||||
## [2025-10-08]
|
||||
|
||||
### Studio
|
||||
- Updated to `2025.10.01-sha-8460121` - [Dashboard updates](https://github.com/orgs/supabase/discussions/39709)
|
||||
- Added "local" remote MCP server - PR [#38797](https://github.com/supabase/supabase/pull/38797), PR [#39041](https://github.com/supabase/supabase/pull/39041)
|
||||
- ⚠️ Changed Studio connection method to `postgres-meta` - affects non-standard database port configurations
|
||||
|
||||
### Auth
|
||||
- Updated to `v2.180.0` - [Release](https://github.com/supabase/auth/releases/tag/v2.180.0)
|
||||
|
||||
### PostgREST
|
||||
- Updated to `v13.0.7` - [Release](https://github.com/PostgREST/postgrest/releases/tag/v13.0.7) | [Changelog](https://github.com/PostgREST/postgrest/blob/main/CHANGELOG.md)
|
||||
|
||||
### Realtime
|
||||
- Updated to `v2.51.11` - [Release](https://github.com/supabase/realtime/releases/tag/v2.51.11)
|
||||
|
||||
### Storage
|
||||
- Updated to `v1.28.0` - [Release](https://github.com/supabase/storage/releases/tag/v1.28.0)
|
||||
|
||||
### Postgres Meta
|
||||
- Updated to `v0.91.6` - [Release](https://github.com/supabase/postgres-meta/releases/tag/v0.91.6)
|
||||
|
||||
### Analytics (Logflare)
|
||||
- Updated to `v1.22.4` - [Release](https://github.com/Logflare/logflare/releases/tag/v1.22.4)
|
||||
|
||||
### Postgres
|
||||
- Updated to `15.8.1.085` - [Release](https://github.com/supabase/postgres/releases/tag/15.8.1.085)
|
||||
|
||||
### Supavisor
|
||||
- Updated to `2.7.0` - [Release](https://github.com/supabase/supavisor/releases/tag/v2.7.0)
|
||||
|
||||
---
|
||||
+86
-2
@@ -1,3 +1,87 @@
|
||||
# Supabase Docker
|
||||
# Self-Hosted Supabase with Docker
|
||||
|
||||
This is a minimal Docker Compose setup for self-hosting Supabase. Follow the steps [here](https://supabase.com/docs/guides/hosting/docker) to get started.
|
||||
This is the official Docker Compose setup for self-hosted Supabase. It provides a complete stack with all Supabase services running locally or on your infrastructure.
|
||||
|
||||
## Getting Started
|
||||
|
||||
Follow the detailed setup guide in our documentation: [Self-Hosting with Docker](https://supabase.com/docs/guides/self-hosting/docker)
|
||||
|
||||
The guide covers:
|
||||
- Prerequisites (Git and Docker)
|
||||
- Initial setup and configuration
|
||||
- Securing your installation
|
||||
- Accessing services
|
||||
- Updating your instance
|
||||
|
||||
## What's Included
|
||||
|
||||
This Docker Compose configuration includes the following services:
|
||||
|
||||
- **[Studio](https://github.com/supabase/supabase/tree/master/apps/studio)** - A dashboard for managing your self-hosted Supabase project
|
||||
- **[Kong](https://github.com/Kong/kong)** - Kong API gateway
|
||||
- **[Auth](https://github.com/supabase/auth)** - JWT-based authentication API for user sign-ups, logins, and session management
|
||||
- **[PostgREST](https://github.com/PostgREST/postgrest)** - Web server that turns your PostgreSQL database directly into a RESTful API
|
||||
- **[Realtime](https://github.com/supabase/realtime)** - Elixir server that listens to PostgreSQL database changes and broadcasts them over websockets
|
||||
- **[Storage](https://github.com/supabase/storage)** - RESTful API for managing files in S3, with Postgres handling permissions
|
||||
- **[imgproxy](https://github.com/imgproxy/imgproxy)** - Fast and secure image processing server
|
||||
- **[postgres-meta](https://github.com/supabase/postgres-meta)** - RESTful API for managing Postgres (fetch tables, add roles, run queries)
|
||||
- **[PostgreSQL](https://github.com/supabase/postgres)** - Object-relational database with over 30 years of active development
|
||||
- **[Edge Runtime](https://github.com/supabase/edge-runtime)** - Web server based on Deno runtime for running JavaScript, TypeScript, and WASM services
|
||||
- **[Logflare](https://github.com/Logflare/logflare)** - Log management and event analytics platform
|
||||
- **[Vector](https://github.com/vectordotdev/vector)** - High-performance observability data pipeline for logs
|
||||
- **[Supavisor](https://github.com/supabase/supavisor)** - Supabase's Postgres connection pooler
|
||||
|
||||
## Documentation
|
||||
|
||||
- **[Documentation](https://supabase.com/docs/guides/self-hosting/docker)** - Setup and configuration guides
|
||||
- **[CHANGELOG.md](./CHANGELOG.md)** - Track recent updates and changes to services
|
||||
- **[versions.md](./versions.md)** - Complete history of Docker image versions for rollback reference
|
||||
|
||||
## Updates
|
||||
|
||||
To update your self-hosted Supabase instance:
|
||||
|
||||
1. Review [CHANGELOG.md](./CHANGELOG.md) for breaking changes
|
||||
2. Check [versions.md](./versions.md) for new image versions
|
||||
3. Update `docker-compose.yml` if there are configuration changes
|
||||
4. Pull the latest images: `docker compose pull`
|
||||
5. Stop services: `docker compose down`
|
||||
6. Start services with new configuration: `docker compose up -d`
|
||||
|
||||
**Note:** Consider to always backup your database before updating.
|
||||
|
||||
## Community & Support
|
||||
|
||||
For troubleshooting common issues, see:
|
||||
- [GitHub Discussions](https://github.com/orgs/supabase/discussions?discussions_q=is%3Aopen+label%3Aself-hosted) - Questions, feature requests, and workarounds
|
||||
- [GitHub Issues](https://github.com/supabase/supabase/issues?q=is%3Aissue%20state%3Aopen%20label%3Aself-hosted) - Known issues
|
||||
- [Documentation](https://supabase.com/docs/guides/self-hosting) - Setup and configuration guides
|
||||
|
||||
Self-hosted Supabase is community-supported. Get help and connect with other users:
|
||||
|
||||
- [Discord](https://discord.supabase.com) - Real-time chat and community support
|
||||
- [Reddit](https://www.reddit.com/r/Supabase/) - Official Supabase subreddit
|
||||
|
||||
Share your self-hosting experience:
|
||||
|
||||
- [GitHub Discussions](https://github.com/orgs/supabase/discussions/39820) - "Self-hosting: What's working (and what's not)?"
|
||||
|
||||
## Important Notes
|
||||
|
||||
### Security
|
||||
|
||||
⚠️ **The default configuration is not secure for production use.**
|
||||
|
||||
Before deploying to production, you must:
|
||||
- Update all default passwords and secrets in the `.env` file
|
||||
- Generate new JWT secrets
|
||||
- Review and update CORS settings
|
||||
- Consider setting up a secure proxy in front of self-hosted Supabase
|
||||
- Review and adjust network security configuration (ACLs, etc.)
|
||||
- Set up proper backup procedures
|
||||
|
||||
See the [security section](https://supabase.com/docs/guides/self-hosting/docker#configuring-and-securing-supabase) in the documentation.
|
||||
|
||||
## License
|
||||
|
||||
This repository is licensed under the Apache 2.0 License. See the main [Supabase repository](https://github.com/supabase/supabase) for details.
|
||||
|
||||
@@ -8,6 +8,16 @@ services:
|
||||
target: dev
|
||||
ports:
|
||||
- 8082:8082
|
||||
develop:
|
||||
watch:
|
||||
- action: sync
|
||||
path: ../apps/studio
|
||||
target: /app/apps/studio
|
||||
ignore:
|
||||
- node_modules/
|
||||
- action: rebuild
|
||||
path: package.json
|
||||
|
||||
mail:
|
||||
container_name: supabase-mail
|
||||
image: inbucket/inbucket:3.0.3
|
||||
|
||||
@@ -0,0 +1,34 @@
|
||||
services:
|
||||
|
||||
kong:
|
||||
ports: !reset []
|
||||
|
||||
caddy:
|
||||
container_name: supabase-caddy
|
||||
image: caddy:2
|
||||
restart: unless-stopped
|
||||
ports:
|
||||
- "80:80"
|
||||
- "443:443"
|
||||
- "443:443/udp"
|
||||
depends_on:
|
||||
kong:
|
||||
condition: service_healthy
|
||||
environment:
|
||||
PROXY_DOMAIN: ${PROXY_DOMAIN}
|
||||
PROXY_AUTH_USERNAME: ${DASHBOARD_USERNAME}
|
||||
PROXY_AUTH_PASSWORD: ${DASHBOARD_PASSWORD}
|
||||
command:
|
||||
- /bin/sh
|
||||
- -c
|
||||
- |
|
||||
PROXY_AUTH_PASSWORD=$$(caddy hash-password --plaintext "$$PROXY_AUTH_PASSWORD") && \
|
||||
caddy run --config /etc/caddy/Caddyfile --adapter caddyfile
|
||||
volumes:
|
||||
- ./volumes/proxy/caddy:/etc/caddy
|
||||
- caddy_data:/data
|
||||
- caddy_config:/config
|
||||
|
||||
volumes:
|
||||
caddy_data:
|
||||
caddy_config:
|
||||
@@ -0,0 +1,33 @@
|
||||
services:
|
||||
|
||||
kong:
|
||||
ports: !reset []
|
||||
|
||||
nginx:
|
||||
container_name: supabase-nginx
|
||||
image: jonasal/nginx-certbot:6.0.1-nginx1.29.5
|
||||
restart: unless-stopped
|
||||
ports:
|
||||
- "80:80"
|
||||
- "443:443"
|
||||
depends_on:
|
||||
kong:
|
||||
condition: service_healthy
|
||||
environment:
|
||||
PROXY_DOMAIN: ${PROXY_DOMAIN}
|
||||
CERTBOT_EMAIL: ${CERTBOT_EMAIL}
|
||||
PROXY_AUTH_USERNAME: ${DASHBOARD_USERNAME}
|
||||
PROXY_AUTH_PASSWORD: ${DASHBOARD_PASSWORD}
|
||||
command:
|
||||
- /bin/bash
|
||||
- -c
|
||||
- |
|
||||
printf '%s:%s\n' "$${PROXY_AUTH_USERNAME}" "$$(openssl passwd -apr1 "$${PROXY_AUTH_PASSWORD}")" > /etc/nginx/user_conf.d/dashboard-passwd && \
|
||||
envsubst '$${PROXY_DOMAIN}' < /etc/nginx/supabase-nginx.conf.tpl > /etc/nginx/user_conf.d/nginx.conf && \
|
||||
/scripts/start_nginx_certbot.sh
|
||||
volumes:
|
||||
- ./volumes/proxy/nginx/supabase-nginx.conf.tpl:/etc/nginx/supabase-nginx.conf.tpl:ro
|
||||
- nginx_letsencrypt:/etc/letsencrypt
|
||||
|
||||
volumes:
|
||||
nginx_letsencrypt:
|
||||
@@ -1,16 +1,16 @@
|
||||
services:
|
||||
|
||||
minio:
|
||||
image: minio/minio
|
||||
ports:
|
||||
- '9000:9000'
|
||||
- '9001:9001'
|
||||
image: cgr.dev/chainguard/minio
|
||||
#ports:
|
||||
# - '9000:9000'
|
||||
# - '9001:9001'
|
||||
environment:
|
||||
MINIO_ROOT_USER: supa-storage
|
||||
MINIO_ROOT_PASSWORD: secret1234
|
||||
MINIO_ROOT_USER: ${MINIO_ROOT_USER}
|
||||
MINIO_ROOT_PASSWORD: ${MINIO_ROOT_PASSWORD}
|
||||
command: server --console-address ":9001" /data
|
||||
healthcheck:
|
||||
test: [ "CMD", "curl", "-f", "http://minio:9000/minio/health/live" ]
|
||||
test: [ "CMD", "mc", "ready", "local" ]
|
||||
interval: 2s
|
||||
timeout: 10s
|
||||
retries: 5
|
||||
@@ -18,20 +18,20 @@ services:
|
||||
- ./volumes/storage:/data:z
|
||||
|
||||
minio-createbucket:
|
||||
image: minio/mc
|
||||
image: cgr.dev/chainguard/minio-client:latest-dev
|
||||
depends_on:
|
||||
minio:
|
||||
condition: service_healthy
|
||||
entrypoint: >
|
||||
/bin/sh -c "
|
||||
/usr/bin/mc alias set supa-minio http://minio:9000 supa-storage secret1234;
|
||||
/usr/bin/mc mb supa-minio/stub;
|
||||
exit 0;
|
||||
/bin/sh -ec "
|
||||
mc alias set supa-minio http://minio:9000 ${MINIO_ROOT_USER} ${MINIO_ROOT_PASSWORD} &&
|
||||
mc mb --ignore-existing supa-minio/${GLOBAL_S3_BUCKET}
|
||||
"
|
||||
|
||||
storage:
|
||||
container_name: supabase-storage
|
||||
image: supabase/storage-api:v1.11.13
|
||||
image: supabase/storage-api:v1.37.8
|
||||
restart: unless-stopped
|
||||
depends_on:
|
||||
db:
|
||||
# Disable this if you are using an external Postgres database
|
||||
@@ -40,6 +40,8 @@ services:
|
||||
condition: service_started
|
||||
imgproxy:
|
||||
condition: service_started
|
||||
minio-createbucket:
|
||||
condition: service_completed_successfully
|
||||
minio:
|
||||
condition: service_healthy
|
||||
healthcheck:
|
||||
@@ -50,45 +52,36 @@ services:
|
||||
"--no-verbose",
|
||||
"--tries=1",
|
||||
"--spider",
|
||||
"http://localhost:5000/status"
|
||||
"http://storage:5000/status"
|
||||
]
|
||||
timeout: 5s
|
||||
interval: 5s
|
||||
retries: 3
|
||||
restart: unless-stopped
|
||||
environment:
|
||||
ANON_KEY: ${ANON_KEY}
|
||||
SERVICE_KEY: ${SERVICE_ROLE_KEY}
|
||||
POSTGREST_URL: http://rest:3000
|
||||
PGRST_JWT_SECRET: ${JWT_SECRET}
|
||||
DATABASE_URL: postgres://supabase_storage_admin:${POSTGRES_PASSWORD}@${POSTGRES_HOST}:${POSTGRES_PORT}/${POSTGRES_DB}
|
||||
REQUEST_ALLOW_X_FORWARDED_PATH: "true"
|
||||
FILE_SIZE_LIMIT: 52428800
|
||||
STORAGE_BACKEND: s3
|
||||
GLOBAL_S3_BUCKET: stub
|
||||
# S3 bucket when using S3 backend, directory name when using 'file'
|
||||
GLOBAL_S3_BUCKET: ${GLOBAL_S3_BUCKET}
|
||||
# S3 Backend configuration
|
||||
GLOBAL_S3_ENDPOINT: http://minio:9000
|
||||
GLOBAL_S3_PROTOCOL: http
|
||||
GLOBAL_S3_FORCE_PATH_STYLE: true
|
||||
AWS_ACCESS_KEY_ID: supa-storage
|
||||
AWS_SECRET_ACCESS_KEY: secret1234
|
||||
AWS_DEFAULT_REGION: stub
|
||||
FILE_STORAGE_BACKEND_PATH: /var/lib/storage
|
||||
TENANT_ID: stub
|
||||
AWS_ACCESS_KEY_ID: ${MINIO_ROOT_USER}
|
||||
AWS_SECRET_ACCESS_KEY: ${MINIO_ROOT_PASSWORD}
|
||||
#FILE_STORAGE_BACKEND_PATH: /var/lib/storage
|
||||
TENANT_ID: ${STORAGE_TENANT_ID}
|
||||
# TODO: https://github.com/supabase/storage-api/issues/55
|
||||
REGION: stub
|
||||
REGION: ${REGION}
|
||||
ENABLE_IMAGE_TRANSFORMATION: "true"
|
||||
IMGPROXY_URL: http://imgproxy:5001
|
||||
volumes:
|
||||
- ./volumes/storage:/var/lib/storage:z
|
||||
|
||||
imgproxy:
|
||||
container_name: supabase-imgproxy
|
||||
image: darthsim/imgproxy:v3.8.0
|
||||
healthcheck:
|
||||
test: [ "CMD", "imgproxy", "health" ]
|
||||
timeout: 5s
|
||||
interval: 5s
|
||||
retries: 3
|
||||
environment:
|
||||
IMGPROXY_BIND: ":5001"
|
||||
IMGPROXY_USE_ETAG: "true"
|
||||
IMGPROXY_ENABLE_WEBP_DETECTION: ${IMGPROXY_ENABLE_WEBP_DETECTION}
|
||||
# S3 protocol endpoint configuration
|
||||
S3_PROTOCOL_ACCESS_KEY_ID: ${S3_PROTOCOL_ACCESS_KEY_ID}
|
||||
S3_PROTOCOL_ACCESS_KEY_SECRET: ${S3_PROTOCOL_ACCESS_KEY_SECRET}
|
||||
#volumes:
|
||||
# - ./volumes/storage:/var/lib/storage:z
|
||||
|
||||
@@ -10,7 +10,7 @@ name: supabase
|
||||
services:
|
||||
|
||||
studio:
|
||||
image: supabase/studio:2025.06.30-sha-6f5982d
|
||||
image: supabase/studio:2026.02.16-sha-26c615c
|
||||
restart: unless-stopped
|
||||
healthcheck:
|
||||
test:
|
||||
@@ -28,8 +28,15 @@ services:
|
||||
analytics:
|
||||
condition: service_healthy
|
||||
environment:
|
||||
# Binds nestjs listener to both IPv4 and IPv6 network interfaces
|
||||
HOSTNAME: "::"
|
||||
|
||||
STUDIO_PG_META_URL: http://meta:8080
|
||||
POSTGRES_PORT: ${POSTGRES_PORT}
|
||||
POSTGRES_HOST: ${POSTGRES_HOST}
|
||||
POSTGRES_DB: ${POSTGRES_DB}
|
||||
POSTGRES_PASSWORD: ${POSTGRES_PASSWORD}
|
||||
PG_META_CRYPTO_KEY: ${PG_META_CRYPTO_KEY}
|
||||
|
||||
DEFAULT_ORGANIZATION_NAME: ${STUDIO_DEFAULT_ORGANIZATION}
|
||||
DEFAULT_PROJECT_NAME: ${STUDIO_DEFAULT_PROJECT}
|
||||
@@ -41,13 +48,22 @@ services:
|
||||
SUPABASE_SERVICE_KEY: ${SERVICE_ROLE_KEY}
|
||||
AUTH_JWT_SECRET: ${JWT_SECRET}
|
||||
|
||||
# LOGFLARE_API_KEY is deprecated
|
||||
LOGFLARE_API_KEY: ${LOGFLARE_PUBLIC_ACCESS_TOKEN}
|
||||
LOGFLARE_PUBLIC_ACCESS_TOKEN: ${LOGFLARE_PUBLIC_ACCESS_TOKEN}
|
||||
LOGFLARE_PRIVATE_ACCESS_TOKEN: ${LOGFLARE_PRIVATE_ACCESS_TOKEN}
|
||||
|
||||
LOGFLARE_URL: http://analytics:4000
|
||||
NEXT_PUBLIC_ENABLE_LOGS: true
|
||||
# Comment to use Big Query backend for analytics
|
||||
NEXT_ANALYTICS_BACKEND_PROVIDER: postgres
|
||||
# Uncomment to use Big Query backend for analytics
|
||||
# NEXT_ANALYTICS_BACKEND_PROVIDER: bigquery
|
||||
SNIPPETS_MANAGEMENT_FOLDER: /app/snippets
|
||||
EDGE_FUNCTIONS_MANAGEMENT_FOLDER: /app/edge-functions
|
||||
volumes:
|
||||
- ./volumes/snippets:/app/snippets:Z
|
||||
- ./volumes/functions:/app/edge-functions:Z
|
||||
|
||||
kong:
|
||||
image: kong:2.8.1
|
||||
@@ -55,6 +71,8 @@ services:
|
||||
volumes:
|
||||
# https://github.com/supabase/supabase/issues/12661
|
||||
- ./volumes/api/kong.yml:/home/kong/temp.yml:ro,z
|
||||
#- ./volumes/api/server.crt:/home/kong/server.crt:ro
|
||||
#- ./volumes/api/server.key:/home/kong/server.key:ro
|
||||
depends_on:
|
||||
analytics:
|
||||
condition: service_healthy
|
||||
@@ -63,9 +81,11 @@ services:
|
||||
KONG_DECLARATIVE_CONFIG: /home/kong/kong.yml
|
||||
# https://github.com/supabase/cli/issues/14
|
||||
KONG_DNS_ORDER: LAST,A,CNAME
|
||||
KONG_PLUGINS: request-transformer,cors,key-auth,acl,basic-auth
|
||||
KONG_PLUGINS: request-transformer,cors,key-auth,acl,basic-auth,request-termination,ip-restriction
|
||||
KONG_NGINX_PROXY_PROXY_BUFFER_SIZE: 160k
|
||||
KONG_NGINX_PROXY_PROXY_BUFFERS: 64 160k
|
||||
#KONG_SSL_CERT: /home/kong/server.crt
|
||||
#KONG_SSL_CERT_KEY: /home/kong/server.key
|
||||
SUPABASE_ANON_KEY: ${ANON_KEY}
|
||||
SUPABASE_SERVICE_KEY: ${SERVICE_ROLE_KEY}
|
||||
DASHBOARD_USERNAME: ${DASHBOARD_USERNAME}
|
||||
@@ -75,7 +95,7 @@ services:
|
||||
/docker-entrypoint.sh kong docker-start'
|
||||
|
||||
auth:
|
||||
image: supabase/gotrue:v2.177.0
|
||||
image: supabase/gotrue:v2.186.0
|
||||
restart: unless-stopped
|
||||
healthcheck:
|
||||
test:
|
||||
@@ -136,7 +156,47 @@ services:
|
||||
|
||||
GOTRUE_EXTERNAL_PHONE_ENABLED: ${ENABLE_PHONE_SIGNUP}
|
||||
GOTRUE_SMS_AUTOCONFIRM: ${ENABLE_PHONE_AUTOCONFIRM}
|
||||
# Uncomment to enable custom access token hook. Please see: https://supabase.com/docs/guides/auth/auth-hooks for full list of hooks and additional details about custom_access_token_hook
|
||||
# Uncomment to enable OAuth / social login providers.
|
||||
# GOTRUE_EXTERNAL_GOOGLE_ENABLED: ${GOOGLE_ENABLED}
|
||||
# GOTRUE_EXTERNAL_GOOGLE_CLIENT_ID: ${GOOGLE_CLIENT_ID}
|
||||
# GOTRUE_EXTERNAL_GOOGLE_SECRET: ${GOOGLE_SECRET}
|
||||
# GOTRUE_EXTERNAL_GOOGLE_REDIRECT_URI: ${API_EXTERNAL_URL}/auth/v1/callback
|
||||
|
||||
# GOTRUE_EXTERNAL_GITHUB_ENABLED: ${GITHUB_ENABLED}
|
||||
# GOTRUE_EXTERNAL_GITHUB_CLIENT_ID: ${GITHUB_CLIENT_ID}
|
||||
# GOTRUE_EXTERNAL_GITHUB_SECRET: ${GITHUB_SECRET}
|
||||
# GOTRUE_EXTERNAL_GITHUB_REDIRECT_URI: ${API_EXTERNAL_URL}/auth/v1/callback
|
||||
|
||||
# GOTRUE_EXTERNAL_AZURE_ENABLED: ${AZURE_ENABLED}
|
||||
# GOTRUE_EXTERNAL_AZURE_CLIENT_ID: ${AZURE_CLIENT_ID}
|
||||
# GOTRUE_EXTERNAL_AZURE_SECRET: ${AZURE_SECRET}
|
||||
# GOTRUE_EXTERNAL_AZURE_REDIRECT_URI: ${API_EXTERNAL_URL}/auth/v1/callback
|
||||
|
||||
# Uncomment to configure SMS delivery (phone auth and phone MFA).
|
||||
# GOTRUE_SMS_PROVIDER: ${SMS_PROVIDER}
|
||||
# GOTRUE_SMS_OTP_EXP: ${SMS_OTP_EXP}
|
||||
# GOTRUE_SMS_OTP_LENGTH: ${SMS_OTP_LENGTH}
|
||||
# GOTRUE_SMS_MAX_FREQUENCY: ${SMS_MAX_FREQUENCY}
|
||||
# GOTRUE_SMS_TEMPLATE: ${SMS_TEMPLATE}
|
||||
|
||||
# Twilio credentials (when SMS_PROVIDER=twilio)
|
||||
# GOTRUE_SMS_TWILIO_ACCOUNT_SID: ${SMS_TWILIO_ACCOUNT_SID}
|
||||
# GOTRUE_SMS_TWILIO_AUTH_TOKEN: ${SMS_TWILIO_AUTH_TOKEN}
|
||||
# GOTRUE_SMS_TWILIO_MESSAGE_SERVICE_SID: ${SMS_TWILIO_MESSAGE_SERVICE_SID}
|
||||
|
||||
# Test OTP mappings for development
|
||||
# GOTRUE_SMS_TEST_OTP: ${SMS_TEST_OTP}
|
||||
|
||||
# Uncomment to configure multi-factor authentication (MFA).
|
||||
# GOTRUE_MFA_TOTP_ENROLL_ENABLED: ${MFA_TOTP_ENROLL_ENABLED}
|
||||
# GOTRUE_MFA_TOTP_VERIFY_ENABLED: ${MFA_TOTP_VERIFY_ENABLED}
|
||||
# GOTRUE_MFA_PHONE_ENROLL_ENABLED: ${MFA_PHONE_ENROLL_ENABLED}
|
||||
# GOTRUE_MFA_PHONE_VERIFY_ENABLED: ${MFA_PHONE_VERIFY_ENABLED}
|
||||
# GOTRUE_MFA_MAX_ENROLLED_FACTORS: ${MFA_MAX_ENROLLED_FACTORS}
|
||||
|
||||
# Uncomment to enable custom access token hook.
|
||||
# See: https://supabase.com/docs/guides/auth/auth-hooks for
|
||||
# full list of hooks and additional details about custom_access_token_hook
|
||||
|
||||
# GOTRUE_HOOK_CUSTOM_ACCESS_TOKEN_ENABLED: "true"
|
||||
# GOTRUE_HOOK_CUSTOM_ACCESS_TOKEN_URI: "pg-functions://postgres/public/custom_access_token_hook"
|
||||
@@ -157,7 +217,7 @@ services:
|
||||
# GOTRUE_HOOK_SEND_EMAIL_SECRETS: "v1,whsec_VGhpcyBpcyBhbiBleGFtcGxlIG9mIGEgc2hvcnRlciBCYXNlNjQgc3RyaW5n"
|
||||
|
||||
rest:
|
||||
image: postgrest/postgrest:v12.2.12
|
||||
image: postgrest/postgrest:v14.5
|
||||
restart: unless-stopped
|
||||
depends_on:
|
||||
db:
|
||||
@@ -177,7 +237,7 @@ services:
|
||||
|
||||
realtime:
|
||||
# This container name looks inconsistent but is correct because realtime constructs tenant id by parsing the subdomain
|
||||
image: supabase/realtime:v2.34.47
|
||||
image: supabase/realtime:v2.76.5
|
||||
restart: unless-stopped
|
||||
depends_on:
|
||||
db:
|
||||
@@ -188,19 +248,14 @@ services:
|
||||
healthcheck:
|
||||
test:
|
||||
[
|
||||
"CMD",
|
||||
"curl",
|
||||
"-sSfL",
|
||||
"--head",
|
||||
"-o",
|
||||
"/dev/null",
|
||||
"-H",
|
||||
"Authorization: Bearer ${ANON_KEY}",
|
||||
"http://localhost:4000/api/tenants/realtime-dev/health"
|
||||
"CMD-SHELL",
|
||||
"curl -sSfL --head -o /dev/null -H \"Authorization: Bearer
|
||||
${ANON_KEY}\" http://localhost:4000/api/tenants/realtime-dev/health"
|
||||
]
|
||||
timeout: 5s
|
||||
interval: 5s
|
||||
interval: 30s
|
||||
retries: 3
|
||||
start_period: 10s
|
||||
environment:
|
||||
PORT: 4000
|
||||
DB_HOST: ${POSTGRES_HOST}
|
||||
@@ -216,15 +271,22 @@ services:
|
||||
DNS_NODES: "''"
|
||||
RLIMIT_NOFILE: "10000"
|
||||
APP_NAME: realtime
|
||||
SEED_SELF_HOST: true
|
||||
RUN_JANITOR: true
|
||||
SEED_SELF_HOST: "true"
|
||||
RUN_JANITOR: "true"
|
||||
DISABLE_HEALTHCHECK_LOGGING: "true"
|
||||
|
||||
# To use S3 backed storage: docker compose -f docker-compose.yml -f docker-compose.s3.yml up
|
||||
storage:
|
||||
image: supabase/storage-api:v1.25.7
|
||||
image: supabase/storage-api:v1.37.8
|
||||
restart: unless-stopped
|
||||
volumes:
|
||||
- ./volumes/storage:/var/lib/storage:z
|
||||
depends_on:
|
||||
db:
|
||||
# Disable this if you are using an external Postgres database
|
||||
condition: service_healthy
|
||||
rest:
|
||||
condition: service_started
|
||||
imgproxy:
|
||||
condition: service_started
|
||||
healthcheck:
|
||||
test:
|
||||
[
|
||||
@@ -238,32 +300,37 @@ services:
|
||||
timeout: 5s
|
||||
interval: 5s
|
||||
retries: 3
|
||||
depends_on:
|
||||
db:
|
||||
# Disable this if you are using an external Postgres database
|
||||
condition: service_healthy
|
||||
rest:
|
||||
condition: service_started
|
||||
imgproxy:
|
||||
condition: service_started
|
||||
environment:
|
||||
ANON_KEY: ${ANON_KEY}
|
||||
SERVICE_KEY: ${SERVICE_ROLE_KEY}
|
||||
POSTGREST_URL: http://rest:3000
|
||||
PGRST_JWT_SECRET: ${JWT_SECRET}
|
||||
DATABASE_URL: postgres://supabase_storage_admin:${POSTGRES_PASSWORD}@${POSTGRES_HOST}:${POSTGRES_PORT}/${POSTGRES_DB}
|
||||
REQUEST_ALLOW_X_FORWARDED_PATH: "true"
|
||||
FILE_SIZE_LIMIT: 52428800
|
||||
STORAGE_BACKEND: file
|
||||
# S3 bucket when using S3 backend, directory name when using 'file'
|
||||
GLOBAL_S3_BUCKET: ${GLOBAL_S3_BUCKET}
|
||||
# S3 Backend configuration
|
||||
#GLOBAL_S3_ENDPOINT: https://your-s3-endpoint
|
||||
#GLOBAL_S3_PROTOCOL: https
|
||||
#GLOBAL_S3_FORCE_PATH_STYLE: true
|
||||
#AWS_ACCESS_KEY_ID: your-access-key-id
|
||||
#AWS_SECRET_ACCESS_KEY: your-secret-access-key
|
||||
FILE_STORAGE_BACKEND_PATH: /var/lib/storage
|
||||
TENANT_ID: stub
|
||||
TENANT_ID: ${STORAGE_TENANT_ID}
|
||||
# TODO: https://github.com/supabase/storage-api/issues/55
|
||||
REGION: stub
|
||||
GLOBAL_S3_BUCKET: stub
|
||||
REGION: ${REGION}
|
||||
ENABLE_IMAGE_TRANSFORMATION: "true"
|
||||
IMGPROXY_URL: http://imgproxy:5001
|
||||
# S3 protocol endpoint configuration
|
||||
S3_PROTOCOL_ACCESS_KEY_ID: ${S3_PROTOCOL_ACCESS_KEY_ID}
|
||||
S3_PROTOCOL_ACCESS_KEY_SECRET: ${S3_PROTOCOL_ACCESS_KEY_SECRET}
|
||||
volumes:
|
||||
- ./volumes/storage:/var/lib/storage:z
|
||||
|
||||
imgproxy:
|
||||
image: darthsim/imgproxy:v3.8.0
|
||||
image: darthsim/imgproxy:v3.30.1
|
||||
restart: unless-stopped
|
||||
volumes:
|
||||
- ./volumes/storage:/var/lib/storage:z
|
||||
@@ -277,9 +344,10 @@ services:
|
||||
IMGPROXY_LOCAL_FILESYSTEM_ROOT: /
|
||||
IMGPROXY_USE_ETAG: "true"
|
||||
IMGPROXY_ENABLE_WEBP_DETECTION: ${IMGPROXY_ENABLE_WEBP_DETECTION}
|
||||
IMGPROXY_MAX_SRC_RESOLUTION: 16.8
|
||||
|
||||
meta:
|
||||
image: supabase/postgres-meta:v0.91.0
|
||||
image: supabase/postgres-meta:v0.95.2
|
||||
restart: unless-stopped
|
||||
depends_on:
|
||||
db:
|
||||
@@ -294,18 +362,21 @@ services:
|
||||
PG_META_DB_NAME: ${POSTGRES_DB}
|
||||
PG_META_DB_USER: supabase_admin
|
||||
PG_META_DB_PASSWORD: ${POSTGRES_PASSWORD}
|
||||
CRYPTO_KEY: ${PG_META_CRYPTO_KEY}
|
||||
|
||||
functions:
|
||||
image: supabase/edge-runtime:v1.67.4
|
||||
image: supabase/edge-runtime:v1.70.3
|
||||
restart: unless-stopped
|
||||
volumes:
|
||||
- ./volumes/functions:/home/deno/functions:Z
|
||||
- deno-cache:/root/.cache/deno
|
||||
depends_on:
|
||||
analytics:
|
||||
condition: service_healthy
|
||||
environment:
|
||||
JWT_SECRET: ${JWT_SECRET}
|
||||
SUPABASE_URL: http://kong:8000
|
||||
SUPABASE_PUBLIC_URL: ${SUPABASE_PUBLIC_URL}
|
||||
SUPABASE_ANON_KEY: ${ANON_KEY}
|
||||
SUPABASE_SERVICE_ROLE_KEY: ${SERVICE_ROLE_KEY}
|
||||
SUPABASE_DB_URL: postgresql://postgres:${POSTGRES_PASSWORD}@${POSTGRES_HOST}:${POSTGRES_PORT}/${POSTGRES_DB}
|
||||
@@ -314,8 +385,10 @@ services:
|
||||
command: [ "start", "--main-service", "/home/deno/functions/main" ]
|
||||
|
||||
analytics:
|
||||
image: supabase/logflare:1.14.2
|
||||
image: supabase/logflare:1.31.2
|
||||
restart: unless-stopped
|
||||
# ports:
|
||||
# - 4000:4000
|
||||
# Uncomment to use Big Query backend for analytics
|
||||
# volumes:
|
||||
# - type: bind
|
||||
@@ -343,7 +416,6 @@ services:
|
||||
LOGFLARE_PRIVATE_ACCESS_TOKEN: ${LOGFLARE_PRIVATE_ACCESS_TOKEN}
|
||||
LOGFLARE_SINGLE_TENANT: true
|
||||
LOGFLARE_SUPABASE_MODE: true
|
||||
LOGFLARE_MIN_CLUSTER_SIZE: 1
|
||||
|
||||
# Comment variables to use Big Query backend for analytics
|
||||
POSTGRES_BACKEND_URL: postgresql://supabase_admin:${POSTGRES_PASSWORD}@${POSTGRES_HOST}:${POSTGRES_PORT}/_supabase
|
||||
@@ -355,7 +427,7 @@ services:
|
||||
|
||||
# Comment out everything below this point if you are using an external Postgres database
|
||||
db:
|
||||
image: supabase/postgres:15.8.1.060
|
||||
image: supabase/postgres:15.8.1.085
|
||||
restart: unless-stopped
|
||||
volumes:
|
||||
- ./volumes/db/realtime.sql:/docker-entrypoint-initdb.d/migrations/99-realtime.sql:Z
|
||||
@@ -403,7 +475,7 @@ services:
|
||||
]
|
||||
|
||||
vector:
|
||||
image: timberio/vector:0.28.1-alpine
|
||||
image: timberio/vector:0.53.0-alpine
|
||||
restart: unless-stopped
|
||||
volumes:
|
||||
- ./volumes/logs/vector.yml:/etc/vector/vector.yml:ro,z
|
||||
@@ -429,7 +501,7 @@ services:
|
||||
|
||||
# Update the DATABASE_URL if you are using an external Postgres database
|
||||
supavisor:
|
||||
image: supabase/supavisor:2.5.7
|
||||
image: supabase/supavisor:2.7.4
|
||||
restart: unless-stopped
|
||||
volumes:
|
||||
- ./volumes/pooler/pooler.exs:/etc/pooler/pooler.exs:ro,z
|
||||
@@ -480,3 +552,4 @@ services:
|
||||
|
||||
volumes:
|
||||
db-config:
|
||||
deno-cache:
|
||||
|
||||
+61
-29
@@ -1,44 +1,76 @@
|
||||
#!/bin/bash
|
||||
#!/bin/sh
|
||||
|
||||
echo "WARNING: This will remove all containers and container data, and will reset the .env file. This action cannot be undone!"
|
||||
read -p "Are you sure you want to proceed? (y/N) " -n 1 -r
|
||||
echo # Move to a new line
|
||||
if [[ ! $REPLY =~ ^[Yy]$ ]]
|
||||
then
|
||||
echo "Operation cancelled."
|
||||
exit 1
|
||||
set -e
|
||||
|
||||
auto_confirm=0
|
||||
|
||||
confirm () {
|
||||
if [ "$auto_confirm" = "1" ]; then
|
||||
return 0
|
||||
fi
|
||||
|
||||
printf "Are you sure you want to proceed? (y/N) "
|
||||
read -r REPLY
|
||||
case "$REPLY" in
|
||||
[Yy])
|
||||
;;
|
||||
*)
|
||||
echo "Script canceled."
|
||||
exit 1
|
||||
;;
|
||||
esac
|
||||
}
|
||||
|
||||
if [ "$1" = "-y" ]; then
|
||||
auto_confirm=1
|
||||
fi
|
||||
|
||||
echo "Stopping and removing all containers..."
|
||||
docker compose -f docker-compose.yml -f ./dev/docker-compose.dev.yml down -v --remove-orphans
|
||||
echo ""
|
||||
echo "*** WARNING: This will remove all containers and container data, and optionally reset .env ***"
|
||||
echo ""
|
||||
|
||||
echo "Cleaning up bind-mounted directories..."
|
||||
BIND_MOUNTS=(
|
||||
"./volumes/db/data"
|
||||
)
|
||||
confirm
|
||||
|
||||
for DIR in "${BIND_MOUNTS[@]}"; do
|
||||
if [ -d "$DIR" ]; then
|
||||
echo "Deleting $DIR..."
|
||||
rm -rf "$DIR"
|
||||
else
|
||||
echo "Directory $DIR does not exist. Skipping bind mount deletion step..."
|
||||
fi
|
||||
echo "===> Stopping and removing all containers..."
|
||||
|
||||
if [ -f ".env" ]; then
|
||||
docker compose -f docker-compose.yml -f ./dev/docker-compose.dev.yml down -v --remove-orphans
|
||||
elif [ -f ".env.example" ]; then
|
||||
echo "No .env found, using .env.example for docker compose down..."
|
||||
docker compose --env-file .env.example -f docker-compose.yml -f ./dev/docker-compose.dev.yml down -v --remove-orphans
|
||||
else
|
||||
echo "Skipping 'docker compose down' because there's no env-file."
|
||||
fi
|
||||
|
||||
echo "===> Cleaning up bind-mounted directories..."
|
||||
BIND_MOUNTS="./volumes/db/data ./volumes/storage"
|
||||
|
||||
for dir in $BIND_MOUNTS; do
|
||||
if [ -d "$dir" ]; then
|
||||
echo "Removing $dir..."
|
||||
confirm
|
||||
rm -rf "$dir"
|
||||
else
|
||||
echo "$dir not found."
|
||||
fi
|
||||
done
|
||||
|
||||
echo "Resetting .env file..."
|
||||
if [ -f ".env" ]; then
|
||||
echo "Removing existing .env file..."
|
||||
rm -f .env
|
||||
echo "===> Resetting .env file (will save backup to .env.old)..."
|
||||
confirm
|
||||
if [ -f ".env" ] || [ -L ".env" ]; then
|
||||
echo "Renaming existing .env file to .env.old"
|
||||
mv .env .env.old
|
||||
else
|
||||
echo "No .env file found. Skipping .env removal step..."
|
||||
echo "No .env file found."
|
||||
fi
|
||||
|
||||
if [ -f ".env.example" ]; then
|
||||
echo "Copying .env.example to .env..."
|
||||
cp .env.example .env
|
||||
echo "===> Copying .env.example to .env"
|
||||
cp .env.example .env
|
||||
else
|
||||
echo ".env.example file not found. Skipping .env reset step..."
|
||||
echo "No .env.example found, can't restore .env to default values."
|
||||
fi
|
||||
|
||||
echo "Cleanup complete!"
|
||||
echo "Re-run 'docker compose pull' to update images."
|
||||
echo ""
|
||||
|
||||
@@ -0,0 +1,157 @@
|
||||
#!/bin/sh
|
||||
#
|
||||
# Portions of this code are derived from Inder Singh's update-db-pass.sh
|
||||
# Copyright 2025 Inder Singh. Licensed under Apache License 2.0.
|
||||
# Original source:
|
||||
# https://github.com/singh-inder/supabase-automated-self-host/blob/main/docker/update-db-pass.sh
|
||||
#
|
||||
# GitHub discussion here:
|
||||
# https://github.com/supabase/supabase/issues/22605#issuecomment-3323382144
|
||||
#
|
||||
# Changed:
|
||||
# - POSIX shell compatibility
|
||||
# - No hardcoded values for database service and admin user
|
||||
# - Use .env for the admin user and database service port
|
||||
# - Does _not_ set password for supabase_read_only_user (this role is not
|
||||
# supposed to have a password)
|
||||
# - Print all values and confirm before updating
|
||||
# - Stop on any errors
|
||||
#
|
||||
# Heads up:
|
||||
# - Updating _analytics.source_backends is not needed after PR logflare#2069
|
||||
# - Newer Logflare versions use a different table and update connection string
|
||||
#
|
||||
|
||||
set -e
|
||||
|
||||
if ! docker compose version > /dev/null 2>&1; then
|
||||
echo "Docker Compose not found."
|
||||
exit 1
|
||||
fi
|
||||
|
||||
if [ ! -f .env ]; then
|
||||
echo "Missing .env file. Exiting."
|
||||
exit 1
|
||||
fi
|
||||
|
||||
# Generate random hex-only password to avoid issues with SQL/shell
|
||||
new_passwd="$(openssl rand -hex 16)"
|
||||
# If replacing with a custom password, avoid using @/?#:&
|
||||
# https://supabase.com/docs/guides/database/postgres/roles#passwords
|
||||
# new_passwd="d0notUseSpecialSymbolsForPq123-"
|
||||
|
||||
# Check Postgres service
|
||||
db_image_prefix="supabase.postgres:"
|
||||
|
||||
compose_output=$(docker compose ps \
|
||||
--format '{{.Image}}\t{{.Service}}\t{{.Status}}' 2>/dev/null | \
|
||||
grep -m1 "^$db_image_prefix" || true)
|
||||
|
||||
if [ -z "$compose_output" ]; then
|
||||
echo "Postgres container not found. Exiting."
|
||||
exit 1
|
||||
fi
|
||||
|
||||
db_image=$(echo "$compose_output" | cut -f1)
|
||||
db_srv_name=$(echo "$compose_output" | cut -f2)
|
||||
db_srv_status=$(echo "$compose_output" | cut -f3)
|
||||
|
||||
case "$db_srv_status" in
|
||||
Up*)
|
||||
;;
|
||||
*)
|
||||
echo "Postgres container status: $db_srv_status"
|
||||
echo "Exiting."
|
||||
exit 1
|
||||
;;
|
||||
esac
|
||||
|
||||
db_srv_port=$(grep "^POSTGRES_PORT=" .env | cut -d '=' -f 2)
|
||||
port_source=" (.env):"
|
||||
if [ -z "$db_srv_port" ]; then
|
||||
db_srv_port="5432"
|
||||
port_source=" (default):"
|
||||
fi
|
||||
|
||||
db_admin_user="supabase_admin"
|
||||
|
||||
echo ""
|
||||
echo "*** Check configuration below before updating database passwords! ***"
|
||||
echo ""
|
||||
echo "Service name: $db_srv_name"
|
||||
echo "Service status: $db_srv_status"
|
||||
echo "Service port${port_source} $db_srv_port"
|
||||
echo "Image: $db_image"
|
||||
echo ""
|
||||
echo "Admin user: $db_admin_user"
|
||||
|
||||
if ! test -t 0; then
|
||||
echo ""
|
||||
echo "Running non-interactively. Not updating passwords."
|
||||
exit 0
|
||||
fi
|
||||
|
||||
echo "New database password: $new_passwd"
|
||||
echo ""
|
||||
|
||||
printf "Update database passwords? (y/N) "
|
||||
read -r REPLY
|
||||
case "$REPLY" in
|
||||
[Yy])
|
||||
;;
|
||||
*)
|
||||
echo "Canceled. Not updating passwords."
|
||||
exit 0
|
||||
;;
|
||||
esac
|
||||
|
||||
echo "Updating passwords..."
|
||||
echo "Connecting to the database service container..."
|
||||
|
||||
docker compose exec -T "$db_srv_name" psql -U "$db_admin_user" -d "_supabase" -v ON_ERROR_STOP=1 <<EOF
|
||||
alter user anon with password '${new_passwd}';
|
||||
alter user authenticated with password '${new_passwd}';
|
||||
alter user authenticator with password '${new_passwd}';
|
||||
alter user dashboard_user with password '${new_passwd}';
|
||||
alter user pgbouncer with password '${new_passwd}';
|
||||
alter user postgres with password '${new_passwd}';
|
||||
alter user service_role with password '${new_passwd}';
|
||||
alter user supabase_admin with password '${new_passwd}';
|
||||
alter user supabase_auth_admin with password '${new_passwd}';
|
||||
alter user supabase_functions_admin with password '${new_passwd}';
|
||||
alter user supabase_replication_admin with password '${new_passwd}';
|
||||
alter user supabase_storage_admin with password '${new_passwd}';
|
||||
|
||||
DROP SCHEMA _supavisor CASCADE;
|
||||
create schema if not exists _supavisor;
|
||||
alter schema _supavisor owner to supabase_admin;
|
||||
|
||||
DO \$\$
|
||||
BEGIN
|
||||
IF EXISTS (
|
||||
SELECT 1
|
||||
FROM information_schema.tables
|
||||
WHERE table_schema = '_analytics'
|
||||
AND table_name = 'source_backends'
|
||||
) THEN
|
||||
UPDATE _analytics.source_backends
|
||||
SET config = jsonb_set(
|
||||
config,
|
||||
'{url}',
|
||||
'"postgresql://${db_admin_user}:${new_passwd}@${db_srv_name}:${db_srv_port}/postgres"',
|
||||
false
|
||||
)
|
||||
WHERE type = 'postgres';
|
||||
END IF;
|
||||
END
|
||||
\$\$;
|
||||
EOF
|
||||
|
||||
echo "Updating POSTGRES_PASSWORD in .env..."
|
||||
sed -i.old "s|^POSTGRES_PASSWORD=.*$|POSTGRES_PASSWORD=$new_passwd|" .env
|
||||
|
||||
echo ""
|
||||
echo "Success. To update and restart containers use:"
|
||||
echo ""
|
||||
echo "docker compose up -d --force-recreate"
|
||||
echo ""
|
||||
@@ -0,0 +1,123 @@
|
||||
#!/bin/sh
|
||||
#
|
||||
# Portions of this code are derived from Inder Singh's setup.sh shell script.
|
||||
# Copyright 2025 Inder Singh. Licensed under Apache License 2.0.
|
||||
# Original source: https://github.com/singh-inder/supabase-automated-self-host/blob/main/setup.sh
|
||||
#
|
||||
|
||||
set -e
|
||||
|
||||
gen_hex() {
|
||||
openssl rand -hex "$1"
|
||||
}
|
||||
|
||||
gen_base64() {
|
||||
openssl rand -base64 "$1"
|
||||
}
|
||||
|
||||
base64_url_encode() {
|
||||
openssl enc -base64 -A | tr '+/' '-_' | tr -d '='
|
||||
}
|
||||
|
||||
gen_token() {
|
||||
payload=$1
|
||||
payload_base64=$(printf %s "$payload" | base64_url_encode)
|
||||
header_base64=$(printf %s "$header" | base64_url_encode)
|
||||
signed_content="${header_base64}.${payload_base64}"
|
||||
signature=$(printf %s "$signed_content" | openssl dgst -binary -sha256 -hmac "$jwt_secret" | base64_url_encode)
|
||||
printf '%s' "${signed_content}.${signature}"
|
||||
}
|
||||
|
||||
if ! command -v openssl >/dev/null 2>&1; then
|
||||
echo "Error: openssl is required but not found."
|
||||
exit 1
|
||||
fi
|
||||
|
||||
jwt_secret="$(gen_base64 30)"
|
||||
|
||||
# Used in get_token()
|
||||
header='{"alg":"HS256","typ":"JWT"}'
|
||||
iat=$(date +%s)
|
||||
exp=$((iat + 5 * 3600 * 24 * 365)) # 5 years
|
||||
|
||||
# Normalizes JSON formatting so that the token matches https://www.jwt.io/ results
|
||||
anon_payload="{\"role\":\"anon\",\"iss\":\"supabase\",\"iat\":$iat,\"exp\":$exp}"
|
||||
service_role_payload="{\"role\":\"service_role\",\"iss\":\"supabase\",\"iat\":$iat,\"exp\":$exp}"
|
||||
|
||||
#echo "anon_payload=$anon_payload"
|
||||
#echo "service_role_payload=$service_role_payload"
|
||||
|
||||
anon_key=$(gen_token "$anon_payload")
|
||||
service_role_key=$(gen_token "$service_role_payload")
|
||||
|
||||
secret_key_base=$(gen_base64 48)
|
||||
vault_enc_key=$(gen_hex 16)
|
||||
pg_meta_crypto_key=$(gen_base64 24)
|
||||
|
||||
logflare_public_access_token=$(gen_base64 24)
|
||||
logflare_private_access_token=$(gen_base64 24)
|
||||
|
||||
s3_protocol_access_key_id=$(gen_hex 16)
|
||||
s3_protocol_access_key_secret=$(gen_hex 32)
|
||||
|
||||
minio_root_password=$(gen_hex 16)
|
||||
|
||||
echo ""
|
||||
echo "JWT_SECRET=${jwt_secret}"
|
||||
echo ""
|
||||
#echo "Issued at: $iat"
|
||||
#echo "Expire: $exp"
|
||||
echo "ANON_KEY=${anon_key}"
|
||||
echo "SERVICE_ROLE_KEY=${service_role_key}"
|
||||
echo ""
|
||||
echo "SECRET_KEY_BASE=${secret_key_base}"
|
||||
echo "VAULT_ENC_KEY=${vault_enc_key}"
|
||||
echo "PG_META_CRYPTO_KEY=${pg_meta_crypto_key}"
|
||||
echo "LOGFLARE_PUBLIC_ACCESS_TOKEN=${logflare_public_access_token}"
|
||||
echo "LOGFLARE_PRIVATE_ACCESS_TOKEN=${logflare_private_access_token}"
|
||||
echo "S3_PROTOCOL_ACCESS_KEY_ID=${s3_protocol_access_key_id}"
|
||||
echo "S3_PROTOCOL_ACCESS_KEY_SECRET=${s3_protocol_access_key_secret}"
|
||||
echo "MINIO_ROOT_PASSWORD=${minio_root_password}"
|
||||
echo ""
|
||||
|
||||
postgres_password=$(gen_hex 16)
|
||||
dashboard_password=$(gen_hex 16)
|
||||
|
||||
echo "POSTGRES_PASSWORD=${postgres_password}"
|
||||
echo "DASHBOARD_PASSWORD=${dashboard_password}"
|
||||
echo ""
|
||||
|
||||
if ! test -t 0; then
|
||||
echo "Running non-interactively. Skipping .env update."
|
||||
exit 0
|
||||
fi
|
||||
|
||||
printf "Update .env file? (y/N) "
|
||||
read -r REPLY
|
||||
case "$REPLY" in
|
||||
[Yy])
|
||||
;;
|
||||
*)
|
||||
echo "Not updating .env"
|
||||
exit 0
|
||||
;;
|
||||
esac
|
||||
|
||||
echo "Updating .env..."
|
||||
|
||||
sed \
|
||||
-i.old \
|
||||
-e "s|^JWT_SECRET=.*$|JWT_SECRET=${jwt_secret}|" \
|
||||
-e "s|^ANON_KEY=.*$|ANON_KEY=${anon_key}|" \
|
||||
-e "s|^SERVICE_ROLE_KEY=.*$|SERVICE_ROLE_KEY=${service_role_key}|" \
|
||||
-e "s|^SECRET_KEY_BASE=.*$|SECRET_KEY_BASE=${secret_key_base}|" \
|
||||
-e "s|^VAULT_ENC_KEY=.*$|VAULT_ENC_KEY=${vault_enc_key}|" \
|
||||
-e "s|^PG_META_CRYPTO_KEY=.*$|PG_META_CRYPTO_KEY=${pg_meta_crypto_key}|" \
|
||||
-e "s|^LOGFLARE_PUBLIC_ACCESS_TOKEN=.*$|LOGFLARE_PUBLIC_ACCESS_TOKEN=${logflare_public_access_token}|" \
|
||||
-e "s|^LOGFLARE_PRIVATE_ACCESS_TOKEN=.*$|LOGFLARE_PRIVATE_ACCESS_TOKEN=${logflare_private_access_token}|" \
|
||||
-e "s|^S3_PROTOCOL_ACCESS_KEY_ID=.*$|S3_PROTOCOL_ACCESS_KEY_ID=${s3_protocol_access_key_id}|" \
|
||||
-e "s|^S3_PROTOCOL_ACCESS_KEY_SECRET=.*$|S3_PROTOCOL_ACCESS_KEY_SECRET=${s3_protocol_access_key_secret}|" \
|
||||
-e "s|^MINIO_ROOT_PASSWORD=.*$|MINIO_ROOT_PASSWORD=${minio_root_password}|" \
|
||||
-e "s|^POSTGRES_PASSWORD=.*$|POSTGRES_PASSWORD=${postgres_password}|" \
|
||||
-e "s|^DASHBOARD_PASSWORD=.*$|DASHBOARD_PASSWORD=${dashboard_password}|" \
|
||||
.env
|
||||
@@ -0,0 +1,107 @@
|
||||
# Docker Image Versions
|
||||
|
||||
## 2026-02-16
|
||||
- supabase/studio:2026.02.16-sha-26c615c (prev supabase/studio:2026.01.27-sha-6aa59ff)
|
||||
- supabase/gotrue:v2.186.0 (prev supabase/gotrue:v2.185.0)
|
||||
- postgrest/postgrest:v14.5 (prev postgrest/postgrest:v14.3)
|
||||
- supabase/realtime:v2.76.5 (prev supabase/realtime:v2.72.0)
|
||||
- supabase/storage-api:v1.37.8 (prev supabase/storage-api:v1.37.1)
|
||||
- supabase/edge-runtime:v1.70.3 (prev supabase/edge-runtime:v1.70.0)
|
||||
- supabase/logflare:1.31.2 (prev supabase/logflare:1.30.3)
|
||||
- timberio/vector:0.53.0-alpine (prev timberio/vector:0.28.1-alpine)
|
||||
|
||||
## 2026-02-05
|
||||
- supabase/storage-api:v1.37.1 (prev supabase/storage-api:v1.33.5)
|
||||
|
||||
## 2026-01-27
|
||||
- supabase/studio:2026.01.27-sha-6aa59ff (prev supabase/studio:2025.12.17-sha-43f4f7f)
|
||||
- supabase/gotrue:v2.185.0 (prev supabase/gotrue:v2.184.0)
|
||||
- postgrest/postgrest:v14.3 (prev postgrest/postgrest:v14.1)
|
||||
- supabase/realtime:v2.72.0 (prev supabase/realtime:v2.68.0)
|
||||
- supabase/storage-api:v1.33.5 (prev supabase/storage-api:v1.33.0)
|
||||
- darthsim/imgproxy:v3.30.1 (prev darthsim/imgproxy:v3.8.0)
|
||||
- supabase/postgres-meta:v0.95.2 (prev supabase/postgres-meta:v0.95.1)
|
||||
- supabase/edge-runtime:v1.70.0 (prev supabase/edge-runtime:v1.69.28)
|
||||
- supabase/logflare:1.30.3 (prev supabase/logflare:1.27.0)
|
||||
|
||||
## 2025-12-18
|
||||
- supabase/studio:2025.12.17-sha-43f4f7f (prev supabase/studio:2025.12.09-sha-434634f)
|
||||
- supabase/gotrue:v2.184.0 (prev supabase/gotrue:v2.183.0)
|
||||
- supabase/postgres-meta:v0.95.1 (prev supabase/postgres-meta:v0.93.1)
|
||||
- supabase/logflare:1.27.0 (prev supabase/logflare:1.26.25)
|
||||
|
||||
## 2025-12-10
|
||||
- supabase/studio:2025.12.09-sha-434634f (prev supabase/studio:2025.11.26-sha-8f096b5)
|
||||
- postgrest/postgrest:v14.1 (prev postgrest/postgrest:v13.0.7)
|
||||
- supabase/realtime:v2.68.0 (prev supabase/realtime:v2.65.3)
|
||||
- supabase/storage-api:v1.33.0 (prev supabase/storage-api:v1.32.0)
|
||||
- supabase/edge-runtime:v1.69.28 (prev supabase/edge-runtime:v1.69.25)
|
||||
- supabase/logflare:1.26.25 (prev supabase/logflare:1.26.13)
|
||||
|
||||
## 2025-11-26
|
||||
- supabase/studio:2025.11.26-sha-8f096b5 (prev supabase/studio:2025.11.24-sha-d990ae8)
|
||||
- supabase/realtime:v2.65.3 (prev supabase/realtime:v2.65.2)
|
||||
- supabase/logflare:1.26.13 (prev supabase/logflare:1.26.12)
|
||||
|
||||
## 2025-11-25
|
||||
- supabase/studio:2025.11.24-sha-d990ae8 (prev supabase/studio:2025.11.10-sha-5291fe3)
|
||||
- supabase/gotrue:v2.183.0 (prev supabase/gotrue:v2.182.1)
|
||||
- supabase/realtime:v2.65.2 (prev supabase/realtime:v2.63.0)
|
||||
- supabase/storage-api:v1.32.0 (prev supabase/storage-api:v1.29.0)
|
||||
- supabase/edge-runtime:v1.69.25 (prev supabase/edge-runtime:v1.69.23)
|
||||
- supabase/logflare:1.26.12 (prev supabase/logflare:1.22.6)
|
||||
|
||||
## 2025-11-12
|
||||
- supabase/studio:2025.11.10-sha-5291fe3 (prev 2025.10.27-sha-85b84e0)
|
||||
- supabase/gotrue:v2.182.1 (prev v2.180.0)
|
||||
- supabase/realtime:v2.63.0 (prev v2.57.2)
|
||||
- supabase/storage-api:v1.29.0 (prev v1.28.2)
|
||||
- supabase/edge-runtime:v1.69.23 (prev v1.69.15)
|
||||
- supabase/supavisor:2.7.4 (prev 2.7.3)
|
||||
|
||||
## 2025-10-28
|
||||
- supabase/studio:2025.10.27-sha-85b84e0 (prev 2025.10.20-sha-5005fc6)
|
||||
- supabase/realtime:v2.57.2 (prev v2.56.0)
|
||||
- supabase/storage-api:v1.28.2 (prev v1.28.1)
|
||||
- supabase/postgres-meta:v0.93.1 (prev v0.93.0)
|
||||
- supabase/edge-runtime:v1.69.15 (prev v1.69.14)
|
||||
|
||||
## 2025-10-21
|
||||
- supabase/studio:2025.10.20-sha-5005fc6 (prev 2025.10.01-sha-8460121)
|
||||
- supabase/realtime:v2.56.0 (prev v2.51.11)
|
||||
- supabase/storage-api:v1.28.1 (prev v1.28.0)
|
||||
- supabase/postgres-meta:v0.93.0 (prev v0.91.6)
|
||||
- supabase/edge-runtime:v1.69.14 (prev v1.69.6)
|
||||
- supabase/supavisor:2.7.3 (prev 2.7.0)
|
||||
|
||||
## 2025-10-13
|
||||
- supabase/logflare:1.22.6 (prev 1.22.4)
|
||||
|
||||
## 2025-10-08
|
||||
- supabase/studio:2025.10.01-sha-8460121 (prev 2025.06.30-sha-6f5982d)
|
||||
- supabase/gotrue:v2.180.0 (prev v2.177.0)
|
||||
- postgrest/postgrest:v13.0.7 (prev v12.2.12)
|
||||
- supabase/realtime:v2.51.11 (prev v2.34.47)
|
||||
- supabase/storage-api:v1.28.0 (prev v1.25.7)
|
||||
- supabase/postgres-meta:v0.91.6 (prev v0.91.0)
|
||||
- supabase/logflare:1.22.4 (prev 1.14.2)
|
||||
- supabase/postgres:15.8.1.085 (prev 15.8.1.060)
|
||||
- supabase/supavisor:2.7.0 (prev 2.5.7)
|
||||
|
||||
## 2025-07-15
|
||||
- supabase/gotrue:v2.177.0 (prev v2.176.1)
|
||||
- supabase/storage-api:v1.25.7 (prev v1.24.7)
|
||||
- supabase/postgres-meta:v0.91.0 (prev v0.89.3)
|
||||
- supabase/supavisor:2.5.7 (prev 2.5.6)
|
||||
|
||||
## 2025-07-02
|
||||
- supabase/studio:2025.06.30-sha-6f5982d (prev 2025.06.02-sha-8f2993d)
|
||||
- supabase/gotrue:v2.176.1 (prev v2.174.0)
|
||||
- supabase/storage-api:v1.24.7 (prev v1.23.0)
|
||||
- supabase/supavisor:2.5.6 (prev 2.5.1)
|
||||
|
||||
## 2025-06-03
|
||||
- supabase/studio:2025.06.02-sha-8f2993d (prev 2025.05.19-sha-3487831)
|
||||
- supabase/gotrue:v2.174.0 (prev v2.172.1)
|
||||
- supabase/storage-api:v1.23.0 (prev v1.22.17)
|
||||
- supabase/postgres-meta:v0.89.3 (prev v0.89.0)
|
||||
@@ -27,8 +27,8 @@ acls:
|
||||
###
|
||||
basicauth_credentials:
|
||||
- consumer: DASHBOARD
|
||||
username: $DASHBOARD_USERNAME
|
||||
password: $DASHBOARD_PASSWORD
|
||||
username: '$DASHBOARD_USERNAME'
|
||||
password: '$DASHBOARD_PASSWORD'
|
||||
|
||||
###
|
||||
### API Routes
|
||||
@@ -197,14 +197,29 @@ services:
|
||||
- name: cors
|
||||
|
||||
## Analytics routes
|
||||
- name: analytics-v1
|
||||
_comment: 'Analytics: /analytics/v1/* -> http://logflare:4000/*'
|
||||
url: http://analytics:4000/
|
||||
routes:
|
||||
- name: analytics-v1-all
|
||||
strip_path: true
|
||||
paths:
|
||||
- /analytics/v1/
|
||||
## Not used - Studio and Vector talk directly to analytics via Docker networking.
|
||||
## If external access is needed, add routes with key-auth matching Logflare's x-api-key auth.
|
||||
# - name: analytics-v1-api
|
||||
# _comment: 'Analytics: /analytics/v1/api/endpoints/* -> http://logflare:4000/api/endpoints/*'
|
||||
# url: http://analytics:4000/api/endpoints
|
||||
# routes:
|
||||
# - name: analytics-v1-api
|
||||
# strip_path: true
|
||||
# paths:
|
||||
# - /analytics/v1/api/endpoints/
|
||||
# - name: analytics-v1
|
||||
# _comment: 'Analytics: /analytics/v1/* -> http://logflare:4000/*'
|
||||
# url: http://analytics:4000/
|
||||
# routes:
|
||||
# - name: dashboard-v1-all
|
||||
# strip_path: true
|
||||
# paths:
|
||||
# - /analytics/v1
|
||||
# plugins:
|
||||
# - name: cors
|
||||
# - name: basic-auth
|
||||
# config:
|
||||
# hide_credentials: true
|
||||
|
||||
## Secure Database routes
|
||||
- name: meta
|
||||
@@ -225,6 +240,48 @@ services:
|
||||
allow:
|
||||
- admin
|
||||
|
||||
## Block access to /api/mcp
|
||||
- name: mcp-blocker
|
||||
_comment: 'Block direct access to /api/mcp'
|
||||
url: http://studio:3000/api/mcp
|
||||
routes:
|
||||
- name: mcp-blocker-route
|
||||
strip_path: true
|
||||
paths:
|
||||
- /api/mcp
|
||||
plugins:
|
||||
- name: request-termination
|
||||
config:
|
||||
status_code: 403
|
||||
message: "Access is forbidden."
|
||||
|
||||
## MCP endpoint - local access
|
||||
- name: mcp
|
||||
_comment: 'MCP: /mcp -> http://studio:3000/api/mcp (local access)'
|
||||
url: http://studio:3000/api/mcp
|
||||
routes:
|
||||
- name: mcp
|
||||
strip_path: true
|
||||
paths:
|
||||
- /mcp
|
||||
plugins:
|
||||
# Block access to /mcp by default
|
||||
- name: request-termination
|
||||
config:
|
||||
status_code: 403
|
||||
message: "Access is forbidden."
|
||||
# Enable local access (danger zone!)
|
||||
# 1. Comment out the 'request-termination' section above
|
||||
# 2. Uncomment the entire section below, including 'deny'
|
||||
# 3. Add your local IPs to the 'allow' list
|
||||
#- name: cors
|
||||
#- name: ip-restriction
|
||||
# config:
|
||||
# allow:
|
||||
# - 127.0.0.1
|
||||
# - ::1
|
||||
# deny: []
|
||||
|
||||
## Protected Dashboard - catch all remaining routes
|
||||
- name: dashboard
|
||||
_comment: 'Studio: /* -> http://studio:3000/*'
|
||||
|
||||
@@ -2,9 +2,7 @@
|
||||
// https://deno.land/manual/getting_started/setup_your_environment
|
||||
// This enables autocomplete, go to definition, etc.
|
||||
|
||||
import { serve } from "https://deno.land/std@0.177.1/http/server.ts"
|
||||
|
||||
serve(async () => {
|
||||
Deno.serve(async () => {
|
||||
return new Response(
|
||||
`"Hello from Edge Functions!"`,
|
||||
{ headers: { "Content-Type": "application/json" } },
|
||||
|
||||
@@ -1,4 +1,3 @@
|
||||
import { serve } from 'https://deno.land/std@0.131.0/http/server.ts'
|
||||
import * as jose from 'https://deno.land/x/jose@v4.14.4/index.ts'
|
||||
|
||||
console.log('main function started')
|
||||
@@ -30,7 +29,7 @@ async function verifyJWT(jwt: string): Promise<boolean> {
|
||||
return true
|
||||
}
|
||||
|
||||
serve(async (req: Request) => {
|
||||
Deno.serve(async (req: Request) => {
|
||||
if (req.method !== 'OPTIONS' && VERIFY_JWT) {
|
||||
try {
|
||||
const token = getAuthToken(req)
|
||||
|
||||
@@ -33,9 +33,9 @@ transforms:
|
||||
kong: '.appname == "supabase-kong"'
|
||||
auth: '.appname == "supabase-auth"'
|
||||
rest: '.appname == "supabase-rest"'
|
||||
realtime: '.appname == "supabase-realtime"'
|
||||
realtime: '.appname == "realtime-dev.supabase-realtime"'
|
||||
storage: '.appname == "supabase-storage"'
|
||||
functions: '.appname == "supabase-functions"'
|
||||
functions: '.appname == "supabase-edge-functions"'
|
||||
db: '.appname == "supabase-db"'
|
||||
# Ignores non nginx errors since they are related with kong booting up
|
||||
kong_logs:
|
||||
@@ -49,10 +49,13 @@ transforms:
|
||||
.metadata.request.headers.referer = req.referer
|
||||
.metadata.request.headers.user_agent = req.agent
|
||||
.metadata.request.headers.cf_connecting_ip = req.client
|
||||
.metadata.request.method = req.method
|
||||
.metadata.request.path = req.path
|
||||
.metadata.request.protocol = req.protocol
|
||||
.metadata.response.status_code = req.status
|
||||
url, split_err = split(req.request, " ")
|
||||
if split_err == null {
|
||||
.metadata.request.method = url[0]
|
||||
.metadata.request.path = url[1]
|
||||
.metadata.request.protocol = url[2]
|
||||
}
|
||||
}
|
||||
if err != null {
|
||||
abort
|
||||
@@ -101,14 +104,20 @@ transforms:
|
||||
parsed, err = parse_regex(.event_message, r'^(?P<time>.*): (?P<msg>.*)$')
|
||||
if err == null {
|
||||
.event_message = parsed.msg
|
||||
.timestamp = to_timestamp!(parsed.time)
|
||||
.timestamp = parse_timestamp!(value: parsed.time,format: "%d/%b/%Y:%H:%M:%S %z")
|
||||
.metadata.host = .project
|
||||
}
|
||||
# Filter out healthcheck logs from Realtime
|
||||
realtime_logs_filtered:
|
||||
type: filter
|
||||
inputs:
|
||||
- router.realtime
|
||||
condition: '!contains(string!(.event_message), "/health")'
|
||||
# Realtime logs are structured so we parse the severity level using regex (ignore time because it has no date)
|
||||
realtime_logs:
|
||||
type: remap
|
||||
inputs:
|
||||
- router.realtime
|
||||
- realtime_logs_filtered
|
||||
source: |-
|
||||
.metadata.project = del(.project)
|
||||
.metadata.external_id = .metadata.project
|
||||
@@ -117,6 +126,13 @@ transforms:
|
||||
.event_message = parsed.msg
|
||||
.metadata.level = parsed.level
|
||||
}
|
||||
# Function logs are unstructured messages on stderr
|
||||
functions_logs:
|
||||
type: remap
|
||||
inputs:
|
||||
- router.functions
|
||||
source: |-
|
||||
.metadata.project_ref = del(.project)
|
||||
# Storage logs may contain json objects so we parse them for completeness
|
||||
storage_logs:
|
||||
type: remap
|
||||
@@ -147,7 +163,7 @@ transforms:
|
||||
if err != null || parsed == null {
|
||||
.metadata.parsed.error_severity = "info"
|
||||
}
|
||||
if parsed != null {
|
||||
if parsed.level != null {
|
||||
.metadata.parsed.error_severity = parsed.level
|
||||
}
|
||||
if .metadata.parsed.error_severity == "info" {
|
||||
@@ -164,7 +180,8 @@ sinks:
|
||||
codec: 'json'
|
||||
method: 'post'
|
||||
request:
|
||||
retry_max_duration_secs: 10
|
||||
retry_max_duration_secs: 30
|
||||
retry_initial_backoff_secs: 1
|
||||
headers:
|
||||
x-api-key: ${LOGFLARE_PUBLIC_ACCESS_TOKEN?LOGFLARE_PUBLIC_ACCESS_TOKEN is required}
|
||||
uri: 'http://analytics:4000/api/logs?source_name=gotrue.logs.prod'
|
||||
@@ -176,7 +193,8 @@ sinks:
|
||||
codec: 'json'
|
||||
method: 'post'
|
||||
request:
|
||||
retry_max_duration_secs: 10
|
||||
retry_max_duration_secs: 30
|
||||
retry_initial_backoff_secs: 1
|
||||
headers:
|
||||
x-api-key: ${LOGFLARE_PUBLIC_ACCESS_TOKEN?LOGFLARE_PUBLIC_ACCESS_TOKEN is required}
|
||||
uri: 'http://analytics:4000/api/logs?source_name=realtime.logs.prod'
|
||||
@@ -188,7 +206,8 @@ sinks:
|
||||
codec: 'json'
|
||||
method: 'post'
|
||||
request:
|
||||
retry_max_duration_secs: 10
|
||||
retry_max_duration_secs: 30
|
||||
retry_initial_backoff_secs: 1
|
||||
headers:
|
||||
x-api-key: ${LOGFLARE_PUBLIC_ACCESS_TOKEN?LOGFLARE_PUBLIC_ACCESS_TOKEN is required}
|
||||
uri: 'http://analytics:4000/api/logs?source_name=postgREST.logs.prod'
|
||||
@@ -200,22 +219,23 @@ sinks:
|
||||
codec: 'json'
|
||||
method: 'post'
|
||||
request:
|
||||
retry_max_duration_secs: 10
|
||||
retry_max_duration_secs: 30
|
||||
retry_initial_backoff_secs: 1
|
||||
headers:
|
||||
x-api-key: ${LOGFLARE_PUBLIC_ACCESS_TOKEN?LOGFLARE_PUBLIC_ACCESS_TOKEN is required}
|
||||
# We must route the sink through kong because ingesting logs before logflare is fully initialised will
|
||||
# lead to broken queries from studio. This works by the assumption that containers are started in the
|
||||
# following order: vector > db > logflare > kong
|
||||
uri: 'http://kong:8000/analytics/v1/api/logs?source_name=postgres.logs'
|
||||
# Route directly to analytics like other sinks. Retry handles the startup
|
||||
# race where analytics may not be ready yet when early DB logs arrive.
|
||||
uri: 'http://analytics:4000/api/logs?source_name=postgres.logs'
|
||||
logflare_functions:
|
||||
type: 'http'
|
||||
inputs:
|
||||
- router.functions
|
||||
- functions_logs
|
||||
encoding:
|
||||
codec: 'json'
|
||||
method: 'post'
|
||||
request:
|
||||
retry_max_duration_secs: 10
|
||||
retry_max_duration_secs: 30
|
||||
retry_initial_backoff_secs: 1
|
||||
headers:
|
||||
x-api-key: ${LOGFLARE_PUBLIC_ACCESS_TOKEN?LOGFLARE_PUBLIC_ACCESS_TOKEN is required}
|
||||
uri: 'http://analytics:4000/api/logs?source_name=deno-relay-logs'
|
||||
@@ -227,7 +247,8 @@ sinks:
|
||||
codec: 'json'
|
||||
method: 'post'
|
||||
request:
|
||||
retry_max_duration_secs: 10
|
||||
retry_max_duration_secs: 30
|
||||
retry_initial_backoff_secs: 1
|
||||
headers:
|
||||
x-api-key: ${LOGFLARE_PUBLIC_ACCESS_TOKEN?LOGFLARE_PUBLIC_ACCESS_TOKEN is required}
|
||||
uri: 'http://analytics:4000/api/logs?source_name=storage.logs.prod.2'
|
||||
@@ -240,7 +261,8 @@ sinks:
|
||||
codec: 'json'
|
||||
method: 'post'
|
||||
request:
|
||||
retry_max_duration_secs: 10
|
||||
retry_max_duration_secs: 30
|
||||
retry_initial_backoff_secs: 1
|
||||
headers:
|
||||
x-api-key: ${LOGFLARE_PUBLIC_ACCESS_TOKEN?LOGFLARE_PUBLIC_ACCESS_TOKEN is required}
|
||||
uri: 'http://analytics:4000/api/logs?source_name=cloudflare.logs.prod'
|
||||
|
||||
@@ -0,0 +1,36 @@
|
||||
{$PROXY_DOMAIN} {
|
||||
@supabase_api path /auth/v1/* /rest/v1/* /graphql/v1/* /realtime/v1/* /functions/v1/* /mcp
|
||||
|
||||
handle @supabase_api {
|
||||
reverse_proxy kong:8000
|
||||
}
|
||||
|
||||
handle_path /storage/v1/* {
|
||||
# CORS headers for Storage (bypasses Kong, which normally handles CORS)
|
||||
@cors_preflight method OPTIONS
|
||||
handle @cors_preflight {
|
||||
header Access-Control-Allow-Origin *
|
||||
header Access-Control-Allow-Methods "GET, HEAD, PUT, PATCH, POST, DELETE, OPTIONS"
|
||||
header Access-Control-Allow-Headers *
|
||||
respond 204
|
||||
}
|
||||
|
||||
header Access-Control-Allow-Origin *
|
||||
|
||||
reverse_proxy storage:5000 {
|
||||
# Required for TUS resumable upload Location headers and S3 signature verification.
|
||||
header_up X-Forwarded-Prefix /{http.request.orig_uri.path.0}/{http.request.orig_uri.path.1}
|
||||
}
|
||||
}
|
||||
|
||||
handle {
|
||||
basic_auth {
|
||||
# PROXY_AUTH_PASSWORD is overwritten with the bcrypt on startup
|
||||
{$PROXY_AUTH_USERNAME} {$PROXY_AUTH_PASSWORD}
|
||||
}
|
||||
|
||||
reverse_proxy studio:3000
|
||||
}
|
||||
|
||||
header -server
|
||||
}
|
||||
@@ -0,0 +1,109 @@
|
||||
upstream kong_upstream {
|
||||
server kong:8000;
|
||||
keepalive 2;
|
||||
}
|
||||
|
||||
server {
|
||||
listen 443 ssl;
|
||||
listen [::]:443 ssl;
|
||||
http2 on;
|
||||
|
||||
server_name ${PROXY_DOMAIN};
|
||||
server_tokens off;
|
||||
|
||||
proxy_http_version 1.1;
|
||||
|
||||
proxy_set_header Host $host;
|
||||
proxy_set_header X-Real-IP $remote_addr;
|
||||
proxy_set_header X-Forwarded-For $remote_addr;
|
||||
proxy_set_header X-Forwarded-Proto $scheme;
|
||||
proxy_set_header X-Forwarded-Host $http_host;
|
||||
proxy_set_header X-Forwarded-Port $server_port;
|
||||
|
||||
ssl_certificate /etc/letsencrypt/live/${PROXY_DOMAIN}/fullchain.pem;
|
||||
ssl_certificate_key /etc/letsencrypt/live/${PROXY_DOMAIN}/privkey.pem;
|
||||
ssl_trusted_certificate /etc/letsencrypt/live/${PROXY_DOMAIN}/chain.pem;
|
||||
|
||||
ssl_dhparam /etc/letsencrypt/dhparams/dhparam.pem;
|
||||
|
||||
ssl_session_cache shared:SSL:10m;
|
||||
ssl_session_timeout 10m;
|
||||
|
||||
# Prevent 502 errors from large Supabase auth cookies
|
||||
large_client_header_buffers 4 16k;
|
||||
proxy_buffer_size 128k;
|
||||
proxy_buffers 4 256k;
|
||||
proxy_busy_buffers_size 256k;
|
||||
|
||||
location / {
|
||||
auth_basic "supabase";
|
||||
auth_basic_user_file /etc/nginx/user_conf.d/dashboard-passwd;
|
||||
|
||||
proxy_pass http://studio:3000;
|
||||
}
|
||||
|
||||
location /auth {
|
||||
proxy_pass http://kong_upstream;
|
||||
}
|
||||
|
||||
location /rest {
|
||||
proxy_pass http://kong_upstream;
|
||||
}
|
||||
|
||||
location /realtime/v1/ {
|
||||
proxy_pass http://kong_upstream;
|
||||
|
||||
proxy_set_header Host $host;
|
||||
proxy_set_header X-Real-IP $remote_addr;
|
||||
proxy_set_header X-Forwarded-For $remote_addr;
|
||||
proxy_set_header X-Forwarded-Proto $scheme;
|
||||
proxy_set_header X-Forwarded-Host $http_host;
|
||||
proxy_set_header X-Forwarded-Port $server_port;
|
||||
|
||||
proxy_set_header Upgrade $http_upgrade;
|
||||
proxy_set_header Connection "upgrade";
|
||||
|
||||
proxy_read_timeout 3600s;
|
||||
}
|
||||
|
||||
location /storage/v1/ {
|
||||
proxy_pass http://storage:5000/;
|
||||
proxy_buffering off;
|
||||
|
||||
proxy_set_header Host $host;
|
||||
proxy_set_header X-Real-IP $remote_addr;
|
||||
proxy_set_header X-Forwarded-For $remote_addr;
|
||||
proxy_set_header X-Forwarded-Proto $scheme;
|
||||
proxy_set_header X-Forwarded-Host $http_host;
|
||||
proxy_set_header X-Forwarded-Port $server_port;
|
||||
|
||||
# Required for TUS resumable upload Location headers and S3 signature verification.
|
||||
proxy_set_header X-Forwarded-Prefix /storage/v1;
|
||||
|
||||
client_max_body_size 0;
|
||||
|
||||
# CORS headers for Storage (bypasses Kong, which normally handles CORS)
|
||||
if ($request_method = OPTIONS) {
|
||||
add_header 'Access-Control-Allow-Origin' '*';
|
||||
add_header 'Access-Control-Allow-Methods' 'GET, HEAD, PUT, PATCH, POST, DELETE, OPTIONS';
|
||||
add_header 'Access-Control-Allow-Headers' '*';
|
||||
add_header 'Content-Length' 0;
|
||||
add_header 'Content-Type' 'text/plain charset=UTF-8';
|
||||
return 204;
|
||||
}
|
||||
|
||||
add_header 'Access-Control-Allow-Origin' '*';
|
||||
}
|
||||
|
||||
location /functions {
|
||||
proxy_pass http://kong_upstream;
|
||||
}
|
||||
|
||||
location /graphql {
|
||||
proxy_pass http://kong_upstream;
|
||||
}
|
||||
|
||||
location /mcp {
|
||||
proxy_pass http://kong_upstream;
|
||||
}
|
||||
}
|
||||
+1
-1
@@ -1,6 +1,6 @@
|
||||
import utils from "../utils.js";
|
||||
|
||||
await utils.cloneOrPullRepo({ repo: "https://github.com/supabase/supabase" });
|
||||
await utils.cloneOrPullRepo({ repo: "https://github.com/supabase/supabase", branch: "master" });
|
||||
await utils.copyDir("./repo/docker", "./code");
|
||||
|
||||
await utils.removeContainerNames("./code/docker-compose.yml");
|
||||
|
||||
Reference in New Issue
Block a user