Compare commits
12 Commits
| Author | SHA1 | Date | |
|---|---|---|---|
| 0381268589 | |||
| 527c097c61 | |||
| 61e436a151 | |||
| 988bcb7223 | |||
| a0b5bb0c2a | |||
| 128651d310 | |||
| 6f07307229 | |||
| f32d48a271 | |||
| c6b41076ea | |||
| 854efbcff0 | |||
| ee335fa22e | |||
| fa0b9127f1 |
@@ -6,7 +6,7 @@ _APP_OPTIONS_FUNCTIONS_FORCE_HTTPS=disabled
|
|||||||
_APP_OPTIONS_ROUTER_FORCE_HTTPS=disabled
|
_APP_OPTIONS_ROUTER_FORCE_HTTPS=disabled
|
||||||
_APP_OPTIONS_ROUTER_PROTECTION=disabled
|
_APP_OPTIONS_ROUTER_PROTECTION=disabled
|
||||||
_APP_OPENSSL_KEY_V1=your-secret-key
|
_APP_OPENSSL_KEY_V1=your-secret-key
|
||||||
_APP_DOMAIN=localhost
|
_APP_DOMAIN=$(PRIMARY_DOMAIN)
|
||||||
_APP_CUSTOM_DOMAIN_DENY_LIST=example.com,test.com,app.example.com
|
_APP_CUSTOM_DOMAIN_DENY_LIST=example.com,test.com,app.example.com
|
||||||
_APP_DOMAIN_FUNCTIONS=functions.localhost
|
_APP_DOMAIN_FUNCTIONS=functions.localhost
|
||||||
_APP_DOMAIN_SITES=sites.localhost
|
_APP_DOMAIN_SITES=sites.localhost
|
||||||
@@ -14,6 +14,8 @@ _APP_DOMAIN_TARGET=localhost
|
|||||||
_APP_DOMAIN_TARGET_CNAME=localhost
|
_APP_DOMAIN_TARGET_CNAME=localhost
|
||||||
_APP_DOMAIN_TARGET_AAAA=::1
|
_APP_DOMAIN_TARGET_AAAA=::1
|
||||||
_APP_DOMAIN_TARGET_A=127.0.0.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_ROOT=enabled
|
||||||
_APP_CONSOLE_WHITELIST_EMAILS=
|
_APP_CONSOLE_WHITELIST_EMAILS=
|
||||||
_APP_CONSOLE_WHITELIST_IPS=
|
_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_FUNCTIONS_RUNTIMES=node-16.0,php-8.0,python-3.9,ruby-3.0
|
||||||
_APP_EXECUTOR_SECRET=your-secret-key
|
_APP_EXECUTOR_SECRET=your-secret-key
|
||||||
_APP_EXECUTOR_HOST=http://exc1/v1
|
_APP_EXECUTOR_HOST=http://exc1/v1
|
||||||
|
_APP_BROWSER_HOST=http://appwrite-browser:3000/v1
|
||||||
_APP_EXECUTOR_RUNTIME_NETWORK=appwrite_runtimes
|
_APP_EXECUTOR_RUNTIME_NETWORK=appwrite_runtimes
|
||||||
_APP_FUNCTIONS_ENVS=node-16.0,php-7.4,python-3.9,ruby-3.0
|
_APP_FUNCTIONS_ENVS=node-16.0,php-7.4,python-3.9,ruby-3.0
|
||||||
_APP_FUNCTIONS_INACTIVE_THRESHOLD=60
|
_APP_FUNCTIONS_INACTIVE_THRESHOLD=60
|
||||||
|
|||||||
@@ -28,7 +28,7 @@ services:
|
|||||||
- appwrite
|
- appwrite
|
||||||
|
|
||||||
appwrite:
|
appwrite:
|
||||||
image: appwrite/appwrite:1.7.4
|
image: appwrite/appwrite:1.8.1
|
||||||
<<: *x-logging
|
<<: *x-logging
|
||||||
restart: unless-stopped
|
restart: unless-stopped
|
||||||
networks:
|
networks:
|
||||||
@@ -83,6 +83,8 @@ services:
|
|||||||
- _APP_DOMAIN_TARGET_CNAME
|
- _APP_DOMAIN_TARGET_CNAME
|
||||||
- _APP_DOMAIN_TARGET_AAAA
|
- _APP_DOMAIN_TARGET_AAAA
|
||||||
- _APP_DOMAIN_TARGET_A
|
- _APP_DOMAIN_TARGET_A
|
||||||
|
- _APP_DOMAIN_TARGET_CAA
|
||||||
|
- _APP_DNS
|
||||||
- _APP_DOMAIN_FUNCTIONS
|
- _APP_DOMAIN_FUNCTIONS
|
||||||
- _APP_REDIS_HOST
|
- _APP_REDIS_HOST
|
||||||
- _APP_REDIS_PORT
|
- _APP_REDIS_PORT
|
||||||
@@ -162,10 +164,9 @@ services:
|
|||||||
- _APP_MIGRATIONS_FIREBASE_CLIENT_ID
|
- _APP_MIGRATIONS_FIREBASE_CLIENT_ID
|
||||||
- _APP_MIGRATIONS_FIREBASE_CLIENT_SECRET
|
- _APP_MIGRATIONS_FIREBASE_CLIENT_SECRET
|
||||||
- _APP_ASSISTANT_OPENAI_API_KEY
|
- _APP_ASSISTANT_OPENAI_API_KEY
|
||||||
|
|
||||||
appwrite-console:
|
appwrite-console:
|
||||||
<<: *x-logging
|
<<: *x-logging
|
||||||
image: appwrite/console:6.0.13
|
image: appwrite/console:7.5.7
|
||||||
restart: unless-stopped
|
restart: unless-stopped
|
||||||
networks:
|
networks:
|
||||||
- appwrite
|
- appwrite
|
||||||
@@ -185,7 +186,7 @@ services:
|
|||||||
- traefik.http.routers.appwrite_console_https.tls=true
|
- traefik.http.routers.appwrite_console_https.tls=true
|
||||||
|
|
||||||
appwrite-realtime:
|
appwrite-realtime:
|
||||||
image: appwrite/appwrite:1.7.4
|
image: appwrite/appwrite:1.8.1
|
||||||
entrypoint: realtime
|
entrypoint: realtime
|
||||||
<<: *x-logging
|
<<: *x-logging
|
||||||
restart: unless-stopped
|
restart: unless-stopped
|
||||||
@@ -227,7 +228,7 @@ services:
|
|||||||
- _APP_LOGGING_CONFIG
|
- _APP_LOGGING_CONFIG
|
||||||
|
|
||||||
appwrite-worker-audits:
|
appwrite-worker-audits:
|
||||||
image: appwrite/appwrite:1.7.4
|
image: appwrite/appwrite:1.8.1
|
||||||
entrypoint: worker-audits
|
entrypoint: worker-audits
|
||||||
<<: *x-logging
|
<<: *x-logging
|
||||||
restart: unless-stopped
|
restart: unless-stopped
|
||||||
@@ -252,7 +253,7 @@ services:
|
|||||||
- _APP_LOGGING_CONFIG
|
- _APP_LOGGING_CONFIG
|
||||||
|
|
||||||
appwrite-worker-webhooks:
|
appwrite-worker-webhooks:
|
||||||
image: appwrite/appwrite:1.7.4
|
image: appwrite/appwrite:1.8.1
|
||||||
entrypoint: worker-webhooks
|
entrypoint: worker-webhooks
|
||||||
<<: *x-logging
|
<<: *x-logging
|
||||||
restart: unless-stopped
|
restart: unless-stopped
|
||||||
@@ -279,7 +280,7 @@ services:
|
|||||||
- _APP_LOGGING_CONFIG
|
- _APP_LOGGING_CONFIG
|
||||||
|
|
||||||
appwrite-worker-deletes:
|
appwrite-worker-deletes:
|
||||||
image: appwrite/appwrite:1.7.4
|
image: appwrite/appwrite:1.8.1
|
||||||
entrypoint: worker-deletes
|
entrypoint: worker-deletes
|
||||||
<<: *x-logging
|
<<: *x-logging
|
||||||
restart: unless-stopped
|
restart: unless-stopped
|
||||||
@@ -341,7 +342,7 @@ services:
|
|||||||
- _APP_EMAIL_CERTIFICATES
|
- _APP_EMAIL_CERTIFICATES
|
||||||
|
|
||||||
appwrite-worker-databases:
|
appwrite-worker-databases:
|
||||||
image: appwrite/appwrite:1.7.4
|
image: appwrite/appwrite:1.8.1
|
||||||
entrypoint: worker-databases
|
entrypoint: worker-databases
|
||||||
<<: *x-logging
|
<<: *x-logging
|
||||||
restart: unless-stopped
|
restart: unless-stopped
|
||||||
@@ -366,7 +367,7 @@ services:
|
|||||||
- _APP_LOGGING_CONFIG
|
- _APP_LOGGING_CONFIG
|
||||||
|
|
||||||
appwrite-worker-builds:
|
appwrite-worker-builds:
|
||||||
image: appwrite/appwrite:1.7.4
|
image: appwrite/appwrite:1.8.1
|
||||||
entrypoint: worker-builds
|
entrypoint: worker-builds
|
||||||
<<: *x-logging
|
<<: *x-logging
|
||||||
restart: unless-stopped
|
restart: unless-stopped
|
||||||
@@ -433,7 +434,7 @@ services:
|
|||||||
- _APP_DOMAIN_SITES
|
- _APP_DOMAIN_SITES
|
||||||
|
|
||||||
appwrite-worker-certificates:
|
appwrite-worker-certificates:
|
||||||
image: appwrite/appwrite:1.7.4
|
image: appwrite/appwrite:1.8.1
|
||||||
entrypoint: worker-certificates
|
entrypoint: worker-certificates
|
||||||
<<: *x-logging
|
<<: *x-logging
|
||||||
restart: unless-stopped
|
restart: unless-stopped
|
||||||
@@ -453,6 +454,8 @@ services:
|
|||||||
- _APP_DOMAIN_TARGET_CNAME
|
- _APP_DOMAIN_TARGET_CNAME
|
||||||
- _APP_DOMAIN_TARGET_AAAA
|
- _APP_DOMAIN_TARGET_AAAA
|
||||||
- _APP_DOMAIN_TARGET_A
|
- _APP_DOMAIN_TARGET_A
|
||||||
|
- _APP_DOMAIN_TARGET_CAA
|
||||||
|
- _APP_DNS
|
||||||
- _APP_DOMAIN_FUNCTIONS
|
- _APP_DOMAIN_FUNCTIONS
|
||||||
- _APP_EMAIL_CERTIFICATES
|
- _APP_EMAIL_CERTIFICATES
|
||||||
- _APP_REDIS_HOST
|
- _APP_REDIS_HOST
|
||||||
@@ -467,7 +470,7 @@ services:
|
|||||||
- _APP_LOGGING_CONFIG
|
- _APP_LOGGING_CONFIG
|
||||||
|
|
||||||
appwrite-worker-functions:
|
appwrite-worker-functions:
|
||||||
image: appwrite/appwrite:1.7.4
|
image: appwrite/appwrite:1.8.1
|
||||||
entrypoint: worker-functions
|
entrypoint: worker-functions
|
||||||
<<: *x-logging
|
<<: *x-logging
|
||||||
restart: unless-stopped
|
restart: unless-stopped
|
||||||
@@ -505,7 +508,7 @@ services:
|
|||||||
- _APP_LOGGING_CONFIG
|
- _APP_LOGGING_CONFIG
|
||||||
|
|
||||||
appwrite-worker-mails:
|
appwrite-worker-mails:
|
||||||
image: appwrite/appwrite:1.7.4
|
image: appwrite/appwrite:1.8.1
|
||||||
entrypoint: worker-mails
|
entrypoint: worker-mails
|
||||||
<<: *x-logging
|
<<: *x-logging
|
||||||
restart: unless-stopped
|
restart: unless-stopped
|
||||||
@@ -538,7 +541,7 @@ services:
|
|||||||
- _APP_OPTIONS_FORCE_HTTPS
|
- _APP_OPTIONS_FORCE_HTTPS
|
||||||
|
|
||||||
appwrite-worker-messaging:
|
appwrite-worker-messaging:
|
||||||
image: appwrite/appwrite:1.7.4
|
image: appwrite/appwrite:1.8.1
|
||||||
entrypoint: worker-messaging
|
entrypoint: worker-messaging
|
||||||
<<: *x-logging
|
<<: *x-logging
|
||||||
restart: unless-stopped
|
restart: unless-stopped
|
||||||
@@ -588,7 +591,7 @@ services:
|
|||||||
- _APP_STORAGE_WASABI_BUCKET
|
- _APP_STORAGE_WASABI_BUCKET
|
||||||
|
|
||||||
appwrite-worker-migrations:
|
appwrite-worker-migrations:
|
||||||
image: appwrite/appwrite:1.7.4
|
image: appwrite/appwrite:1.8.1
|
||||||
entrypoint: worker-migrations
|
entrypoint: worker-migrations
|
||||||
<<: *x-logging
|
<<: *x-logging
|
||||||
restart: unless-stopped
|
restart: unless-stopped
|
||||||
@@ -606,6 +609,8 @@ services:
|
|||||||
- _APP_DOMAIN_TARGET_CNAME
|
- _APP_DOMAIN_TARGET_CNAME
|
||||||
- _APP_DOMAIN_TARGET_AAAA
|
- _APP_DOMAIN_TARGET_AAAA
|
||||||
- _APP_DOMAIN_TARGET_A
|
- _APP_DOMAIN_TARGET_A
|
||||||
|
- _APP_DOMAIN_TARGET_CAA
|
||||||
|
- _APP_DNS
|
||||||
- _APP_EMAIL_SECURITY
|
- _APP_EMAIL_SECURITY
|
||||||
- _APP_REDIS_HOST
|
- _APP_REDIS_HOST
|
||||||
- _APP_REDIS_PORT
|
- _APP_REDIS_PORT
|
||||||
@@ -621,7 +626,7 @@ services:
|
|||||||
- _APP_MIGRATIONS_FIREBASE_CLIENT_SECRET
|
- _APP_MIGRATIONS_FIREBASE_CLIENT_SECRET
|
||||||
|
|
||||||
appwrite-task-maintenance:
|
appwrite-task-maintenance:
|
||||||
image: appwrite/appwrite:1.7.4
|
image: appwrite/appwrite:1.8.1
|
||||||
entrypoint: maintenance
|
entrypoint: maintenance
|
||||||
<<: *x-logging
|
<<: *x-logging
|
||||||
restart: unless-stopped
|
restart: unless-stopped
|
||||||
@@ -636,6 +641,8 @@ services:
|
|||||||
- _APP_DOMAIN_TARGET_CNAME
|
- _APP_DOMAIN_TARGET_CNAME
|
||||||
- _APP_DOMAIN_TARGET_AAAA
|
- _APP_DOMAIN_TARGET_AAAA
|
||||||
- _APP_DOMAIN_TARGET_A
|
- _APP_DOMAIN_TARGET_A
|
||||||
|
- _APP_DOMAIN_TARGET_CAA
|
||||||
|
- _APP_DNS
|
||||||
- _APP_DOMAIN_FUNCTIONS
|
- _APP_DOMAIN_FUNCTIONS
|
||||||
- _APP_OPENSSL_KEY_V1
|
- _APP_OPENSSL_KEY_V1
|
||||||
- _APP_REDIS_HOST
|
- _APP_REDIS_HOST
|
||||||
@@ -657,7 +664,7 @@ services:
|
|||||||
- _APP_MAINTENANCE_RETENTION_SCHEDULES
|
- _APP_MAINTENANCE_RETENTION_SCHEDULES
|
||||||
|
|
||||||
appwrite-task-stats-resources:
|
appwrite-task-stats-resources:
|
||||||
image: appwrite/appwrite:1.7.4
|
image: appwrite/appwrite:1.8.1
|
||||||
entrypoint: stats-resources
|
entrypoint: stats-resources
|
||||||
<<: *x-logging
|
<<: *x-logging
|
||||||
restart: unless-stopped
|
restart: unless-stopped
|
||||||
@@ -685,7 +692,7 @@ services:
|
|||||||
- _APP_STATS_RESOURCES_INTERVAL
|
- _APP_STATS_RESOURCES_INTERVAL
|
||||||
|
|
||||||
appwrite-worker-stats-resources:
|
appwrite-worker-stats-resources:
|
||||||
image: appwrite/appwrite:1.7.4
|
image: appwrite/appwrite:1.8.1
|
||||||
entrypoint: worker-stats-resources
|
entrypoint: worker-stats-resources
|
||||||
<<: *x-logging
|
<<: *x-logging
|
||||||
restart: unless-stopped
|
restart: unless-stopped
|
||||||
@@ -712,7 +719,7 @@ services:
|
|||||||
- _APP_STATS_RESOURCES_INTERVAL
|
- _APP_STATS_RESOURCES_INTERVAL
|
||||||
|
|
||||||
appwrite-worker-stats-usage:
|
appwrite-worker-stats-usage:
|
||||||
image: appwrite/appwrite:1.7.4
|
image: appwrite/appwrite:1.8.1
|
||||||
entrypoint: worker-stats-usage
|
entrypoint: worker-stats-usage
|
||||||
<<: *x-logging
|
<<: *x-logging
|
||||||
restart: unless-stopped
|
restart: unless-stopped
|
||||||
@@ -739,7 +746,7 @@ services:
|
|||||||
- _APP_USAGE_AGGREGATION_INTERVAL
|
- _APP_USAGE_AGGREGATION_INTERVAL
|
||||||
|
|
||||||
appwrite-task-scheduler-functions:
|
appwrite-task-scheduler-functions:
|
||||||
image: appwrite/appwrite:1.7.4
|
image: appwrite/appwrite:1.8.1
|
||||||
entrypoint: schedule-functions
|
entrypoint: schedule-functions
|
||||||
<<: *x-logging
|
<<: *x-logging
|
||||||
restart: unless-stopped
|
restart: unless-stopped
|
||||||
@@ -763,7 +770,7 @@ services:
|
|||||||
- _APP_DB_PASS
|
- _APP_DB_PASS
|
||||||
|
|
||||||
appwrite-task-scheduler-executions:
|
appwrite-task-scheduler-executions:
|
||||||
image: appwrite/appwrite:1.7.4
|
image: appwrite/appwrite:1.8.1
|
||||||
entrypoint: schedule-executions
|
entrypoint: schedule-executions
|
||||||
<<: *x-logging
|
<<: *x-logging
|
||||||
restart: unless-stopped
|
restart: unless-stopped
|
||||||
@@ -787,7 +794,7 @@ services:
|
|||||||
- _APP_DB_PASS
|
- _APP_DB_PASS
|
||||||
|
|
||||||
appwrite-task-scheduler-messages:
|
appwrite-task-scheduler-messages:
|
||||||
image: appwrite/appwrite:1.7.4
|
image: appwrite/appwrite:1.8.1
|
||||||
entrypoint: schedule-messages
|
entrypoint: schedule-messages
|
||||||
<<: *x-logging
|
<<: *x-logging
|
||||||
restart: unless-stopped
|
restart: unless-stopped
|
||||||
@@ -811,7 +818,7 @@ services:
|
|||||||
- _APP_DB_PASS
|
- _APP_DB_PASS
|
||||||
|
|
||||||
appwrite-assistant:
|
appwrite-assistant:
|
||||||
image: appwrite/assistant:0.4.0
|
image: appwrite/assistant:0.8.4
|
||||||
<<: *x-logging
|
<<: *x-logging
|
||||||
restart: unless-stopped
|
restart: unless-stopped
|
||||||
networks:
|
networks:
|
||||||
@@ -820,7 +827,7 @@ services:
|
|||||||
- _APP_ASSISTANT_OPENAI_API_KEY
|
- _APP_ASSISTANT_OPENAI_API_KEY
|
||||||
|
|
||||||
appwrite-browser:
|
appwrite-browser:
|
||||||
image: appwrite/browser:0.2.4
|
image: appwrite/browser:0.3.2
|
||||||
<<: *x-logging
|
<<: *x-logging
|
||||||
restart: unless-stopped
|
restart: unless-stopped
|
||||||
networks:
|
networks:
|
||||||
@@ -831,7 +838,7 @@ services:
|
|||||||
<<: *x-logging
|
<<: *x-logging
|
||||||
restart: unless-stopped
|
restart: unless-stopped
|
||||||
stop_signal: SIGINT
|
stop_signal: SIGINT
|
||||||
image: openruntimes/executor:0.7.14
|
image: openruntimes/executor:0.7.22
|
||||||
networks:
|
networks:
|
||||||
- appwrite
|
- appwrite
|
||||||
- runtimes
|
- runtimes
|
||||||
|
|||||||
@@ -11,3 +11,9 @@ await utils.downloadFile(
|
|||||||
|
|
||||||
await utils.removeContainerNames("./code/docker-compose.yml");
|
await utils.removeContainerNames("./code/docker-compose.yml");
|
||||||
await utils.removePorts("./code/docker-compose.yml");
|
await utils.removePorts("./code/docker-compose.yml");
|
||||||
|
|
||||||
|
await utils.searchReplace(
|
||||||
|
"./code/.env.example",
|
||||||
|
"_APP_DOMAIN=localhost",
|
||||||
|
"_APP_DOMAIN=$(PRIMARY_DOMAIN)"
|
||||||
|
);
|
||||||
|
|||||||
@@ -1,14 +0,0 @@
|
|||||||
#!/bin/bash
|
|
||||||
|
|
||||||
if [ ! -d "./repo" ]; then
|
|
||||||
git clone --depth 1 --branch main --single-branch https://github.com/appwrite/appwrite.git repo
|
|
||||||
else
|
|
||||||
cd repo
|
|
||||||
git pull
|
|
||||||
cd ..
|
|
||||||
fi
|
|
||||||
|
|
||||||
curl -s https://appwrite.io/install/compose > ./code/docker-compose.yml
|
|
||||||
curl -s https://appwrite.io/install/env > ./code/.env.example
|
|
||||||
|
|
||||||
|
|
||||||
+424
-41
@@ -24,6 +24,11 @@ CONSOLE_WEB_URL=
|
|||||||
# Example: https://api.dify.ai
|
# Example: https://api.dify.ai
|
||||||
SERVICE_API_URL=
|
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,
|
# WebApp API backend Url,
|
||||||
# used to declare the back-end URL for the front-end API.
|
# used to declare the back-end URL for the front-end API.
|
||||||
# If empty, it is the same domain.
|
# If empty, it is the same domain.
|
||||||
@@ -34,7 +39,7 @@ APP_API_URL=
|
|||||||
# used to display WebAPP API Base Url to the front-end.
|
# used to display WebAPP API Base Url to the front-end.
|
||||||
# If empty, it is the same domain.
|
# If empty, it is the same domain.
|
||||||
# Example: https://app.dify.ai
|
# Example: https://app.dify.ai
|
||||||
APP_WEB_URL=
|
APP_WEB_URL=https://$(PRIMARY_DOMAIN)
|
||||||
|
|
||||||
# File preview or download Url prefix.
|
# File preview or download Url prefix.
|
||||||
# used to display File preview or download Url to the front-end or as Multi-model inputs;
|
# used to display File preview or download Url to the front-end or as Multi-model inputs;
|
||||||
@@ -47,6 +52,16 @@ APP_WEB_URL=
|
|||||||
# ensuring port 5001 is externally accessible (see docker-compose.yaml).
|
# ensuring port 5001 is externally accessible (see docker-compose.yaml).
|
||||||
FILES_URL=
|
FILES_URL=
|
||||||
|
|
||||||
|
# INTERNAL_FILES_URL is used for plugin daemon communication within Docker network.
|
||||||
|
# Set this to the internal Docker service URL for proper plugin file access.
|
||||||
|
# Example: INTERNAL_FILES_URL=http://api:5001
|
||||||
|
INTERNAL_FILES_URL=
|
||||||
|
|
||||||
|
# Ensure UTF-8 encoding
|
||||||
|
LANG=C.UTF-8
|
||||||
|
LC_ALL=C.UTF-8
|
||||||
|
PYTHONIOENCODING=utf-8
|
||||||
|
|
||||||
# ------------------------------
|
# ------------------------------
|
||||||
# Server Configuration
|
# Server Configuration
|
||||||
# ------------------------------
|
# ------------------------------
|
||||||
@@ -54,6 +69,8 @@ FILES_URL=
|
|||||||
# The log level for the application.
|
# The log level for the application.
|
||||||
# Supported values are `DEBUG`, `INFO`, `WARNING`, `ERROR`, `CRITICAL`
|
# Supported values are `DEBUG`, `INFO`, `WARNING`, `ERROR`, `CRITICAL`
|
||||||
LOG_LEVEL=INFO
|
LOG_LEVEL=INFO
|
||||||
|
# Log output format: text or json
|
||||||
|
LOG_OUTPUT_FORMAT=text
|
||||||
# Log file path
|
# Log file path
|
||||||
LOG_FILE=/app/logs/server.log
|
LOG_FILE=/app/logs/server.log
|
||||||
# Log file max size, the unit is MB
|
# Log file max size, the unit is MB
|
||||||
@@ -81,7 +98,7 @@ ENABLE_REQUEST_LOGGING=False
|
|||||||
# A secret key that is used for securely signing the session cookie
|
# A secret key that is used for securely signing the session cookie
|
||||||
# and encrypting sensitive information on the database.
|
# and encrypting sensitive information on the database.
|
||||||
# You can generate a strong key using `openssl rand -base64 42`.
|
# You can generate a strong key using `openssl rand -base64 42`.
|
||||||
SECRET_KEY=sk-9f73s3ljTXVcMT3Blb3ljTqtsKiGHXVcMT3BlbkFJLK7U
|
SECRET_KEY=
|
||||||
|
|
||||||
# Password for admin user initialization.
|
# Password for admin user initialization.
|
||||||
# If left unset, admin user will not be prompted for a password
|
# If left unset, admin user will not be prompted for a password
|
||||||
@@ -118,6 +135,8 @@ ACCESS_TOKEN_EXPIRE_MINUTES=60
|
|||||||
# Refresh token expiration time in days
|
# Refresh token expiration time in days
|
||||||
REFRESH_TOKEN_EXPIRE_DAYS=30
|
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.
|
# 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_ACTIVE_REQUESTS=0
|
||||||
APP_MAX_EXECUTION_TIME=1200
|
APP_MAX_EXECUTION_TIME=1200
|
||||||
@@ -139,6 +158,12 @@ DIFY_PORT=5001
|
|||||||
SERVER_WORKER_AMOUNT=1
|
SERVER_WORKER_AMOUNT=1
|
||||||
|
|
||||||
# Defaults to gevent. If using windows, it can be switched to sync or solo.
|
# 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
|
SERVER_WORKER_CLASS=gevent
|
||||||
|
|
||||||
# Default number of worker connections, the default is 10.
|
# Default number of worker connections, the default is 10.
|
||||||
@@ -146,6 +171,12 @@ SERVER_WORKER_CONNECTIONS=10
|
|||||||
|
|
||||||
# Similar to SERVER_WORKER_CLASS.
|
# Similar to SERVER_WORKER_CLASS.
|
||||||
# If using windows, it can be switched to sync or solo.
|
# 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=
|
CELERY_WORKER_CLASS=
|
||||||
|
|
||||||
# Request handling timeout. The default is 200,
|
# Request handling timeout. The default is 200,
|
||||||
@@ -191,24 +222,42 @@ ENABLE_WEBSITE_JINAREADER=true
|
|||||||
ENABLE_WEBSITE_FIRECRAWL=true
|
ENABLE_WEBSITE_FIRECRAWL=true
|
||||||
ENABLE_WEBSITE_WATERCRAWL=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
|
# Database Configuration
|
||||||
# The database uses PostgreSQL. Please use the public schema.
|
# 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 'db' service below.
|
# 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_USERNAME=postgres
|
||||||
DB_PASSWORD=difyai123456
|
DB_PASSWORD=difyai123456
|
||||||
DB_HOST=db
|
DB_HOST=db_postgres
|
||||||
DB_PORT=5432
|
DB_PORT=5432
|
||||||
DB_DATABASE=dify
|
DB_DATABASE=dify
|
||||||
|
|
||||||
# The size of the database connection pool.
|
# The size of the database connection pool.
|
||||||
# The default is 30 connections, which can be appropriately increased.
|
# The default is 30 connections, which can be appropriately increased.
|
||||||
SQLALCHEMY_POOL_SIZE=30
|
SQLALCHEMY_POOL_SIZE=30
|
||||||
|
# The default is 10 connections, which allows temporary overflow beyond the pool size.
|
||||||
|
SQLALCHEMY_MAX_OVERFLOW=10
|
||||||
# Database connection pool recycling time, the default is 3600 seconds.
|
# Database connection pool recycling time, the default is 3600 seconds.
|
||||||
SQLALCHEMY_POOL_RECYCLE=3600
|
SQLALCHEMY_POOL_RECYCLE=3600
|
||||||
# Whether to print SQL, default is false.
|
# Whether to print SQL, default is false.
|
||||||
SQLALCHEMY_ECHO=false
|
SQLALCHEMY_ECHO=false
|
||||||
|
# If True, will test connections for liveness upon each checkout
|
||||||
|
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
|
# Maximum number of connections to the database
|
||||||
# Default is 100
|
# Default is 100
|
||||||
@@ -240,6 +289,43 @@ POSTGRES_MAINTENANCE_WORK_MEM=64MB
|
|||||||
# Reference: https://www.postgresql.org/docs/current/runtime-config-query.html#GUC-EFFECTIVE-CACHE-SIZE
|
# Reference: https://www.postgresql.org/docs/current/runtime-config-query.html#GUC-EFFECTIVE-CACHE-SIZE
|
||||||
POSTGRES_EFFECTIVE_CACHE_SIZE=4096MB
|
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
|
# Redis Configuration
|
||||||
# This Redis configuration is used for caching and for pub/sub during conversation.
|
# This Redis configuration is used for caching and for pub/sub during conversation.
|
||||||
@@ -250,6 +336,15 @@ REDIS_PORT=6379
|
|||||||
REDIS_USERNAME=
|
REDIS_USERNAME=
|
||||||
REDIS_PASSWORD=difyai123456
|
REDIS_PASSWORD=difyai123456
|
||||||
REDIS_USE_SSL=false
|
REDIS_USE_SSL=false
|
||||||
|
# SSL configuration for Redis (when REDIS_USE_SSL=true)
|
||||||
|
REDIS_SSL_CERT_REQS=CERT_NONE
|
||||||
|
# Options: CERT_NONE, CERT_OPTIONAL, CERT_REQUIRED
|
||||||
|
REDIS_SSL_CA_CERTS=
|
||||||
|
# Path to CA certificate file for SSL verification
|
||||||
|
REDIS_SSL_CERTFILE=
|
||||||
|
# Path to client certificate file for SSL authentication
|
||||||
|
REDIS_SSL_KEYFILE=
|
||||||
|
# Path to client private key file for SSL authentication
|
||||||
REDIS_DB=0
|
REDIS_DB=0
|
||||||
|
|
||||||
# Whether to use Redis Sentinel mode.
|
# Whether to use Redis Sentinel mode.
|
||||||
@@ -274,12 +369,14 @@ REDIS_CLUSTERS_PASSWORD=
|
|||||||
# Celery Configuration
|
# Celery Configuration
|
||||||
# ------------------------------
|
# ------------------------------
|
||||||
|
|
||||||
# Use redis as the broker, and redis db 1 for celery broker.
|
# 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>`
|
# Format as follows: `redis://<redis_username>:<redis_password>@<redis_host>:<redis_port>/<redis_database>`.
|
||||||
# Example: redis://:difyai123456@redis:6379/1
|
# Example: redis://:difyai123456@redis:6379/1
|
||||||
# If use Redis Sentinel, format as follows: `sentinel://<sentinel_username>:<sentinel_password>@<sentinel_host>:<sentinel_port>/<redis_database>`
|
# If use Redis Sentinel, format as follows: `sentinel://<redis_username>:<redis_password>@<sentinel_host1>:<sentinel_port>/<redis_database>`
|
||||||
# Example: sentinel://localhost:26379/1;sentinel://localhost:26380/1;sentinel://localhost:26381/1
|
# For high availability, you can configure multiple Sentinel nodes (if provided) separated by semicolons like below example:
|
||||||
|
# Example: sentinel://:difyai123456@localhost:26379/1;sentinel://:difyai12345@localhost:26379/1;sentinel://:difyai12345@localhost:26379/1
|
||||||
CELERY_BROKER_URL=redis://:difyai123456@redis:6379/1
|
CELERY_BROKER_URL=redis://:difyai123456@redis:6379/1
|
||||||
|
CELERY_BACKEND=redis
|
||||||
BROKER_USE_SSL=false
|
BROKER_USE_SSL=false
|
||||||
|
|
||||||
# If you are using Redis Sentinel for high availability, configure the following settings.
|
# If you are using Redis Sentinel for high availability, configure the following settings.
|
||||||
@@ -300,6 +397,11 @@ WEB_API_CORS_ALLOW_ORIGINS=*
|
|||||||
# Specifies the allowed origins for cross-origin requests to the console API,
|
# Specifies the allowed origins for cross-origin requests to the console API,
|
||||||
# e.g. https://cloud.dify.ai or * for all origins.
|
# e.g. https://cloud.dify.ai or * for all origins.
|
||||||
CONSOLE_CORS_ALLOW_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
|
# File Storage Configuration
|
||||||
@@ -317,6 +419,25 @@ OPENDAL_SCHEME=fs
|
|||||||
# Configurations for OpenDAL Local File System.
|
# Configurations for OpenDAL Local File System.
|
||||||
OPENDAL_FS_ROOT=storage
|
OPENDAL_FS_ROOT=storage
|
||||||
|
|
||||||
|
# ClickZetta Volume Configuration (for storage backend)
|
||||||
|
# To use ClickZetta Volume as storage backend, set STORAGE_TYPE=clickzetta-volume
|
||||||
|
# Note: ClickZetta Volume will reuse the existing CLICKZETTA_* connection parameters
|
||||||
|
|
||||||
|
# Volume type selection (three types available):
|
||||||
|
# - user: Personal/small team use, simple config, user-level permissions
|
||||||
|
# - table: Enterprise multi-tenant, smart routing, table-level + user-level permissions
|
||||||
|
# - external: Data lake integration, external storage connection, volume-level + storage-level permissions
|
||||||
|
CLICKZETTA_VOLUME_TYPE=user
|
||||||
|
|
||||||
|
# External Volume name (required only when TYPE=external)
|
||||||
|
CLICKZETTA_VOLUME_NAME=
|
||||||
|
|
||||||
|
# Table Volume table prefix (used only when TYPE=table)
|
||||||
|
CLICKZETTA_VOLUME_TABLE_PREFIX=dataset_
|
||||||
|
|
||||||
|
# Dify file directory prefix (isolates from other apps, recommended to keep default)
|
||||||
|
CLICKZETTA_VOLUME_DIFY_PREFIX=dify_km
|
||||||
|
|
||||||
# S3 Configuration
|
# S3 Configuration
|
||||||
#
|
#
|
||||||
S3_ENDPOINT=
|
S3_ENDPOINT=
|
||||||
@@ -328,6 +449,15 @@ S3_SECRET_KEY=
|
|||||||
# If set to false, the access key and secret key must be provided.
|
# If set to false, the access key and secret key must be provided.
|
||||||
S3_USE_AWS_MANAGED_IAM=false
|
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 Configuration
|
||||||
#
|
#
|
||||||
AZURE_BLOB_ACCOUNT_NAME=difyai
|
AZURE_BLOB_ACCOUNT_NAME=difyai
|
||||||
@@ -350,6 +480,7 @@ ALIYUN_OSS_REGION=ap-southeast-1
|
|||||||
ALIYUN_OSS_AUTH_VERSION=v4
|
ALIYUN_OSS_AUTH_VERSION=v4
|
||||||
# Don't start with '/'. OSS doesn't support leading slash in object names.
|
# Don't start with '/'. OSS doesn't support leading slash in object names.
|
||||||
ALIYUN_OSS_PATH=your-path
|
ALIYUN_OSS_PATH=your-path
|
||||||
|
ALIYUN_CLOUDBOX_ID=your-cloudbox-id
|
||||||
|
|
||||||
# Tencent COS Configuration
|
# Tencent COS Configuration
|
||||||
#
|
#
|
||||||
@@ -358,6 +489,7 @@ TENCENT_COS_SECRET_KEY=your-secret-key
|
|||||||
TENCENT_COS_SECRET_ID=your-secret-id
|
TENCENT_COS_SECRET_ID=your-secret-id
|
||||||
TENCENT_COS_REGION=your-region
|
TENCENT_COS_REGION=your-region
|
||||||
TENCENT_COS_SCHEME=your-scheme
|
TENCENT_COS_SCHEME=your-scheme
|
||||||
|
TENCENT_COS_CUSTOM_DOMAIN=your-custom-domain
|
||||||
|
|
||||||
# Oracle Storage Configuration
|
# Oracle Storage Configuration
|
||||||
#
|
#
|
||||||
@@ -373,6 +505,7 @@ HUAWEI_OBS_BUCKET_NAME=your-bucket-name
|
|||||||
HUAWEI_OBS_SECRET_KEY=your-secret-key
|
HUAWEI_OBS_SECRET_KEY=your-secret-key
|
||||||
HUAWEI_OBS_ACCESS_KEY=your-access-key
|
HUAWEI_OBS_ACCESS_KEY=your-access-key
|
||||||
HUAWEI_OBS_SERVER=your-server-url
|
HUAWEI_OBS_SERVER=your-server-url
|
||||||
|
HUAWEI_OBS_PATH_STYLE=false
|
||||||
|
|
||||||
# Volcengine TOS Configuration
|
# Volcengine TOS Configuration
|
||||||
#
|
#
|
||||||
@@ -400,12 +533,33 @@ SUPABASE_URL=your-server-url
|
|||||||
# ------------------------------
|
# ------------------------------
|
||||||
|
|
||||||
# The type of vector store to use.
|
# 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`.
|
# 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
|
VECTOR_STORE=weaviate
|
||||||
|
# Prefix used to create collection name in vector database
|
||||||
|
VECTOR_INDEX_NAME_PREFIX=Vector_index
|
||||||
|
|
||||||
# The Weaviate endpoint URL. Only available when VECTOR_STORE is `weaviate`.
|
# The Weaviate endpoint URL. Only available when VECTOR_STORE is `weaviate`.
|
||||||
WEAVIATE_ENDPOINT=http://weaviate:8080
|
WEAVIATE_ENDPOINT=http://weaviate:8080
|
||||||
WEAVIATE_API_KEY=WVF5YThaHlkYwhGUSmCRgsX3tD5ngdN8pkih
|
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`.
|
# The Qdrant endpoint URL. Only available when VECTOR_STORE is `qdrant`.
|
||||||
QDRANT_URL=http://qdrant:6333
|
QDRANT_URL=http://qdrant:6333
|
||||||
@@ -529,6 +683,15 @@ ORACLE_WALLET_LOCATION=/app/api/storage/wallet
|
|||||||
ORACLE_WALLET_PASSWORD=dify
|
ORACLE_WALLET_PASSWORD=dify
|
||||||
ORACLE_IS_AUTONOMOUS=false
|
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 configurations, only available when VECTOR_STORE is `relyt`
|
||||||
RELYT_HOST=db
|
RELYT_HOST=db
|
||||||
RELYT_PORT=5432
|
RELYT_PORT=5432
|
||||||
@@ -565,6 +728,17 @@ ELASTICSEARCH_USERNAME=elastic
|
|||||||
ELASTICSEARCH_PASSWORD=elastic
|
ELASTICSEARCH_PASSWORD=elastic
|
||||||
KIBANA_PORT=5601
|
KIBANA_PORT=5601
|
||||||
|
|
||||||
|
# Using ElasticSearch Cloud Serverless, or not.
|
||||||
|
ELASTICSEARCH_USE_CLOUD=false
|
||||||
|
ELASTICSEARCH_CLOUD_URL=YOUR-ELASTICSEARCH_CLOUD_URL
|
||||||
|
ELASTICSEARCH_API_KEY=YOUR-ELASTICSEARCH_API_KEY
|
||||||
|
|
||||||
|
ELASTICSEARCH_VERIFY_CERTS=False
|
||||||
|
ELASTICSEARCH_CA_CERTS=
|
||||||
|
ELASTICSEARCH_REQUEST_TIMEOUT=100000
|
||||||
|
ELASTICSEARCH_RETRY_ON_TIMEOUT=True
|
||||||
|
ELASTICSEARCH_MAX_RETRIES=10
|
||||||
|
|
||||||
# baidu vector configurations, only available when VECTOR_STORE is `baidu`
|
# baidu vector configurations, only available when VECTOR_STORE is `baidu`
|
||||||
BAIDU_VECTOR_DB_ENDPOINT=http://127.0.0.1:5287
|
BAIDU_VECTOR_DB_ENDPOINT=http://127.0.0.1:5287
|
||||||
BAIDU_VECTOR_DB_CONNECTION_TIMEOUT_MS=30000
|
BAIDU_VECTOR_DB_CONNECTION_TIMEOUT_MS=30000
|
||||||
@@ -573,6 +747,8 @@ BAIDU_VECTOR_DB_API_KEY=dify
|
|||||||
BAIDU_VECTOR_DB_DATABASE=dify
|
BAIDU_VECTOR_DB_DATABASE=dify
|
||||||
BAIDU_VECTOR_DB_SHARD=1
|
BAIDU_VECTOR_DB_SHARD=1
|
||||||
BAIDU_VECTOR_DB_REPLICAS=3
|
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 configurations, only available when VECTOR_STORE is `vikingdb`
|
||||||
VIKINGDB_ACCESS_KEY=your-ak
|
VIKINGDB_ACCESS_KEY=your-ak
|
||||||
@@ -584,21 +760,12 @@ VIKINGDB_CONNECTION_TIMEOUT=30
|
|||||||
VIKINGDB_SOCKET_TIMEOUT=30
|
VIKINGDB_SOCKET_TIMEOUT=30
|
||||||
|
|
||||||
# Lindorm configuration, only available when VECTOR_STORE is `lindorm`
|
# Lindorm configuration, only available when VECTOR_STORE is `lindorm`
|
||||||
LINDORM_URL=http://lindorm:30070
|
LINDORM_URL=http://localhost:30070
|
||||||
LINDORM_USERNAME=lindorm
|
LINDORM_USERNAME=admin
|
||||||
LINDORM_PASSWORD=lindorm
|
LINDORM_PASSWORD=admin
|
||||||
|
LINDORM_USING_UGC=True
|
||||||
LINDORM_QUERY_TIMEOUT=1
|
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 configurations, only available when VECTOR_STORE is `opengauss`
|
||||||
OPENGAUSS_HOST=opengauss
|
OPENGAUSS_HOST=opengauss
|
||||||
OPENGAUSS_PORT=6600
|
OPENGAUSS_PORT=6600
|
||||||
@@ -624,6 +791,36 @@ TABLESTORE_ENDPOINT=https://instance-name.cn-hangzhou.ots.aliyuncs.com
|
|||||||
TABLESTORE_INSTANCE_NAME=instance-name
|
TABLESTORE_INSTANCE_NAME=instance-name
|
||||||
TABLESTORE_ACCESS_KEY_ID=xxx
|
TABLESTORE_ACCESS_KEY_ID=xxx
|
||||||
TABLESTORE_ACCESS_KEY_SECRET=xxx
|
TABLESTORE_ACCESS_KEY_SECRET=xxx
|
||||||
|
TABLESTORE_NORMALIZE_FULLTEXT_BM25_SCORE=false
|
||||||
|
|
||||||
|
# Clickzetta configuration, only available when VECTOR_STORE is `clickzetta`
|
||||||
|
CLICKZETTA_USERNAME=
|
||||||
|
CLICKZETTA_PASSWORD=
|
||||||
|
CLICKZETTA_INSTANCE=
|
||||||
|
CLICKZETTA_SERVICE=api.clickzetta.com
|
||||||
|
CLICKZETTA_WORKSPACE=quick_start
|
||||||
|
CLICKZETTA_VCLUSTER=default_ap
|
||||||
|
CLICKZETTA_SCHEMA=dify
|
||||||
|
CLICKZETTA_BATCH_SIZE=100
|
||||||
|
CLICKZETTA_ENABLE_INVERTED_INDEX=true
|
||||||
|
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
|
# Knowledge Configuration
|
||||||
@@ -635,6 +832,25 @@ UPLOAD_FILE_SIZE_LIMIT=15
|
|||||||
# The maximum number of files that can be uploaded at a time, default 5.
|
# The maximum number of files that can be uploaded at a time, default 5.
|
||||||
UPLOAD_FILE_BATCH_LIMIT=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`
|
# ETL type, support: `dify`, `Unstructured`
|
||||||
# `dify` Dify's proprietary file extraction scheme
|
# `dify` Dify's proprietary file extraction scheme
|
||||||
# `Unstructured` Unstructured.io file extraction scheme
|
# `Unstructured` Unstructured.io file extraction scheme
|
||||||
@@ -705,6 +921,12 @@ API_SENTRY_PROFILES_SAMPLE_RATE=1.0
|
|||||||
# If not set, Sentry error reporting will be disabled.
|
# If not set, Sentry error reporting will be disabled.
|
||||||
WEB_SENTRY_DSN=
|
WEB_SENTRY_DSN=
|
||||||
|
|
||||||
|
# Plugin_daemon Service Sentry DSN address, default is empty, when empty,
|
||||||
|
# all monitoring information is not reported to Sentry.
|
||||||
|
# If not set, Sentry error reporting will be disabled.
|
||||||
|
PLUGIN_SENTRY_ENABLED=false
|
||||||
|
PLUGIN_SENTRY_DSN=
|
||||||
|
|
||||||
# ------------------------------
|
# ------------------------------
|
||||||
# Notion Integration Configuration
|
# Notion Integration Configuration
|
||||||
# Variables can be obtained by applying for Notion integration: https://www.notion.so/my-integrations
|
# Variables can be obtained by applying for Notion integration: https://www.notion.so/my-integrations
|
||||||
@@ -746,6 +968,8 @@ SMTP_USERNAME=
|
|||||||
SMTP_PASSWORD=
|
SMTP_PASSWORD=
|
||||||
SMTP_USE_TLS=true
|
SMTP_USE_TLS=true
|
||||||
SMTP_OPPORTUNISTIC_TLS=false
|
SMTP_OPPORTUNISTIC_TLS=false
|
||||||
|
# Optional: override the local hostname used for SMTP HELO/EHLO
|
||||||
|
SMTP_LOCAL_HOSTNAME=
|
||||||
|
|
||||||
# Sendgid configuration
|
# Sendgid configuration
|
||||||
SENDGRID_API_KEY=
|
SENDGRID_API_KEY=
|
||||||
@@ -763,42 +987,135 @@ INVITE_EXPIRY_HOURS=72
|
|||||||
|
|
||||||
# Reset password token valid time (minutes),
|
# Reset password token valid time (minutes),
|
||||||
RESET_PASSWORD_TOKEN_EXPIRY_MINUTES=5
|
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.
|
# The sandbox service endpoint.
|
||||||
CODE_EXECUTION_ENDPOINT=http://sandbox:8194
|
CODE_EXECUTION_ENDPOINT=http://sandbox:8194
|
||||||
CODE_EXECUTION_API_KEY=dify-sandbox
|
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_MAX_NUMBER=9223372036854775807
|
||||||
CODE_MIN_NUMBER=-9223372036854775808
|
CODE_MIN_NUMBER=-9223372036854775808
|
||||||
CODE_MAX_DEPTH=5
|
CODE_MAX_DEPTH=5
|
||||||
CODE_MAX_PRECISION=20
|
CODE_MAX_PRECISION=20
|
||||||
CODE_MAX_STRING_LENGTH=80000
|
CODE_MAX_STRING_LENGTH=400000
|
||||||
CODE_MAX_STRING_ARRAY_LENGTH=30
|
CODE_MAX_STRING_ARRAY_LENGTH=30
|
||||||
CODE_MAX_OBJECT_ARRAY_LENGTH=30
|
CODE_MAX_OBJECT_ARRAY_LENGTH=30
|
||||||
CODE_MAX_NUMBER_ARRAY_LENGTH=1000
|
CODE_MAX_NUMBER_ARRAY_LENGTH=1000
|
||||||
CODE_EXECUTION_CONNECT_TIMEOUT=10
|
CODE_EXECUTION_CONNECT_TIMEOUT=10
|
||||||
CODE_EXECUTION_READ_TIMEOUT=60
|
CODE_EXECUTION_READ_TIMEOUT=60
|
||||||
CODE_EXECUTION_WRITE_TIMEOUT=10
|
CODE_EXECUTION_WRITE_TIMEOUT=10
|
||||||
TEMPLATE_TRANSFORM_MAX_LENGTH=80000
|
TEMPLATE_TRANSFORM_MAX_LENGTH=400000
|
||||||
|
|
||||||
# Workflow runtime configuration
|
# Workflow runtime configuration
|
||||||
WORKFLOW_MAX_EXECUTION_STEPS=500
|
WORKFLOW_MAX_EXECUTION_STEPS=500
|
||||||
WORKFLOW_MAX_EXECUTION_TIME=1200
|
WORKFLOW_MAX_EXECUTION_TIME=1200
|
||||||
WORKFLOW_CALL_MAX_DEPTH=5
|
WORKFLOW_CALL_MAX_DEPTH=5
|
||||||
MAX_VARIABLE_SIZE=204800
|
MAX_VARIABLE_SIZE=204800
|
||||||
WORKFLOW_PARALLEL_DEPTH_LIMIT=3
|
|
||||||
WORKFLOW_FILE_UPLOAD_LIMIT=10
|
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
|
# Workflow storage configuration
|
||||||
# Options: rdbms, hybrid
|
# Options: rdbms, hybrid
|
||||||
# rdbms: Use only the relational database (default)
|
# rdbms: Use only the relational database (default)
|
||||||
# hybrid: Save new data to object storage, read from both object storage and RDBMS
|
# hybrid: Save new data to object storage, read from both object storage and RDBMS
|
||||||
WORKFLOW_NODE_EXECUTION_STORAGE=rdbms
|
WORKFLOW_NODE_EXECUTION_STORAGE=rdbms
|
||||||
|
|
||||||
|
# Repository configuration
|
||||||
|
# Core workflow execution repository implementation
|
||||||
|
# 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
|
||||||
|
# Enable automatic cleanup of workflow run logs to manage database size
|
||||||
|
WORKFLOW_LOG_CLEANUP_ENABLED=false
|
||||||
|
# Number of days to retain workflow run logs (default: 30 days)
|
||||||
|
WORKFLOW_LOG_RETENTION_DAYS=30
|
||||||
|
# Batch size for workflow log cleanup operations (default: 100)
|
||||||
|
WORKFLOW_LOG_CLEANUP_BATCH_SIZE=100
|
||||||
|
|
||||||
|
# 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 in workflow configuration
|
||||||
HTTP_REQUEST_NODE_MAX_BINARY_SIZE=10485760
|
HTTP_REQUEST_NODE_MAX_BINARY_SIZE=10485760
|
||||||
HTTP_REQUEST_NODE_MAX_TEXT_SIZE=1048576
|
HTTP_REQUEST_NODE_MAX_TEXT_SIZE=1048576
|
||||||
HTTP_REQUEST_NODE_SSL_VERIFY=True
|
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 X-* headers to redirect clients
|
||||||
RESPECT_XFORWARD_HEADERS_ENABLED=false
|
RESPECT_XFORWARD_HEADERS_ENABLED=false
|
||||||
|
|
||||||
@@ -826,19 +1143,21 @@ MAX_ITERATIONS_NUM=99
|
|||||||
# The timeout for the text generation in millisecond
|
# The timeout for the text generation in millisecond
|
||||||
TEXT_GENERATION_TIMEOUT_MS=60000
|
TEXT_GENERATION_TIMEOUT_MS=60000
|
||||||
|
|
||||||
# ------------------------------
|
# Allow rendering unsafe URLs which have "data:" scheme.
|
||||||
# Environment Variables for db Service
|
ALLOW_UNSAFE_DATA_SCHEME=false
|
||||||
# ------------------------------
|
|
||||||
|
|
||||||
# The name of the default postgres user.
|
# Maximum number of tree depth in the workflow
|
||||||
POSTGRES_USER=${DB_USERNAME}
|
MAX_TREE_DEPTH=50
|
||||||
# The password for the default postgres user.
|
|
||||||
POSTGRES_PASSWORD=${DB_PASSWORD}
|
# ------------------------------
|
||||||
# The name of the default postgres database.
|
# Environment Variables for database Service
|
||||||
POSTGRES_DB=${DB_DATABASE}
|
# ------------------------------
|
||||||
# postgres data directory
|
# Postgres data directory
|
||||||
PGDATA=/var/lib/postgresql/data/pgdata
|
PGDATA=/var/lib/postgresql/data/pgdata
|
||||||
|
|
||||||
|
# MySQL Default Configuration
|
||||||
|
MYSQL_HOST_VOLUME=./volumes/mysql/data
|
||||||
|
|
||||||
# ------------------------------
|
# ------------------------------
|
||||||
# Environment Variables for sandbox Service
|
# Environment Variables for sandbox Service
|
||||||
# ------------------------------
|
# ------------------------------
|
||||||
@@ -872,6 +1191,10 @@ WEAVIATE_AUTHENTICATION_APIKEY_ALLOWED_KEYS=WVF5YThaHlkYwhGUSmCRgsX3tD5ngdN8pkih
|
|||||||
WEAVIATE_AUTHENTICATION_APIKEY_USERS=hello@dify.ai
|
WEAVIATE_AUTHENTICATION_APIKEY_USERS=hello@dify.ai
|
||||||
WEAVIATE_AUTHORIZATION_ADMINLIST_ENABLED=true
|
WEAVIATE_AUTHORIZATION_ADMINLIST_ENABLED=true
|
||||||
WEAVIATE_AUTHORIZATION_ADMINLIST_USERS=hello@dify.ai
|
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
|
# Environment Variables for Chroma
|
||||||
@@ -954,11 +1277,11 @@ NGINX_SSL_PORT=443
|
|||||||
# and modify the env vars below accordingly.
|
# and modify the env vars below accordingly.
|
||||||
NGINX_SSL_CERT_FILENAME=dify.crt
|
NGINX_SSL_CERT_FILENAME=dify.crt
|
||||||
NGINX_SSL_CERT_KEY_FILENAME=dify.key
|
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 performance tuning
|
||||||
NGINX_WORKER_PROCESSES=auto
|
NGINX_WORKER_PROCESSES=auto
|
||||||
NGINX_CLIENT_MAX_BODY_SIZE=15M
|
NGINX_CLIENT_MAX_BODY_SIZE=100M
|
||||||
NGINX_KEEPALIVE_TIMEOUT=65
|
NGINX_KEEPALIVE_TIMEOUT=65
|
||||||
|
|
||||||
# Proxy settings
|
# Proxy settings
|
||||||
@@ -993,14 +1316,17 @@ SSRF_DEFAULT_TIME_OUT=5
|
|||||||
SSRF_DEFAULT_CONNECT_TIME_OUT=5
|
SSRF_DEFAULT_CONNECT_TIME_OUT=5
|
||||||
SSRF_DEFAULT_READ_TIME_OUT=5
|
SSRF_DEFAULT_READ_TIME_OUT=5
|
||||||
SSRF_DEFAULT_WRITE_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
|
# docker env var for specifying vector db and metadata db type at startup
|
||||||
# (based on the vector db type, the corresponding docker
|
# (based on the vector db and metadata db type, the corresponding docker
|
||||||
# compose profile will be used)
|
# compose profile will be used)
|
||||||
# if you want to use unstructured, add ',unstructured' to the end
|
# 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
|
# Docker Compose Service Expose Host Port Configurations
|
||||||
@@ -1066,9 +1392,16 @@ MARKETPLACE_ENABLED=true
|
|||||||
MARKETPLACE_API_URL=https://marketplace.dify.ai
|
MARKETPLACE_API_URL=https://marketplace.dify.ai
|
||||||
|
|
||||||
FORCE_VERIFYING_SIGNATURE=true
|
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_PYTHON_ENV_INIT_TIMEOUT=120
|
||||||
|
# Plugin Daemon side timeout (configure to match the API side below)
|
||||||
PLUGIN_MAX_EXECUTION_TIMEOUT=600
|
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=https://pypi.tuna.tsinghua.edu.cn/simple
|
||||||
PIP_MIRROR_URL=
|
PIP_MIRROR_URL=
|
||||||
|
|
||||||
@@ -1114,6 +1447,8 @@ PLUGIN_VOLCENGINE_TOS_REGION=
|
|||||||
# OTLP Collector Configuration
|
# OTLP Collector Configuration
|
||||||
# ------------------------------
|
# ------------------------------
|
||||||
ENABLE_OTEL=false
|
ENABLE_OTEL=false
|
||||||
|
OTLP_TRACE_ENDPOINT=
|
||||||
|
OTLP_METRIC_ENDPOINT=
|
||||||
OTLP_BASE_ENDPOINT=http://localhost:4318
|
OTLP_BASE_ENDPOINT=http://localhost:4318
|
||||||
OTLP_API_KEY=
|
OTLP_API_KEY=
|
||||||
OTEL_EXPORTER_OTLP_PROTOCOL=
|
OTEL_EXPORTER_OTLP_PROTOCOL=
|
||||||
@@ -1135,3 +1470,51 @@ QUEUE_MONITOR_THRESHOLD=200
|
|||||||
QUEUE_MONITOR_ALERT_EMAILS=
|
QUEUE_MONITOR_ALERT_EMAILS=
|
||||||
# Monitor interval in minutes, default is 30 minutes
|
# Monitor interval in minutes, default is 30 minutes
|
||||||
QUEUE_MONITOR_INTERVAL=30
|
QUEUE_MONITOR_INTERVAL=30
|
||||||
|
|
||||||
|
# Swagger UI configuration
|
||||||
|
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_RETENTION_DAYS=30
|
||||||
|
|||||||
+103
-45
@@ -4,7 +4,7 @@ Welcome to the new `docker` directory for deploying Dify using Docker Compose. T
|
|||||||
|
|
||||||
### What's Updated
|
### What's Updated
|
||||||
|
|
||||||
- **Certbot Container**: `docker-compose.yaml` now contains `certbot` for managing SSL certificates. This container automatically renews certificates and ensures secure HTTPS connections.
|
- **Certbot Container**: `docker-compose.yaml` now contains `certbot` for managing SSL certificates. This container automatically renews certificates and ensures secure HTTPS connections.\
|
||||||
For more information, refer `docker/certbot/README.md`.
|
For more information, refer `docker/certbot/README.md`.
|
||||||
|
|
||||||
- **Persistent Environment Variables**: Environment variables are now managed through a `.env` file, ensuring that your configurations persist across deployments.
|
- **Persistent Environment Variables**: Environment variables are now managed through a `.env` file, ensuring that your configurations persist across deployments.
|
||||||
@@ -13,43 +13,50 @@ Welcome to the new `docker` directory for deploying Dify using Docker Compose. T
|
|||||||
> The `.env` file is a crucial component in Docker and Docker Compose environments, serving as a centralized configuration file where you can define environment variables that are accessible to the containers at runtime. This file simplifies the management of environment settings across different stages of development, testing, and production, providing consistency and ease of configuration to deployments.
|
> The `.env` file is a crucial component in Docker and Docker Compose environments, serving as a centralized configuration file where you can define environment variables that are accessible to the containers at runtime. This file simplifies the management of environment settings across different stages of development, testing, and production, providing consistency and ease of configuration to deployments.
|
||||||
|
|
||||||
- **Unified Vector Database Services**: All vector database services are now managed from a single Docker Compose file `docker-compose.yaml`. You can switch between different vector databases by setting the `VECTOR_STORE` environment variable in your `.env` file.
|
- **Unified Vector Database Services**: All vector database services are now managed from a single Docker Compose file `docker-compose.yaml`. You can switch between different vector databases by setting the `VECTOR_STORE` environment variable in your `.env` file.
|
||||||
|
|
||||||
- **Mandatory .env File**: A `.env` file is now required to run `docker compose up`. This file is crucial for configuring your deployment and for any custom settings to persist through upgrades.
|
- **Mandatory .env File**: A `.env` file is now required to run `docker compose up`. This file is crucial for configuring your deployment and for any custom settings to persist through upgrades.
|
||||||
|
|
||||||
### How to Deploy Dify with `docker-compose.yaml`
|
### How to Deploy Dify with `docker-compose.yaml`
|
||||||
|
|
||||||
1. **Prerequisites**: Ensure Docker and Docker Compose are installed on your system.
|
1. **Prerequisites**: Ensure Docker and Docker Compose are installed on your system.
|
||||||
2. **Environment Setup**:
|
1. **Environment Setup**:
|
||||||
- Navigate to the `docker` directory.
|
- Navigate to the `docker` directory.
|
||||||
- Copy the `.env.example` file to a new file named `.env` by running `cp .env.example .env`.
|
- 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.
|
- Customize the `.env` file as needed. Refer to the `.env.example` file for detailed configuration options.
|
||||||
3. **Running the Services**:
|
- **Optional (Recommended for upgrades)**:
|
||||||
- Execute `docker compose up` from the `docker` directory to start the services.
|
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.
|
||||||
- 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`.
|
This is especially useful when upgrading Dify or managing a large, customized `.env` file.
|
||||||
4. **SSL Certificate Setup**:
|
See the [Environment Variables Synchronization](#environment-variables-synchronization) section below.
|
||||||
- Refer `docker/certbot/README.md` to set up SSL certificates using Certbot.
|
1. **Running the Services**:
|
||||||
5. **OpenTelemetry Collector Setup**:
|
- 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`.
|
||||||
|
1. **SSL Certificate Setup**:
|
||||||
|
- Refer `docker/certbot/README.md` to set up SSL certificates using Certbot.
|
||||||
|
1. **OpenTelemetry Collector Setup**:
|
||||||
- Change `ENABLE_OTEL` to `true` in `.env`.
|
- Change `ENABLE_OTEL` to `true` in `.env`.
|
||||||
- Configure `OTLP_BASE_ENDPOINT` properly.
|
- Configure `OTLP_BASE_ENDPOINT` properly.
|
||||||
|
|
||||||
### How to Deploy Middleware for Developing Dify
|
### How to Deploy Middleware for Developing Dify
|
||||||
|
|
||||||
1. **Middleware Setup**:
|
1. **Middleware Setup**:
|
||||||
- Use the `docker-compose.middleware.yaml` for setting up essential middleware services like databases and caches.
|
- Use the `docker-compose.middleware.yaml` for setting up essential middleware services like databases and caches.
|
||||||
- Navigate to the `docker` directory.
|
- Navigate to the `docker` directory.
|
||||||
- Ensure the `middleware.env` file is created by running `cp middleware.env.example middleware.env` (refer to the `middleware.env.example` file).
|
- Ensure the `middleware.env` file is created by running `cp middleware.env.example middleware.env` (refer to the `middleware.env.example` file).
|
||||||
2. **Running Middleware Services**:
|
1. **Running Middleware Services**:
|
||||||
- Navigate to the `docker` directory.
|
- 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
|
### Migration for Existing Users
|
||||||
|
|
||||||
For users migrating from the `docker-legacy` setup:
|
For users migrating from the `docker-legacy` setup:
|
||||||
|
|
||||||
1. **Review Changes**: Familiarize yourself with the new `.env` configuration and Docker Compose setup.
|
1. **Review Changes**: Familiarize yourself with the new `.env` configuration and Docker Compose setup.
|
||||||
2. **Transfer Customizations**:
|
1. **Transfer Customizations**:
|
||||||
- If you have customized configurations such as `docker-compose.yaml`, `ssrf_proxy/squid.conf`, or `nginx/conf.d/default.conf`, you will need to reflect these changes in the `.env` file you create.
|
- If you have customized configurations such as `docker-compose.yaml`, `ssrf_proxy/squid.conf`, or `nginx/conf.d/default.conf`, you will need to reflect these changes in the `.env` file you create.
|
||||||
3. **Data Migration**:
|
1. **Data Migration**:
|
||||||
- Ensure that data from services like databases and caches is backed up and migrated appropriately to the new structure if necessary.
|
- Ensure that data from services like databases and caches is backed up and migrated appropriately to the new structure if necessary.
|
||||||
|
|
||||||
### Overview of `.env`
|
### Overview of `.env`
|
||||||
|
|
||||||
@@ -64,39 +71,90 @@ For users migrating from the `docker-legacy` setup:
|
|||||||
The `.env.example` file provided in the Docker setup is extensive and covers a wide range of configuration options. It is structured into several sections, each pertaining to different aspects of the application and its services. Here are some of the key sections and variables:
|
The `.env.example` file provided in the Docker setup is extensive and covers a wide range of configuration options. It is structured into several sections, each pertaining to different aspects of the application and its services. Here are some of the key sections and variables:
|
||||||
|
|
||||||
1. **Common Variables**:
|
1. **Common Variables**:
|
||||||
- `CONSOLE_API_URL`, `SERVICE_API_URL`: URLs for different API services.
|
|
||||||
- `APP_WEB_URL`: Frontend application URL.
|
|
||||||
- `FILES_URL`: Base URL for file downloads and previews.
|
|
||||||
|
|
||||||
2. **Server Configuration**:
|
- `CONSOLE_API_URL`, `SERVICE_API_URL`: URLs for different API services.
|
||||||
- `LOG_LEVEL`, `DEBUG`, `FLASK_DEBUG`: Logging and debug settings.
|
- `APP_WEB_URL`: Frontend application URL.
|
||||||
- `SECRET_KEY`: A key for encrypting session cookies and other sensitive data.
|
- `FILES_URL`: Base URL for file downloads and previews.
|
||||||
|
|
||||||
3. **Database Configuration**:
|
1. **Server Configuration**:
|
||||||
- `DB_USERNAME`, `DB_PASSWORD`, `DB_HOST`, `DB_PORT`, `DB_DATABASE`: PostgreSQL database credentials and connection details.
|
|
||||||
|
|
||||||
4. **Redis Configuration**:
|
- `LOG_LEVEL`, `DEBUG`, `FLASK_DEBUG`: Logging and debug settings.
|
||||||
- `REDIS_HOST`, `REDIS_PORT`, `REDIS_PASSWORD`: Redis server connection settings.
|
- `SECRET_KEY`: A key for encrypting session cookies and other sensitive data.
|
||||||
|
|
||||||
5. **Celery Configuration**:
|
1. **Database Configuration**:
|
||||||
- `CELERY_BROKER_URL`: Configuration for Celery message broker.
|
|
||||||
|
|
||||||
6. **Storage Configuration**:
|
- `DB_USERNAME`, `DB_PASSWORD`, `DB_HOST`, `DB_PORT`, `DB_DATABASE`: PostgreSQL database credentials and connection details.
|
||||||
- `STORAGE_TYPE`, `S3_BUCKET_NAME`, `AZURE_BLOB_ACCOUNT_NAME`: Settings for file storage options like local, S3, Azure Blob, etc.
|
|
||||||
|
|
||||||
7. **Vector Database Configuration**:
|
1. **Redis Configuration**:
|
||||||
- `VECTOR_STORE`: Type of vector database (e.g., `weaviate`, `milvus`).
|
|
||||||
- Specific settings for each vector store like `WEAVIATE_ENDPOINT`, `MILVUS_URI`.
|
|
||||||
|
|
||||||
8. **CORS Configuration**:
|
- `REDIS_HOST`, `REDIS_PORT`, `REDIS_PASSWORD`: Redis server connection settings.
|
||||||
- `WEB_API_CORS_ALLOW_ORIGINS`, `CONSOLE_CORS_ALLOW_ORIGINS`: Settings for cross-origin resource sharing.
|
|
||||||
|
|
||||||
9. **OpenTelemetry Configuration**:
|
1. **Celery Configuration**:
|
||||||
- `ENABLE_OTEL`: Enable OpenTelemetry collector in api.
|
|
||||||
- `OTLP_BASE_ENDPOINT`: Endpoint for your OTLP exporter.
|
|
||||||
|
|
||||||
10. **Other Service-Specific Environment Variables**:
|
- `CELERY_BROKER_URL`: Configuration for Celery message broker.
|
||||||
- Each service like `nginx`, `redis`, `db`, and vector databases have specific environment variables that are directly referenced in the `docker-compose.yaml`.
|
|
||||||
|
1. **Storage Configuration**:
|
||||||
|
|
||||||
|
- `STORAGE_TYPE`, `S3_BUCKET_NAME`, `AZURE_BLOB_ACCOUNT_NAME`: Settings for file storage options like local, S3, Azure Blob, etc.
|
||||||
|
|
||||||
|
1. **Vector Database Configuration**:
|
||||||
|
|
||||||
|
- `VECTOR_STORE`: Type of vector database (e.g., `weaviate`, `milvus`).
|
||||||
|
- Specific settings for each vector store like `WEAVIATE_ENDPOINT`, `MILVUS_URI`.
|
||||||
|
|
||||||
|
1. **CORS Configuration**:
|
||||||
|
|
||||||
|
- `WEB_API_CORS_ALLOW_ORIGINS`, `CONSOLE_CORS_ALLOW_ORIGINS`: Settings for cross-origin resource sharing.
|
||||||
|
|
||||||
|
1. **OpenTelemetry Configuration**:
|
||||||
|
|
||||||
|
- `ENABLE_OTEL`: Enable OpenTelemetry collector in api.
|
||||||
|
- `OTLP_BASE_ENDPOINT`: Endpoint for your OTLP exporter.
|
||||||
|
|
||||||
|
1. **Other Service-Specific Environment Variables**:
|
||||||
|
|
||||||
|
- 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
|
### Additional Information
|
||||||
|
|
||||||
|
|||||||
@@ -2,12 +2,12 @@
|
|||||||
|
|
||||||
## Short description
|
## Short description
|
||||||
|
|
||||||
docker compose certbot configurations with Backward compatibility (without certbot container).
|
docker compose certbot configurations with Backward compatibility (without certbot container).\
|
||||||
Use `docker compose --profile certbot up` to use this features.
|
Use `docker compose --profile certbot up` to use this features.
|
||||||
|
|
||||||
## The simplest way for launching new servers with SSL certificates
|
## The simplest way for launching new servers with SSL certificates
|
||||||
|
|
||||||
1. Get letsencrypt certs
|
1. Get letsencrypt certs\
|
||||||
set `.env` values
|
set `.env` values
|
||||||
```properties
|
```properties
|
||||||
NGINX_SSL_CERT_FILENAME=fullchain.pem
|
NGINX_SSL_CERT_FILENAME=fullchain.pem
|
||||||
@@ -25,7 +25,7 @@ Use `docker compose --profile certbot up` to use this features.
|
|||||||
```shell
|
```shell
|
||||||
docker compose exec -it certbot /bin/sh /update-cert.sh
|
docker compose exec -it certbot /bin/sh /update-cert.sh
|
||||||
```
|
```
|
||||||
2. Edit `.env` file and `docker compose --profile certbot up` again.
|
1. Edit `.env` file and `docker compose --profile certbot up` again.\
|
||||||
set `.env` value additionally
|
set `.env` value additionally
|
||||||
```properties
|
```properties
|
||||||
NGINX_HTTPS_ENABLED=true
|
NGINX_HTTPS_ENABLED=true
|
||||||
@@ -34,7 +34,7 @@ Use `docker compose --profile certbot up` to use this features.
|
|||||||
```shell
|
```shell
|
||||||
docker compose --profile certbot up -d --no-deps --force-recreate nginx
|
docker compose --profile certbot up -d --no-deps --force-recreate nginx
|
||||||
```
|
```
|
||||||
Then you can access your serve with HTTPS.
|
Then you can access your serve with HTTPS.\
|
||||||
[https://your_domain.com](https://your_domain.com)
|
[https://your_domain.com](https://your_domain.com)
|
||||||
|
|
||||||
## SSL certificates renewal
|
## SSL certificates renewal
|
||||||
|
|||||||
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
|
x-shared-env: &shared-api-worker-env
|
||||||
services:
|
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 service
|
||||||
api:
|
api:
|
||||||
image: langgenius/dify-api:1.5.1
|
image: langgenius/dify-api:1.11.4
|
||||||
restart: always
|
restart: always
|
||||||
environment:
|
environment:
|
||||||
# Use the shared environment variables.
|
# Use the shared environment variables.
|
||||||
@@ -15,10 +34,23 @@ services:
|
|||||||
PLUGIN_REMOTE_INSTALL_HOST: ${EXPOSE_PLUGIN_DEBUGGING_HOST:-localhost}
|
PLUGIN_REMOTE_INSTALL_HOST: ${EXPOSE_PLUGIN_DEBUGGING_HOST:-localhost}
|
||||||
PLUGIN_REMOTE_INSTALL_PORT: ${EXPOSE_PLUGIN_DEBUGGING_PORT:-5003}
|
PLUGIN_REMOTE_INSTALL_PORT: ${EXPOSE_PLUGIN_DEBUGGING_PORT:-5003}
|
||||||
PLUGIN_MAX_PACKAGE_SIZE: ${PLUGIN_MAX_PACKAGE_SIZE:-52428800}
|
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}
|
INNER_API_KEY_FOR_PLUGIN: ${PLUGIN_DIFY_INNER_API_KEY:-QaHbTe77CtuXmsfyhR7+vRjI/+XbV1AaFy691iy+kGDv2Jvy0/eAh8Y1}
|
||||||
depends_on:
|
depends_on:
|
||||||
db:
|
init_permissions:
|
||||||
|
condition: service_completed_successfully
|
||||||
|
db_postgres:
|
||||||
condition: service_healthy
|
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:
|
redis:
|
||||||
condition: service_started
|
condition: service_started
|
||||||
volumes:
|
volumes:
|
||||||
@@ -29,14 +61,14 @@ services:
|
|||||||
- default
|
- default
|
||||||
|
|
||||||
# worker service
|
# worker service
|
||||||
# The Celery worker for processing the queue.
|
# The Celery worker for processing all queues (dataset, workflow, mail, etc.)
|
||||||
worker:
|
worker:
|
||||||
image: langgenius/dify-api:1.5.1
|
image: langgenius/dify-api:1.11.4
|
||||||
restart: always
|
restart: always
|
||||||
environment:
|
environment:
|
||||||
# Use the shared environment variables.
|
# Use the shared environment variables.
|
||||||
<<: *shared-api-worker-env
|
<<: *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
|
MODE: worker
|
||||||
SENTRY_DSN: ${API_SENTRY_DSN:-}
|
SENTRY_DSN: ${API_SENTRY_DSN:-}
|
||||||
SENTRY_TRACES_SAMPLE_RATE: ${API_SENTRY_TRACES_SAMPLE_RATE:-1.0}
|
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}
|
PLUGIN_MAX_PACKAGE_SIZE: ${PLUGIN_MAX_PACKAGE_SIZE:-52428800}
|
||||||
INNER_API_KEY_FOR_PLUGIN: ${PLUGIN_DIFY_INNER_API_KEY:-QaHbTe77CtuXmsfyhR7+vRjI/+XbV1AaFy691iy+kGDv2Jvy0/eAh8Y1}
|
INNER_API_KEY_FOR_PLUGIN: ${PLUGIN_DIFY_INNER_API_KEY:-QaHbTe77CtuXmsfyhR7+vRjI/+XbV1AaFy691iy+kGDv2Jvy0/eAh8Y1}
|
||||||
depends_on:
|
depends_on:
|
||||||
db:
|
init_permissions:
|
||||||
|
condition: service_completed_successfully
|
||||||
|
db_postgres:
|
||||||
condition: service_healthy
|
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:
|
redis:
|
||||||
condition: service_started
|
condition: service_started
|
||||||
volumes:
|
volumes:
|
||||||
@@ -55,18 +99,52 @@ services:
|
|||||||
- ssrf_proxy_network
|
- ssrf_proxy_network
|
||||||
- default
|
- default
|
||||||
|
|
||||||
|
# worker_beat service
|
||||||
|
# Celery beat for scheduling periodic tasks.
|
||||||
|
worker_beat:
|
||||||
|
image: langgenius/dify-api:1.11.4
|
||||||
|
restart: always
|
||||||
|
environment:
|
||||||
|
# Use the shared environment variables.
|
||||||
|
<<: *shared-api-worker-env
|
||||||
|
# Startup mode, 'worker_beat' starts the Celery beat for scheduling periodic tasks.
|
||||||
|
MODE: beat
|
||||||
|
depends_on:
|
||||||
|
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:
|
||||||
|
- ssrf_proxy_network
|
||||||
|
- default
|
||||||
|
|
||||||
# Frontend web application.
|
# Frontend web application.
|
||||||
web:
|
web:
|
||||||
image: langgenius/dify-web:1.5.1
|
image: langgenius/dify-web:1.11.4
|
||||||
restart: always
|
restart: always
|
||||||
environment:
|
environment:
|
||||||
CONSOLE_API_URL: ${CONSOLE_API_URL:-}
|
CONSOLE_API_URL: ${CONSOLE_API_URL:-}
|
||||||
APP_API_URL: ${APP_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:-}
|
SENTRY_DSN: ${WEB_SENTRY_DSN:-}
|
||||||
NEXT_TELEMETRY_DISABLED: ${NEXT_TELEMETRY_DISABLED:-0}
|
NEXT_TELEMETRY_DISABLED: ${NEXT_TELEMETRY_DISABLED:-0}
|
||||||
TEXT_GENERATION_TIMEOUT_MS: ${TEXT_GENERATION_TIMEOUT_MS:-60000}
|
TEXT_GENERATION_TIMEOUT_MS: ${TEXT_GENERATION_TIMEOUT_MS:-60000}
|
||||||
CSP_WHITELIST: ${CSP_WHITELIST:-}
|
CSP_WHITELIST: ${CSP_WHITELIST:-}
|
||||||
ALLOW_EMBED: ${ALLOW_EMBED:-false}
|
ALLOW_EMBED: ${ALLOW_EMBED:-false}
|
||||||
|
ALLOW_UNSAFE_DATA_SCHEME: ${ALLOW_UNSAFE_DATA_SCHEME:-false}
|
||||||
MARKETPLACE_API_URL: ${MARKETPLACE_API_URL:-https://marketplace.dify.ai}
|
MARKETPLACE_API_URL: ${MARKETPLACE_API_URL:-https://marketplace.dify.ai}
|
||||||
MARKETPLACE_URL: ${MARKETPLACE_URL:-https://marketplace.dify.ai}
|
MARKETPLACE_URL: ${MARKETPLACE_URL:-https://marketplace.dify.ai}
|
||||||
TOP_K_MAX_VALUE: ${TOP_K_MAX_VALUE:-}
|
TOP_K_MAX_VALUE: ${TOP_K_MAX_VALUE:-}
|
||||||
@@ -76,17 +154,21 @@ services:
|
|||||||
MAX_TOOLS_NUM: ${MAX_TOOLS_NUM:-10}
|
MAX_TOOLS_NUM: ${MAX_TOOLS_NUM:-10}
|
||||||
MAX_PARALLEL_LIMIT: ${MAX_PARALLEL_LIMIT:-10}
|
MAX_PARALLEL_LIMIT: ${MAX_PARALLEL_LIMIT:-10}
|
||||||
MAX_ITERATIONS_NUM: ${MAX_ITERATIONS_NUM:-99}
|
MAX_ITERATIONS_NUM: ${MAX_ITERATIONS_NUM:-99}
|
||||||
|
MAX_TREE_DEPTH: ${MAX_TREE_DEPTH:-50}
|
||||||
ENABLE_WEBSITE_JINAREADER: ${ENABLE_WEBSITE_JINAREADER:-true}
|
ENABLE_WEBSITE_JINAREADER: ${ENABLE_WEBSITE_JINAREADER:-true}
|
||||||
ENABLE_WEBSITE_FIRECRAWL: ${ENABLE_WEBSITE_FIRECRAWL:-true}
|
ENABLE_WEBSITE_FIRECRAWL: ${ENABLE_WEBSITE_FIRECRAWL:-true}
|
||||||
ENABLE_WEBSITE_WATERCRAWL: ${ENABLE_WEBSITE_WATERCRAWL:-true}
|
ENABLE_WEBSITE_WATERCRAWL: ${ENABLE_WEBSITE_WATERCRAWL:-true}
|
||||||
# The postgres database.
|
|
||||||
db:
|
# The PostgreSQL database.
|
||||||
|
db_postgres:
|
||||||
image: postgres:15-alpine
|
image: postgres:15-alpine
|
||||||
|
profiles:
|
||||||
|
- postgresql
|
||||||
restart: always
|
restart: always
|
||||||
environment:
|
environment:
|
||||||
POSTGRES_USER: ${POSTGRES_USER:-postgres}
|
POSTGRES_USER: ${DB_USERNAME:-postgres}
|
||||||
POSTGRES_PASSWORD: ${POSTGRES_PASSWORD:-difyai123456}
|
POSTGRES_PASSWORD: ${DB_PASSWORD:-difyai123456}
|
||||||
POSTGRES_DB: ${POSTGRES_DB:-dify}
|
POSTGRES_DB: ${DB_DATABASE:-dify}
|
||||||
PGDATA: ${PGDATA:-/var/lib/postgresql/data/pgdata}
|
PGDATA: ${PGDATA:-/var/lib/postgresql/data/pgdata}
|
||||||
command: >
|
command: >
|
||||||
postgres -c 'max_connections=${POSTGRES_MAX_CONNECTIONS:-100}'
|
postgres -c 'max_connections=${POSTGRES_MAX_CONNECTIONS:-100}'
|
||||||
@@ -94,14 +176,56 @@ services:
|
|||||||
-c 'work_mem=${POSTGRES_WORK_MEM:-4MB}'
|
-c 'work_mem=${POSTGRES_WORK_MEM:-4MB}'
|
||||||
-c 'maintenance_work_mem=${POSTGRES_MAINTENANCE_WORK_MEM:-64MB}'
|
-c 'maintenance_work_mem=${POSTGRES_MAINTENANCE_WORK_MEM:-64MB}'
|
||||||
-c 'effective_cache_size=${POSTGRES_EFFECTIVE_CACHE_SIZE:-4096MB}'
|
-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:
|
||||||
- ./volumes/db/data:/var/lib/postgresql/data
|
- ./volumes/db/data:/var/lib/postgresql/data
|
||||||
healthcheck:
|
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
|
interval: 1s
|
||||||
timeout: 3s
|
timeout: 3s
|
||||||
retries: 60
|
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.
|
# The redis cache.
|
||||||
redis:
|
redis:
|
||||||
image: redis:6-alpine
|
image: redis:6-alpine
|
||||||
@@ -114,7 +238,11 @@ services:
|
|||||||
# Set the redis password when startup redis server.
|
# Set the redis password when startup redis server.
|
||||||
command: redis-server --requirepass ${REDIS_PASSWORD:-difyai123456}
|
command: redis-server --requirepass ${REDIS_PASSWORD:-difyai123456}
|
||||||
healthcheck:
|
healthcheck:
|
||||||
test: [ 'CMD', 'redis-cli', 'ping' ]
|
test:
|
||||||
|
[
|
||||||
|
"CMD-SHELL",
|
||||||
|
"redis-cli -a ${REDIS_PASSWORD:-difyai123456} ping | grep -q PONG",
|
||||||
|
]
|
||||||
|
|
||||||
# The DifySandbox
|
# The DifySandbox
|
||||||
sandbox:
|
sandbox:
|
||||||
@@ -136,13 +264,13 @@ services:
|
|||||||
- ./volumes/sandbox/dependencies:/dependencies
|
- ./volumes/sandbox/dependencies:/dependencies
|
||||||
- ./volumes/sandbox/conf:/conf
|
- ./volumes/sandbox/conf:/conf
|
||||||
healthcheck:
|
healthcheck:
|
||||||
test: [ 'CMD', 'curl', '-f', 'http://localhost:8194/health' ]
|
test: ["CMD", "curl", "-f", "http://localhost:8194/health"]
|
||||||
networks:
|
networks:
|
||||||
- ssrf_proxy_network
|
- ssrf_proxy_network
|
||||||
|
|
||||||
# plugin daemon
|
# plugin daemon
|
||||||
plugin_daemon:
|
plugin_daemon:
|
||||||
image: langgenius/dify-plugin-daemon:0.1.3-local
|
image: langgenius/dify-plugin-daemon:0.5.2-local
|
||||||
restart: always
|
restart: always
|
||||||
environment:
|
environment:
|
||||||
# Use the shared environment variables.
|
# Use the shared environment variables.
|
||||||
@@ -160,6 +288,8 @@ services:
|
|||||||
FORCE_VERIFYING_SIGNATURE: ${FORCE_VERIFYING_SIGNATURE:-true}
|
FORCE_VERIFYING_SIGNATURE: ${FORCE_VERIFYING_SIGNATURE:-true}
|
||||||
PYTHON_ENV_INIT_TIMEOUT: ${PLUGIN_PYTHON_ENV_INIT_TIMEOUT:-120}
|
PYTHON_ENV_INIT_TIMEOUT: ${PLUGIN_PYTHON_ENV_INIT_TIMEOUT:-120}
|
||||||
PLUGIN_MAX_EXECUTION_TIMEOUT: ${PLUGIN_MAX_EXECUTION_TIMEOUT:-600}
|
PLUGIN_MAX_EXECUTION_TIMEOUT: ${PLUGIN_MAX_EXECUTION_TIMEOUT:-600}
|
||||||
|
PLUGIN_STDIO_BUFFER_SIZE: ${PLUGIN_STDIO_BUFFER_SIZE:-1024}
|
||||||
|
PLUGIN_STDIO_MAX_BUFFER_SIZE: ${PLUGIN_STDIO_MAX_BUFFER_SIZE:-5242880}
|
||||||
PIP_MIRROR_URL: ${PIP_MIRROR_URL:-}
|
PIP_MIRROR_URL: ${PIP_MIRROR_URL:-}
|
||||||
PLUGIN_STORAGE_TYPE: ${PLUGIN_STORAGE_TYPE:-local}
|
PLUGIN_STORAGE_TYPE: ${PLUGIN_STORAGE_TYPE:-local}
|
||||||
PLUGIN_STORAGE_LOCAL_ROOT: ${PLUGIN_STORAGE_LOCAL_ROOT:-/app/storage}
|
PLUGIN_STORAGE_LOCAL_ROOT: ${PLUGIN_STORAGE_LOCAL_ROOT:-/app/storage}
|
||||||
@@ -189,13 +319,25 @@ services:
|
|||||||
VOLCENGINE_TOS_ACCESS_KEY: ${PLUGIN_VOLCENGINE_TOS_ACCESS_KEY:-}
|
VOLCENGINE_TOS_ACCESS_KEY: ${PLUGIN_VOLCENGINE_TOS_ACCESS_KEY:-}
|
||||||
VOLCENGINE_TOS_SECRET_KEY: ${PLUGIN_VOLCENGINE_TOS_SECRET_KEY:-}
|
VOLCENGINE_TOS_SECRET_KEY: ${PLUGIN_VOLCENGINE_TOS_SECRET_KEY:-}
|
||||||
VOLCENGINE_TOS_REGION: ${PLUGIN_VOLCENGINE_TOS_REGION:-}
|
VOLCENGINE_TOS_REGION: ${PLUGIN_VOLCENGINE_TOS_REGION:-}
|
||||||
|
SENTRY_ENABLED: ${PLUGIN_SENTRY_ENABLED:-false}
|
||||||
|
SENTRY_DSN: ${PLUGIN_SENTRY_DSN:-}
|
||||||
ports:
|
ports:
|
||||||
- "${EXPOSE_PLUGIN_DEBUGGING_PORT:-5003}:${PLUGIN_DEBUGGING_PORT:-5003}"
|
- "${EXPOSE_PLUGIN_DEBUGGING_PORT:-5003}:${PLUGIN_DEBUGGING_PORT:-5003}"
|
||||||
volumes:
|
volumes:
|
||||||
- ./volumes/plugin_daemon:/app/storage
|
- ./volumes/plugin_daemon:/app/storage
|
||||||
depends_on:
|
depends_on:
|
||||||
db:
|
db_postgres:
|
||||||
condition: service_healthy
|
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
|
# ssrf_proxy server
|
||||||
# for more information, please refer to
|
# for more information, please refer to
|
||||||
@@ -206,7 +348,12 @@ services:
|
|||||||
volumes:
|
volumes:
|
||||||
- ./ssrf_proxy/squid.conf.template:/etc/squid/squid.conf.template
|
- ./ssrf_proxy/squid.conf.template:/etc/squid/squid.conf.template
|
||||||
- ./ssrf_proxy/docker-entrypoint.sh:/docker-entrypoint-mount.sh
|
- ./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:
|
environment:
|
||||||
# pls clearly modify the squid env vars to fit your network environment.
|
# pls clearly modify the squid env vars to fit your network environment.
|
||||||
HTTP_PORT: ${SSRF_HTTP_PORT:-3128}
|
HTTP_PORT: ${SSRF_HTTP_PORT:-3128}
|
||||||
@@ -235,8 +382,8 @@ services:
|
|||||||
- CERTBOT_EMAIL=${CERTBOT_EMAIL}
|
- CERTBOT_EMAIL=${CERTBOT_EMAIL}
|
||||||
- CERTBOT_DOMAIN=${CERTBOT_DOMAIN}
|
- CERTBOT_DOMAIN=${CERTBOT_DOMAIN}
|
||||||
- CERTBOT_OPTIONS=${CERTBOT_OPTIONS:-}
|
- CERTBOT_OPTIONS=${CERTBOT_OPTIONS:-}
|
||||||
entrypoint: [ '/docker-entrypoint.sh' ]
|
entrypoint: ["/docker-entrypoint.sh"]
|
||||||
command: [ 'tail', '-f', '/dev/null' ]
|
command: ["tail", "-f", "/dev/null"]
|
||||||
|
|
||||||
# The nginx reverse proxy.
|
# The nginx reverse proxy.
|
||||||
# used for reverse proxying the API service and Web service.
|
# used for reverse proxying the API service and Web service.
|
||||||
@@ -253,7 +400,12 @@ services:
|
|||||||
- ./volumes/certbot/conf/live:/etc/letsencrypt/live # cert dir (with certbot container)
|
- ./volumes/certbot/conf/live:/etc/letsencrypt/live # cert dir (with certbot container)
|
||||||
- ./volumes/certbot/conf:/etc/letsencrypt
|
- ./volumes/certbot/conf:/etc/letsencrypt
|
||||||
- ./volumes/certbot/www:/var/www/html
|
- ./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:
|
environment:
|
||||||
NGINX_SERVER_NAME: ${NGINX_SERVER_NAME:-_}
|
NGINX_SERVER_NAME: ${NGINX_SERVER_NAME:-_}
|
||||||
NGINX_HTTPS_ENABLED: ${NGINX_HTTPS_ENABLED:-false}
|
NGINX_HTTPS_ENABLED: ${NGINX_HTTPS_ENABLED:-false}
|
||||||
@@ -263,9 +415,9 @@ services:
|
|||||||
# and modify the env vars below in .env if HTTPS_ENABLED is true.
|
# 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_FILENAME: ${NGINX_SSL_CERT_FILENAME:-dify.crt}
|
||||||
NGINX_SSL_CERT_KEY_FILENAME: ${NGINX_SSL_CERT_KEY_FILENAME:-dify.key}
|
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_WORKER_PROCESSES: ${NGINX_WORKER_PROCESSES:-auto}
|
||||||
NGINX_CLIENT_MAX_BODY_SIZE: ${NGINX_CLIENT_MAX_BODY_SIZE:-15M}
|
NGINX_CLIENT_MAX_BODY_SIZE: ${NGINX_CLIENT_MAX_BODY_SIZE:-100M}
|
||||||
NGINX_KEEPALIVE_TIMEOUT: ${NGINX_KEEPALIVE_TIMEOUT:-65}
|
NGINX_KEEPALIVE_TIMEOUT: ${NGINX_KEEPALIVE_TIMEOUT:-65}
|
||||||
NGINX_PROXY_READ_TIMEOUT: ${NGINX_PROXY_READ_TIMEOUT:-3600s}
|
NGINX_PROXY_READ_TIMEOUT: ${NGINX_PROXY_READ_TIMEOUT:-3600s}
|
||||||
NGINX_PROXY_SEND_TIMEOUT: ${NGINX_PROXY_SEND_TIMEOUT:-3600s}
|
NGINX_PROXY_SEND_TIMEOUT: ${NGINX_PROXY_SEND_TIMEOUT:-3600s}
|
||||||
@@ -275,14 +427,13 @@ services:
|
|||||||
- api
|
- api
|
||||||
- web
|
- web
|
||||||
ports:
|
ports:
|
||||||
- '${EXPOSE_NGINX_PORT:-80}:${NGINX_PORT:-80}'
|
- "${EXPOSE_NGINX_PORT:-80}:${NGINX_PORT:-80}"
|
||||||
- '${EXPOSE_NGINX_SSL_PORT:-443}:${NGINX_SSL_PORT:-443}'
|
- "${EXPOSE_NGINX_SSL_PORT:-443}:${NGINX_SSL_PORT:-443}"
|
||||||
|
|
||||||
# The Weaviate vector store.
|
# The Weaviate vector store.
|
||||||
weaviate:
|
weaviate:
|
||||||
image: semitechnologies/weaviate:1.19.0
|
image: semitechnologies/weaviate:1.27.0
|
||||||
profiles:
|
profiles:
|
||||||
- ''
|
|
||||||
- weaviate
|
- weaviate
|
||||||
restart: always
|
restart: always
|
||||||
volumes:
|
volumes:
|
||||||
@@ -301,11 +452,73 @@ services:
|
|||||||
AUTHENTICATION_APIKEY_USERS: ${WEAVIATE_AUTHENTICATION_APIKEY_USERS:-hello@dify.ai}
|
AUTHENTICATION_APIKEY_USERS: ${WEAVIATE_AUTHENTICATION_APIKEY_USERS:-hello@dify.ai}
|
||||||
AUTHORIZATION_ADMINLIST_ENABLED: ${WEAVIATE_AUTHORIZATION_ADMINLIST_ENABLED:-true}
|
AUTHORIZATION_ADMINLIST_ENABLED: ${WEAVIATE_AUTHORIZATION_ADMINLIST_ENABLED:-true}
|
||||||
AUTHORIZATION_ADMINLIST_USERS: ${WEAVIATE_AUTHORIZATION_ADMINLIST_USERS:-hello@dify.ai}
|
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.
|
# Qdrant vector store.
|
||||||
# (if used, you need to set VECTOR_STORE to qdrant in the api & worker service.)
|
# (if used, you need to set VECTOR_STORE to qdrant in the api & worker service.)
|
||||||
qdrant:
|
qdrant:
|
||||||
image: langgenius/qdrant:v1.7.3
|
image: langgenius/qdrant:v1.8.3
|
||||||
profiles:
|
profiles:
|
||||||
- qdrant
|
- qdrant
|
||||||
restart: always
|
restart: always
|
||||||
@@ -335,13 +548,17 @@ services:
|
|||||||
working_dir: /opt/couchbase
|
working_dir: /opt/couchbase
|
||||||
stdin_open: true
|
stdin_open: true
|
||||||
tty: true
|
tty: true
|
||||||
entrypoint: [ "" ]
|
entrypoint: [""]
|
||||||
command: sh -c "/opt/couchbase/init/init-cbserver.sh"
|
command: sh -c "/opt/couchbase/init/init-cbserver.sh"
|
||||||
volumes:
|
volumes:
|
||||||
- ./volumes/couchbase/data:/opt/couchbase/var/lib/couchbase/data
|
- ./volumes/couchbase/data:/opt/couchbase/var/lib/couchbase/data
|
||||||
healthcheck:
|
healthcheck:
|
||||||
# ensure bucket was created before proceeding
|
# 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
|
interval: 10s
|
||||||
retries: 10
|
retries: 10
|
||||||
start_period: 30s
|
start_period: 30s
|
||||||
@@ -367,9 +584,9 @@ services:
|
|||||||
volumes:
|
volumes:
|
||||||
- ./volumes/pgvector/data:/var/lib/postgresql/data
|
- ./volumes/pgvector/data:/var/lib/postgresql/data
|
||||||
- ./pgvector/docker-entrypoint.sh:/docker-entrypoint.sh
|
- ./pgvector/docker-entrypoint.sh:/docker-entrypoint.sh
|
||||||
entrypoint: [ '/docker-entrypoint.sh' ]
|
entrypoint: ["/docker-entrypoint.sh"]
|
||||||
healthcheck:
|
healthcheck:
|
||||||
test: [ 'CMD', 'pg_isready' ]
|
test: ["CMD", "pg_isready"]
|
||||||
interval: 1s
|
interval: 1s
|
||||||
timeout: 3s
|
timeout: 3s
|
||||||
retries: 30
|
retries: 30
|
||||||
@@ -386,14 +603,14 @@ services:
|
|||||||
- VB_USERNAME=dify
|
- VB_USERNAME=dify
|
||||||
- VB_PASSWORD=Difyai123456
|
- VB_PASSWORD=Difyai123456
|
||||||
ports:
|
ports:
|
||||||
- '5434:5432'
|
- "5434:5432"
|
||||||
volumes:
|
volumes:
|
||||||
- ./vastbase/lic:/home/vastbase/vastbase/lic
|
- ./vastbase/lic:/home/vastbase/vastbase/lic
|
||||||
- ./vastbase/data:/home/vastbase/data
|
- ./vastbase/data:/home/vastbase/data
|
||||||
- ./vastbase/backup:/home/vastbase/backup
|
- ./vastbase/backup:/home/vastbase/backup
|
||||||
- ./vastbase/backup_log:/home/vastbase/backup_log
|
- ./vastbase/backup_log:/home/vastbase/backup_log
|
||||||
healthcheck:
|
healthcheck:
|
||||||
test: [ 'CMD', 'pg_isready' ]
|
test: ["CMD", "pg_isready"]
|
||||||
interval: 1s
|
interval: 1s
|
||||||
timeout: 3s
|
timeout: 3s
|
||||||
retries: 30
|
retries: 30
|
||||||
@@ -415,7 +632,7 @@ services:
|
|||||||
volumes:
|
volumes:
|
||||||
- ./volumes/pgvecto_rs/data:/var/lib/postgresql/data
|
- ./volumes/pgvecto_rs/data:/var/lib/postgresql/data
|
||||||
healthcheck:
|
healthcheck:
|
||||||
test: [ 'CMD', 'pg_isready' ]
|
test: ["CMD", "pg_isready"]
|
||||||
interval: 1s
|
interval: 1s
|
||||||
timeout: 3s
|
timeout: 3s
|
||||||
retries: 30
|
retries: 30
|
||||||
@@ -433,32 +650,25 @@ services:
|
|||||||
CHROMA_SERVER_AUTHN_PROVIDER: ${CHROMA_SERVER_AUTHN_PROVIDER:-chromadb.auth.token_authn.TokenAuthenticationServerProvider}
|
CHROMA_SERVER_AUTHN_PROVIDER: ${CHROMA_SERVER_AUTHN_PROVIDER:-chromadb.auth.token_authn.TokenAuthenticationServerProvider}
|
||||||
IS_PERSISTENT: ${CHROMA_IS_PERSISTENT:-TRUE}
|
IS_PERSISTENT: ${CHROMA_IS_PERSISTENT:-TRUE}
|
||||||
|
|
||||||
# OceanBase vector database
|
# InterSystems IRIS vector database
|
||||||
oceanbase:
|
iris:
|
||||||
image: oceanbase/oceanbase-ce:4.3.5-lts
|
image: containers.intersystems.com/intersystems/iris-community:2025.3
|
||||||
container_name: oceanbase
|
|
||||||
profiles:
|
profiles:
|
||||||
- oceanbase
|
- iris
|
||||||
|
container_name: iris
|
||||||
restart: always
|
restart: always
|
||||||
volumes:
|
init: true
|
||||||
- ./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
|
|
||||||
ports:
|
ports:
|
||||||
- "${OCEANBASE_VECTOR_PORT:-2881}:2881"
|
- "${IRIS_SUPER_SERVER_PORT:-1972}:1972"
|
||||||
healthcheck:
|
- "${IRIS_WEB_SERVER_PORT:-52773}:52773"
|
||||||
test: [ 'CMD-SHELL', 'obclient -h127.0.0.1 -P2881 -uroot@test -p$${OB_TENANT_PASSWORD} -e "SELECT 1;"' ]
|
volumes:
|
||||||
interval: 10s
|
- ./volumes/iris:/opt/iris
|
||||||
retries: 30
|
- ./iris/iris-init.script:/iris-init.script
|
||||||
start_period: 30s
|
- ./iris/docker-entrypoint.sh:/custom-entrypoint.sh
|
||||||
timeout: 10s
|
entrypoint: ["/custom-entrypoint.sh"]
|
||||||
|
tty: true
|
||||||
|
environment:
|
||||||
|
TZ: ${IRIS_TIMEZONE:-UTC}
|
||||||
|
|
||||||
# Oracle vector database
|
# Oracle vector database
|
||||||
oracle:
|
oracle:
|
||||||
@@ -490,7 +700,7 @@ services:
|
|||||||
- ./volumes/milvus/etcd:/etcd
|
- ./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
|
command: etcd -advertise-client-urls=http://127.0.0.1:2379 -listen-client-urls http://0.0.0.0:2379 --data-dir /etcd
|
||||||
healthcheck:
|
healthcheck:
|
||||||
test: [ 'CMD', 'etcdctl', 'endpoint', 'health' ]
|
test: ["CMD", "etcdctl", "endpoint", "health"]
|
||||||
interval: 30s
|
interval: 30s
|
||||||
timeout: 20s
|
timeout: 20s
|
||||||
retries: 3
|
retries: 3
|
||||||
@@ -509,7 +719,7 @@ services:
|
|||||||
- ./volumes/milvus/minio:/minio_data
|
- ./volumes/milvus/minio:/minio_data
|
||||||
command: minio server /minio_data --console-address ":9001"
|
command: minio server /minio_data --console-address ":9001"
|
||||||
healthcheck:
|
healthcheck:
|
||||||
test: [ 'CMD', 'curl', '-f', 'http://localhost:9000/minio/health/live' ]
|
test: ["CMD", "curl", "-f", "http://localhost:9000/minio/health/live"]
|
||||||
interval: 30s
|
interval: 30s
|
||||||
timeout: 20s
|
timeout: 20s
|
||||||
retries: 3
|
retries: 3
|
||||||
@@ -518,10 +728,10 @@ services:
|
|||||||
|
|
||||||
milvus-standalone:
|
milvus-standalone:
|
||||||
container_name: milvus-standalone
|
container_name: milvus-standalone
|
||||||
image: milvusdb/milvus:v2.5.0-beta
|
image: milvusdb/milvus:v2.6.3
|
||||||
profiles:
|
profiles:
|
||||||
- milvus
|
- milvus
|
||||||
command: [ 'milvus', 'run', 'standalone' ]
|
command: ["milvus", "run", "standalone"]
|
||||||
environment:
|
environment:
|
||||||
ETCD_ENDPOINTS: ${ETCD_ENDPOINTS:-etcd:2379}
|
ETCD_ENDPOINTS: ${ETCD_ENDPOINTS:-etcd:2379}
|
||||||
MINIO_ADDRESS: ${MINIO_ADDRESS:-minio:9000}
|
MINIO_ADDRESS: ${MINIO_ADDRESS:-minio:9000}
|
||||||
@@ -529,7 +739,7 @@ services:
|
|||||||
volumes:
|
volumes:
|
||||||
- ./volumes/milvus/milvus:/var/lib/milvus
|
- ./volumes/milvus/milvus:/var/lib/milvus
|
||||||
healthcheck:
|
healthcheck:
|
||||||
test: [ 'CMD', 'curl', '-f', 'http://localhost:9091/healthz' ]
|
test: ["CMD", "curl", "-f", "http://localhost:9091/healthz"]
|
||||||
interval: 30s
|
interval: 30s
|
||||||
start_period: 90s
|
start_period: 90s
|
||||||
timeout: 20s
|
timeout: 20s
|
||||||
@@ -595,7 +805,7 @@ services:
|
|||||||
volumes:
|
volumes:
|
||||||
- ./volumes/opengauss/data:/var/lib/opengauss/data
|
- ./volumes/opengauss/data:/var/lib/opengauss/data
|
||||||
healthcheck:
|
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
|
interval: 10s
|
||||||
timeout: 10s
|
timeout: 10s
|
||||||
retries: 10
|
retries: 10
|
||||||
@@ -648,18 +858,19 @@ services:
|
|||||||
node.name: dify-es0
|
node.name: dify-es0
|
||||||
discovery.type: single-node
|
discovery.type: single-node
|
||||||
xpack.license.self_generated.type: basic
|
xpack.license.self_generated.type: basic
|
||||||
xpack.security.enabled: 'true'
|
xpack.security.enabled: "true"
|
||||||
xpack.security.enrollment.enabled: 'false'
|
xpack.security.enrollment.enabled: "false"
|
||||||
xpack.security.http.ssl.enabled: 'false'
|
xpack.security.http.ssl.enabled: "false"
|
||||||
ports:
|
ports:
|
||||||
- ${ELASTICSEARCH_PORT:-9200}:9200
|
- ${ELASTICSEARCH_PORT:-9200}:9200
|
||||||
deploy:
|
deploy:
|
||||||
resources:
|
resources:
|
||||||
limits:
|
limits:
|
||||||
memory: 2g
|
memory: 2g
|
||||||
entrypoint: [ 'sh', '-c', "sh /docker-entrypoint-mount.sh" ]
|
entrypoint: ["sh", "-c", "sh /docker-entrypoint-mount.sh"]
|
||||||
healthcheck:
|
healthcheck:
|
||||||
test: [ 'CMD', 'curl', '-s', 'http://localhost:9200/_cluster/health?pretty' ]
|
test:
|
||||||
|
["CMD", "curl", "-s", "http://localhost:9200/_cluster/health?pretty"]
|
||||||
interval: 30s
|
interval: 30s
|
||||||
timeout: 10s
|
timeout: 10s
|
||||||
retries: 50
|
retries: 50
|
||||||
@@ -677,17 +888,17 @@ services:
|
|||||||
environment:
|
environment:
|
||||||
XPACK_ENCRYPTEDSAVEDOBJECTS_ENCRYPTIONKEY: d1a66dfd-c4d3-4a0a-8290-2abcb83ab3aa
|
XPACK_ENCRYPTEDSAVEDOBJECTS_ENCRYPTIONKEY: d1a66dfd-c4d3-4a0a-8290-2abcb83ab3aa
|
||||||
NO_PROXY: localhost,127.0.0.1,elasticsearch,kibana
|
NO_PROXY: localhost,127.0.0.1,elasticsearch,kibana
|
||||||
XPACK_SECURITY_ENABLED: 'true'
|
XPACK_SECURITY_ENABLED: "true"
|
||||||
XPACK_SECURITY_ENROLLMENT_ENABLED: 'false'
|
XPACK_SECURITY_ENROLLMENT_ENABLED: "false"
|
||||||
XPACK_SECURITY_HTTP_SSL_ENABLED: 'false'
|
XPACK_SECURITY_HTTP_SSL_ENABLED: "false"
|
||||||
XPACK_FLEET_ISAIRGAPPED: 'true'
|
XPACK_FLEET_ISAIRGAPPED: "true"
|
||||||
I18N_LOCALE: zh-CN
|
I18N_LOCALE: zh-CN
|
||||||
SERVER_PORT: '5601'
|
SERVER_PORT: "5601"
|
||||||
ELASTICSEARCH_HOSTS: http://elasticsearch:9200
|
ELASTICSEARCH_HOSTS: http://elasticsearch:9200
|
||||||
ports:
|
ports:
|
||||||
- ${KIBANA_PORT:-5601}:5601
|
- ${KIBANA_PORT:-5601}:5601
|
||||||
healthcheck:
|
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
|
interval: 30s
|
||||||
timeout: 10s
|
timeout: 10s
|
||||||
retries: 3
|
retries: 3
|
||||||
|
|||||||
@@ -1,13 +1,16 @@
|
|||||||
services:
|
services:
|
||||||
# The postgres database.
|
# The postgres database.
|
||||||
db:
|
db_postgres:
|
||||||
image: postgres:15-alpine
|
image: postgres:15-alpine
|
||||||
|
profiles:
|
||||||
|
- ""
|
||||||
|
- postgresql
|
||||||
restart: always
|
restart: always
|
||||||
env_file:
|
env_file:
|
||||||
- ./middleware.env
|
- ./middleware.env
|
||||||
environment:
|
environment:
|
||||||
POSTGRES_PASSWORD: ${POSTGRES_PASSWORD:-difyai123456}
|
POSTGRES_PASSWORD: ${DB_PASSWORD:-difyai123456}
|
||||||
POSTGRES_DB: ${POSTGRES_DB:-dify}
|
POSTGRES_DB: ${DB_DATABASE:-dify}
|
||||||
PGDATA: ${PGDATA:-/var/lib/postgresql/data/pgdata}
|
PGDATA: ${PGDATA:-/var/lib/postgresql/data/pgdata}
|
||||||
command: >
|
command: >
|
||||||
postgres -c 'max_connections=${POSTGRES_MAX_CONNECTIONS:-100}'
|
postgres -c 'max_connections=${POSTGRES_MAX_CONNECTIONS:-100}'
|
||||||
@@ -15,12 +18,57 @@ services:
|
|||||||
-c 'work_mem=${POSTGRES_WORK_MEM:-4MB}'
|
-c 'work_mem=${POSTGRES_WORK_MEM:-4MB}'
|
||||||
-c 'maintenance_work_mem=${POSTGRES_MAINTENANCE_WORK_MEM:-64MB}'
|
-c 'maintenance_work_mem=${POSTGRES_MAINTENANCE_WORK_MEM:-64MB}'
|
||||||
-c 'effective_cache_size=${POSTGRES_EFFECTIVE_CACHE_SIZE:-4096MB}'
|
-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:
|
||||||
- ${PGDATA_HOST_VOLUME:-./volumes/db/data}:/var/lib/postgresql/data
|
- ${PGDATA_HOST_VOLUME:-./volumes/db/data}:/var/lib/postgresql/data
|
||||||
ports:
|
ports:
|
||||||
- "${EXPOSE_POSTGRES_PORT:-5432}:5432"
|
- "${EXPOSE_POSTGRES_PORT:-5432}:5432"
|
||||||
healthcheck:
|
healthcheck:
|
||||||
test: [ "CMD", "pg_isready" ]
|
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
|
interval: 1s
|
||||||
timeout: 3s
|
timeout: 3s
|
||||||
retries: 30
|
retries: 30
|
||||||
@@ -41,7 +89,11 @@ services:
|
|||||||
ports:
|
ports:
|
||||||
- "${EXPOSE_REDIS_PORT:-6379}:6379"
|
- "${EXPOSE_REDIS_PORT:-6379}:6379"
|
||||||
healthcheck:
|
healthcheck:
|
||||||
test: [ "CMD", "redis-cli", "ping" ]
|
test:
|
||||||
|
[
|
||||||
|
"CMD-SHELL",
|
||||||
|
"redis-cli -a ${REDIS_PASSWORD:-difyai123456} ping | grep -q PONG",
|
||||||
|
]
|
||||||
|
|
||||||
# The DifySandbox
|
# The DifySandbox
|
||||||
sandbox:
|
sandbox:
|
||||||
@@ -65,22 +117,19 @@ services:
|
|||||||
- ./volumes/sandbox/dependencies:/dependencies
|
- ./volumes/sandbox/dependencies:/dependencies
|
||||||
- ./volumes/sandbox/conf:/conf
|
- ./volumes/sandbox/conf:/conf
|
||||||
healthcheck:
|
healthcheck:
|
||||||
test: [ "CMD", "curl", "-f", "http://localhost:8194/health" ]
|
test: ["CMD", "curl", "-f", "http://localhost:8194/health"]
|
||||||
networks:
|
networks:
|
||||||
- ssrf_proxy_network
|
- ssrf_proxy_network
|
||||||
|
|
||||||
# plugin daemon
|
# plugin daemon
|
||||||
plugin_daemon:
|
plugin_daemon:
|
||||||
image: langgenius/dify-plugin-daemon:0.1.3-local
|
image: langgenius/dify-plugin-daemon:0.5.2-local
|
||||||
restart: always
|
restart: always
|
||||||
env_file:
|
env_file:
|
||||||
- ./middleware.env
|
- ./middleware.env
|
||||||
environment:
|
environment:
|
||||||
# Use the shared environment variables.
|
# Use the shared environment variables.
|
||||||
DB_HOST: ${DB_HOST:-db}
|
LOG_OUTPUT_FORMAT: ${LOG_OUTPUT_FORMAT:-text}
|
||||||
DB_PORT: ${DB_PORT:-5432}
|
|
||||||
DB_USERNAME: ${DB_USER:-postgres}
|
|
||||||
DB_PASSWORD: ${DB_PASSWORD:-difyai123456}
|
|
||||||
DB_DATABASE: ${DB_PLUGIN_DATABASE:-dify_plugin}
|
DB_DATABASE: ${DB_PLUGIN_DATABASE:-dify_plugin}
|
||||||
REDIS_HOST: ${REDIS_HOST:-redis}
|
REDIS_HOST: ${REDIS_HOST:-redis}
|
||||||
REDIS_PORT: ${REDIS_PORT:-6379}
|
REDIS_PORT: ${REDIS_PORT:-6379}
|
||||||
@@ -94,7 +143,6 @@ services:
|
|||||||
PLUGIN_REMOTE_INSTALLING_HOST: ${PLUGIN_DEBUGGING_HOST:-0.0.0.0}
|
PLUGIN_REMOTE_INSTALLING_HOST: ${PLUGIN_DEBUGGING_HOST:-0.0.0.0}
|
||||||
PLUGIN_REMOTE_INSTALLING_PORT: ${PLUGIN_DEBUGGING_PORT:-5003}
|
PLUGIN_REMOTE_INSTALLING_PORT: ${PLUGIN_DEBUGGING_PORT:-5003}
|
||||||
PLUGIN_WORKING_PATH: ${PLUGIN_WORKING_PATH:-/app/storage/cwd}
|
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}
|
PYTHON_ENV_INIT_TIMEOUT: ${PLUGIN_PYTHON_ENV_INIT_TIMEOUT:-120}
|
||||||
PLUGIN_MAX_EXECUTION_TIMEOUT: ${PLUGIN_MAX_EXECUTION_TIMEOUT:-600}
|
PLUGIN_MAX_EXECUTION_TIMEOUT: ${PLUGIN_MAX_EXECUTION_TIMEOUT:-600}
|
||||||
PIP_MIRROR_URL: ${PIP_MIRROR_URL:-}
|
PIP_MIRROR_URL: ${PIP_MIRROR_URL:-}
|
||||||
@@ -126,6 +174,9 @@ services:
|
|||||||
VOLCENGINE_TOS_ACCESS_KEY: ${PLUGIN_VOLCENGINE_TOS_ACCESS_KEY:-}
|
VOLCENGINE_TOS_ACCESS_KEY: ${PLUGIN_VOLCENGINE_TOS_ACCESS_KEY:-}
|
||||||
VOLCENGINE_TOS_SECRET_KEY: ${PLUGIN_VOLCENGINE_TOS_SECRET_KEY:-}
|
VOLCENGINE_TOS_SECRET_KEY: ${PLUGIN_VOLCENGINE_TOS_SECRET_KEY:-}
|
||||||
VOLCENGINE_TOS_REGION: ${PLUGIN_VOLCENGINE_TOS_REGION:-}
|
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:
|
ports:
|
||||||
- "${EXPOSE_PLUGIN_DAEMON_PORT:-5002}:${PLUGIN_DAEMON_PORT:-5002}"
|
- "${EXPOSE_PLUGIN_DAEMON_PORT:-5002}:${PLUGIN_DAEMON_PORT:-5002}"
|
||||||
- "${EXPOSE_PLUGIN_DEBUGGING_PORT:-5003}:${PLUGIN_DEBUGGING_PORT:-5003}"
|
- "${EXPOSE_PLUGIN_DEBUGGING_PORT:-5003}:${PLUGIN_DEBUGGING_PORT:-5003}"
|
||||||
@@ -141,7 +192,12 @@ services:
|
|||||||
volumes:
|
volumes:
|
||||||
- ./ssrf_proxy/squid.conf.template:/etc/squid/squid.conf.template
|
- ./ssrf_proxy/squid.conf.template:/etc/squid/squid.conf.template
|
||||||
- ./ssrf_proxy/docker-entrypoint.sh:/docker-entrypoint-mount.sh
|
- ./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:
|
env_file:
|
||||||
- ./middleware.env
|
- ./middleware.env
|
||||||
environment:
|
environment:
|
||||||
@@ -160,7 +216,7 @@ services:
|
|||||||
|
|
||||||
# The Weaviate vector store.
|
# The Weaviate vector store.
|
||||||
weaviate:
|
weaviate:
|
||||||
image: semitechnologies/weaviate:1.19.0
|
image: semitechnologies/weaviate:1.27.0
|
||||||
profiles:
|
profiles:
|
||||||
- ""
|
- ""
|
||||||
- weaviate
|
- weaviate
|
||||||
@@ -183,8 +239,10 @@ services:
|
|||||||
AUTHENTICATION_APIKEY_USERS: ${WEAVIATE_AUTHENTICATION_APIKEY_USERS:-hello@dify.ai}
|
AUTHENTICATION_APIKEY_USERS: ${WEAVIATE_AUTHENTICATION_APIKEY_USERS:-hello@dify.ai}
|
||||||
AUTHORIZATION_ADMINLIST_ENABLED: ${WEAVIATE_AUTHORIZATION_ADMINLIST_ENABLED:-true}
|
AUTHORIZATION_ADMINLIST_ENABLED: ${WEAVIATE_AUTHORIZATION_ADMINLIST_ENABLED:-true}
|
||||||
AUTHORIZATION_ADMINLIST_USERS: ${WEAVIATE_AUTHORIZATION_ADMINLIST_USERS:-hello@dify.ai}
|
AUTHORIZATION_ADMINLIST_USERS: ${WEAVIATE_AUTHORIZATION_ADMINLIST_USERS:-hello@dify.ai}
|
||||||
|
DISABLE_TELEMETRY: ${WEAVIATE_DISABLE_TELEMETRY:-false}
|
||||||
ports:
|
ports:
|
||||||
- "${EXPOSE_WEAVIATE_PORT:-8080}:8080"
|
- "${EXPOSE_WEAVIATE_PORT:-8080}:8080"
|
||||||
|
- "${EXPOSE_WEAVIATE_GRPC_PORT:-50051}:50051"
|
||||||
|
|
||||||
networks:
|
networks:
|
||||||
# create a network between sandbox, api and ssrf_proxy, and can not access outside.
|
# create a network between sandbox, api and ssrf_proxy, and can not access outside.
|
||||||
|
|||||||
+444
-99
@@ -8,10 +8,16 @@ x-shared-env: &shared-api-worker-env
|
|||||||
CONSOLE_API_URL: ${CONSOLE_API_URL:-}
|
CONSOLE_API_URL: ${CONSOLE_API_URL:-}
|
||||||
CONSOLE_WEB_URL: ${CONSOLE_WEB_URL:-}
|
CONSOLE_WEB_URL: ${CONSOLE_WEB_URL:-}
|
||||||
SERVICE_API_URL: ${SERVICE_API_URL:-}
|
SERVICE_API_URL: ${SERVICE_API_URL:-}
|
||||||
|
TRIGGER_URL: ${TRIGGER_URL:-http://localhost}
|
||||||
APP_API_URL: ${APP_API_URL:-}
|
APP_API_URL: ${APP_API_URL:-}
|
||||||
APP_WEB_URL: ${APP_WEB_URL:-}
|
APP_WEB_URL: ${APP_WEB_URL:-}
|
||||||
FILES_URL: ${FILES_URL:-}
|
FILES_URL: ${FILES_URL:-}
|
||||||
|
INTERNAL_FILES_URL: ${INTERNAL_FILES_URL:-}
|
||||||
|
LANG: ${LANG:-C.UTF-8}
|
||||||
|
LC_ALL: ${LC_ALL:-C.UTF-8}
|
||||||
|
PYTHONIOENCODING: ${PYTHONIOENCODING:-utf-8}
|
||||||
LOG_LEVEL: ${LOG_LEVEL:-INFO}
|
LOG_LEVEL: ${LOG_LEVEL:-INFO}
|
||||||
|
LOG_OUTPUT_FORMAT: ${LOG_OUTPUT_FORMAT:-text}
|
||||||
LOG_FILE: ${LOG_FILE:-/app/logs/server.log}
|
LOG_FILE: ${LOG_FILE:-/app/logs/server.log}
|
||||||
LOG_FILE_MAX_SIZE: ${LOG_FILE_MAX_SIZE:-20}
|
LOG_FILE_MAX_SIZE: ${LOG_FILE_MAX_SIZE:-20}
|
||||||
LOG_FILE_BACKUP_COUNT: ${LOG_FILE_BACKUP_COUNT:-5}
|
LOG_FILE_BACKUP_COUNT: ${LOG_FILE_BACKUP_COUNT:-5}
|
||||||
@@ -29,6 +35,7 @@ x-shared-env: &shared-api-worker-env
|
|||||||
FILES_ACCESS_TIMEOUT: ${FILES_ACCESS_TIMEOUT:-300}
|
FILES_ACCESS_TIMEOUT: ${FILES_ACCESS_TIMEOUT:-300}
|
||||||
ACCESS_TOKEN_EXPIRE_MINUTES: ${ACCESS_TOKEN_EXPIRE_MINUTES:-60}
|
ACCESS_TOKEN_EXPIRE_MINUTES: ${ACCESS_TOKEN_EXPIRE_MINUTES:-60}
|
||||||
REFRESH_TOKEN_EXPIRE_DAYS: ${REFRESH_TOKEN_EXPIRE_DAYS:-30}
|
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_ACTIVE_REQUESTS: ${APP_MAX_ACTIVE_REQUESTS:-0}
|
||||||
APP_MAX_EXECUTION_TIME: ${APP_MAX_EXECUTION_TIME:-1200}
|
APP_MAX_EXECUTION_TIME: ${APP_MAX_EXECUTION_TIME:-1200}
|
||||||
DIFY_BIND_ADDRESS: ${DIFY_BIND_ADDRESS:-0.0.0.0}
|
DIFY_BIND_ADDRESS: ${DIFY_BIND_ADDRESS:-0.0.0.0}
|
||||||
@@ -47,24 +54,40 @@ x-shared-env: &shared-api-worker-env
|
|||||||
ENABLE_WEBSITE_JINAREADER: ${ENABLE_WEBSITE_JINAREADER:-true}
|
ENABLE_WEBSITE_JINAREADER: ${ENABLE_WEBSITE_JINAREADER:-true}
|
||||||
ENABLE_WEBSITE_FIRECRAWL: ${ENABLE_WEBSITE_FIRECRAWL:-true}
|
ENABLE_WEBSITE_FIRECRAWL: ${ENABLE_WEBSITE_FIRECRAWL:-true}
|
||||||
ENABLE_WEBSITE_WATERCRAWL: ${ENABLE_WEBSITE_WATERCRAWL:-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_USERNAME: ${DB_USERNAME:-postgres}
|
||||||
DB_PASSWORD: ${DB_PASSWORD:-difyai123456}
|
DB_PASSWORD: ${DB_PASSWORD:-difyai123456}
|
||||||
DB_HOST: ${DB_HOST:-db}
|
DB_HOST: ${DB_HOST:-db_postgres}
|
||||||
DB_PORT: ${DB_PORT:-5432}
|
DB_PORT: ${DB_PORT:-5432}
|
||||||
DB_DATABASE: ${DB_DATABASE:-dify}
|
DB_DATABASE: ${DB_DATABASE:-dify}
|
||||||
SQLALCHEMY_POOL_SIZE: ${SQLALCHEMY_POOL_SIZE:-30}
|
SQLALCHEMY_POOL_SIZE: ${SQLALCHEMY_POOL_SIZE:-30}
|
||||||
|
SQLALCHEMY_MAX_OVERFLOW: ${SQLALCHEMY_MAX_OVERFLOW:-10}
|
||||||
SQLALCHEMY_POOL_RECYCLE: ${SQLALCHEMY_POOL_RECYCLE:-3600}
|
SQLALCHEMY_POOL_RECYCLE: ${SQLALCHEMY_POOL_RECYCLE:-3600}
|
||||||
SQLALCHEMY_ECHO: ${SQLALCHEMY_ECHO:-false}
|
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_MAX_CONNECTIONS: ${POSTGRES_MAX_CONNECTIONS:-100}
|
||||||
POSTGRES_SHARED_BUFFERS: ${POSTGRES_SHARED_BUFFERS:-128MB}
|
POSTGRES_SHARED_BUFFERS: ${POSTGRES_SHARED_BUFFERS:-128MB}
|
||||||
POSTGRES_WORK_MEM: ${POSTGRES_WORK_MEM:-4MB}
|
POSTGRES_WORK_MEM: ${POSTGRES_WORK_MEM:-4MB}
|
||||||
POSTGRES_MAINTENANCE_WORK_MEM: ${POSTGRES_MAINTENANCE_WORK_MEM:-64MB}
|
POSTGRES_MAINTENANCE_WORK_MEM: ${POSTGRES_MAINTENANCE_WORK_MEM:-64MB}
|
||||||
POSTGRES_EFFECTIVE_CACHE_SIZE: ${POSTGRES_EFFECTIVE_CACHE_SIZE:-4096MB}
|
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_HOST: ${REDIS_HOST:-redis}
|
||||||
REDIS_PORT: ${REDIS_PORT:-6379}
|
REDIS_PORT: ${REDIS_PORT:-6379}
|
||||||
REDIS_USERNAME: ${REDIS_USERNAME:-}
|
REDIS_USERNAME: ${REDIS_USERNAME:-}
|
||||||
REDIS_PASSWORD: ${REDIS_PASSWORD:-difyai123456}
|
REDIS_PASSWORD: ${REDIS_PASSWORD:-difyai123456}
|
||||||
REDIS_USE_SSL: ${REDIS_USE_SSL:-false}
|
REDIS_USE_SSL: ${REDIS_USE_SSL:-false}
|
||||||
|
REDIS_SSL_CERT_REQS: ${REDIS_SSL_CERT_REQS:-CERT_NONE}
|
||||||
|
REDIS_SSL_CA_CERTS: ${REDIS_SSL_CA_CERTS:-}
|
||||||
|
REDIS_SSL_CERTFILE: ${REDIS_SSL_CERTFILE:-}
|
||||||
|
REDIS_SSL_KEYFILE: ${REDIS_SSL_KEYFILE:-}
|
||||||
REDIS_DB: ${REDIS_DB:-0}
|
REDIS_DB: ${REDIS_DB:-0}
|
||||||
REDIS_USE_SENTINEL: ${REDIS_USE_SENTINEL:-false}
|
REDIS_USE_SENTINEL: ${REDIS_USE_SENTINEL:-false}
|
||||||
REDIS_SENTINELS: ${REDIS_SENTINELS:-}
|
REDIS_SENTINELS: ${REDIS_SENTINELS:-}
|
||||||
@@ -76,6 +99,7 @@ x-shared-env: &shared-api-worker-env
|
|||||||
REDIS_CLUSTERS: ${REDIS_CLUSTERS:-}
|
REDIS_CLUSTERS: ${REDIS_CLUSTERS:-}
|
||||||
REDIS_CLUSTERS_PASSWORD: ${REDIS_CLUSTERS_PASSWORD:-}
|
REDIS_CLUSTERS_PASSWORD: ${REDIS_CLUSTERS_PASSWORD:-}
|
||||||
CELERY_BROKER_URL: ${CELERY_BROKER_URL:-redis://:difyai123456@redis:6379/1}
|
CELERY_BROKER_URL: ${CELERY_BROKER_URL:-redis://:difyai123456@redis:6379/1}
|
||||||
|
CELERY_BACKEND: ${CELERY_BACKEND:-redis}
|
||||||
BROKER_USE_SSL: ${BROKER_USE_SSL:-false}
|
BROKER_USE_SSL: ${BROKER_USE_SSL:-false}
|
||||||
CELERY_USE_SENTINEL: ${CELERY_USE_SENTINEL:-false}
|
CELERY_USE_SENTINEL: ${CELERY_USE_SENTINEL:-false}
|
||||||
CELERY_SENTINEL_MASTER_NAME: ${CELERY_SENTINEL_MASTER_NAME:-}
|
CELERY_SENTINEL_MASTER_NAME: ${CELERY_SENTINEL_MASTER_NAME:-}
|
||||||
@@ -83,15 +107,29 @@ x-shared-env: &shared-api-worker-env
|
|||||||
CELERY_SENTINEL_SOCKET_TIMEOUT: ${CELERY_SENTINEL_SOCKET_TIMEOUT:-0.1}
|
CELERY_SENTINEL_SOCKET_TIMEOUT: ${CELERY_SENTINEL_SOCKET_TIMEOUT:-0.1}
|
||||||
WEB_API_CORS_ALLOW_ORIGINS: ${WEB_API_CORS_ALLOW_ORIGINS:-*}
|
WEB_API_CORS_ALLOW_ORIGINS: ${WEB_API_CORS_ALLOW_ORIGINS:-*}
|
||||||
CONSOLE_CORS_ALLOW_ORIGINS: ${CONSOLE_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}
|
STORAGE_TYPE: ${STORAGE_TYPE:-opendal}
|
||||||
OPENDAL_SCHEME: ${OPENDAL_SCHEME:-fs}
|
OPENDAL_SCHEME: ${OPENDAL_SCHEME:-fs}
|
||||||
OPENDAL_FS_ROOT: ${OPENDAL_FS_ROOT:-storage}
|
OPENDAL_FS_ROOT: ${OPENDAL_FS_ROOT:-storage}
|
||||||
|
CLICKZETTA_VOLUME_TYPE: ${CLICKZETTA_VOLUME_TYPE:-user}
|
||||||
|
CLICKZETTA_VOLUME_NAME: ${CLICKZETTA_VOLUME_NAME:-}
|
||||||
|
CLICKZETTA_VOLUME_TABLE_PREFIX: ${CLICKZETTA_VOLUME_TABLE_PREFIX:-dataset_}
|
||||||
|
CLICKZETTA_VOLUME_DIFY_PREFIX: ${CLICKZETTA_VOLUME_DIFY_PREFIX:-dify_km}
|
||||||
S3_ENDPOINT: ${S3_ENDPOINT:-}
|
S3_ENDPOINT: ${S3_ENDPOINT:-}
|
||||||
S3_REGION: ${S3_REGION:-us-east-1}
|
S3_REGION: ${S3_REGION:-us-east-1}
|
||||||
S3_BUCKET_NAME: ${S3_BUCKET_NAME:-difyai}
|
S3_BUCKET_NAME: ${S3_BUCKET_NAME:-difyai}
|
||||||
S3_ACCESS_KEY: ${S3_ACCESS_KEY:-}
|
S3_ACCESS_KEY: ${S3_ACCESS_KEY:-}
|
||||||
S3_SECRET_KEY: ${S3_SECRET_KEY:-}
|
S3_SECRET_KEY: ${S3_SECRET_KEY:-}
|
||||||
S3_USE_AWS_MANAGED_IAM: ${S3_USE_AWS_MANAGED_IAM:-false}
|
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_NAME: ${AZURE_BLOB_ACCOUNT_NAME:-difyai}
|
||||||
AZURE_BLOB_ACCOUNT_KEY: ${AZURE_BLOB_ACCOUNT_KEY:-difyai}
|
AZURE_BLOB_ACCOUNT_KEY: ${AZURE_BLOB_ACCOUNT_KEY:-difyai}
|
||||||
AZURE_BLOB_CONTAINER_NAME: ${AZURE_BLOB_CONTAINER_NAME:-difyai-container}
|
AZURE_BLOB_CONTAINER_NAME: ${AZURE_BLOB_CONTAINER_NAME:-difyai-container}
|
||||||
@@ -105,11 +143,13 @@ x-shared-env: &shared-api-worker-env
|
|||||||
ALIYUN_OSS_REGION: ${ALIYUN_OSS_REGION:-ap-southeast-1}
|
ALIYUN_OSS_REGION: ${ALIYUN_OSS_REGION:-ap-southeast-1}
|
||||||
ALIYUN_OSS_AUTH_VERSION: ${ALIYUN_OSS_AUTH_VERSION:-v4}
|
ALIYUN_OSS_AUTH_VERSION: ${ALIYUN_OSS_AUTH_VERSION:-v4}
|
||||||
ALIYUN_OSS_PATH: ${ALIYUN_OSS_PATH:-your-path}
|
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_BUCKET_NAME: ${TENCENT_COS_BUCKET_NAME:-your-bucket-name}
|
||||||
TENCENT_COS_SECRET_KEY: ${TENCENT_COS_SECRET_KEY:-your-secret-key}
|
TENCENT_COS_SECRET_KEY: ${TENCENT_COS_SECRET_KEY:-your-secret-key}
|
||||||
TENCENT_COS_SECRET_ID: ${TENCENT_COS_SECRET_ID:-your-secret-id}
|
TENCENT_COS_SECRET_ID: ${TENCENT_COS_SECRET_ID:-your-secret-id}
|
||||||
TENCENT_COS_REGION: ${TENCENT_COS_REGION:-your-region}
|
TENCENT_COS_REGION: ${TENCENT_COS_REGION:-your-region}
|
||||||
TENCENT_COS_SCHEME: ${TENCENT_COS_SCHEME:-your-scheme}
|
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_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_BUCKET_NAME: ${OCI_BUCKET_NAME:-your-bucket-name}
|
||||||
OCI_ACCESS_KEY: ${OCI_ACCESS_KEY:-your-access-key}
|
OCI_ACCESS_KEY: ${OCI_ACCESS_KEY:-your-access-key}
|
||||||
@@ -119,6 +159,7 @@ x-shared-env: &shared-api-worker-env
|
|||||||
HUAWEI_OBS_SECRET_KEY: ${HUAWEI_OBS_SECRET_KEY:-your-secret-key}
|
HUAWEI_OBS_SECRET_KEY: ${HUAWEI_OBS_SECRET_KEY:-your-secret-key}
|
||||||
HUAWEI_OBS_ACCESS_KEY: ${HUAWEI_OBS_ACCESS_KEY:-your-access-key}
|
HUAWEI_OBS_ACCESS_KEY: ${HUAWEI_OBS_ACCESS_KEY:-your-access-key}
|
||||||
HUAWEI_OBS_SERVER: ${HUAWEI_OBS_SERVER:-your-server-url}
|
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_BUCKET_NAME: ${VOLCENGINE_TOS_BUCKET_NAME:-your-bucket-name}
|
||||||
VOLCENGINE_TOS_SECRET_KEY: ${VOLCENGINE_TOS_SECRET_KEY:-your-secret-key}
|
VOLCENGINE_TOS_SECRET_KEY: ${VOLCENGINE_TOS_SECRET_KEY:-your-secret-key}
|
||||||
VOLCENGINE_TOS_ACCESS_KEY: ${VOLCENGINE_TOS_ACCESS_KEY:-your-access-key}
|
VOLCENGINE_TOS_ACCESS_KEY: ${VOLCENGINE_TOS_ACCESS_KEY:-your-access-key}
|
||||||
@@ -132,8 +173,21 @@ x-shared-env: &shared-api-worker-env
|
|||||||
SUPABASE_API_KEY: ${SUPABASE_API_KEY:-your-access-key}
|
SUPABASE_API_KEY: ${SUPABASE_API_KEY:-your-access-key}
|
||||||
SUPABASE_URL: ${SUPABASE_URL:-your-server-url}
|
SUPABASE_URL: ${SUPABASE_URL:-your-server-url}
|
||||||
VECTOR_STORE: ${VECTOR_STORE:-weaviate}
|
VECTOR_STORE: ${VECTOR_STORE:-weaviate}
|
||||||
|
VECTOR_INDEX_NAME_PREFIX: ${VECTOR_INDEX_NAME_PREFIX:-Vector_index}
|
||||||
WEAVIATE_ENDPOINT: ${WEAVIATE_ENDPOINT:-http://weaviate:8080}
|
WEAVIATE_ENDPOINT: ${WEAVIATE_ENDPOINT:-http://weaviate:8080}
|
||||||
WEAVIATE_API_KEY: ${WEAVIATE_API_KEY:-WVF5YThaHlkYwhGUSmCRgsX3tD5ngdN8pkih}
|
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_URL: ${QDRANT_URL:-http://qdrant:6333}
|
||||||
QDRANT_API_KEY: ${QDRANT_API_KEY:-difyai123456}
|
QDRANT_API_KEY: ${QDRANT_API_KEY:-difyai123456}
|
||||||
QDRANT_CLIENT_TIMEOUT: ${QDRANT_CLIENT_TIMEOUT:-20}
|
QDRANT_CLIENT_TIMEOUT: ${QDRANT_CLIENT_TIMEOUT:-20}
|
||||||
@@ -226,6 +280,13 @@ x-shared-env: &shared-api-worker-env
|
|||||||
ORACLE_WALLET_LOCATION: ${ORACLE_WALLET_LOCATION:-/app/api/storage/wallet}
|
ORACLE_WALLET_LOCATION: ${ORACLE_WALLET_LOCATION:-/app/api/storage/wallet}
|
||||||
ORACLE_WALLET_PASSWORD: ${ORACLE_WALLET_PASSWORD:-dify}
|
ORACLE_WALLET_PASSWORD: ${ORACLE_WALLET_PASSWORD:-dify}
|
||||||
ORACLE_IS_AUTONOMOUS: ${ORACLE_IS_AUTONOMOUS:-false}
|
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_HOST: ${RELYT_HOST:-db}
|
||||||
RELYT_PORT: ${RELYT_PORT:-5432}
|
RELYT_PORT: ${RELYT_PORT:-5432}
|
||||||
RELYT_USER: ${RELYT_USER:-postgres}
|
RELYT_USER: ${RELYT_USER:-postgres}
|
||||||
@@ -253,6 +314,14 @@ x-shared-env: &shared-api-worker-env
|
|||||||
ELASTICSEARCH_USERNAME: ${ELASTICSEARCH_USERNAME:-elastic}
|
ELASTICSEARCH_USERNAME: ${ELASTICSEARCH_USERNAME:-elastic}
|
||||||
ELASTICSEARCH_PASSWORD: ${ELASTICSEARCH_PASSWORD:-elastic}
|
ELASTICSEARCH_PASSWORD: ${ELASTICSEARCH_PASSWORD:-elastic}
|
||||||
KIBANA_PORT: ${KIBANA_PORT:-5601}
|
KIBANA_PORT: ${KIBANA_PORT:-5601}
|
||||||
|
ELASTICSEARCH_USE_CLOUD: ${ELASTICSEARCH_USE_CLOUD:-false}
|
||||||
|
ELASTICSEARCH_CLOUD_URL: ${ELASTICSEARCH_CLOUD_URL:-YOUR-ELASTICSEARCH_CLOUD_URL}
|
||||||
|
ELASTICSEARCH_API_KEY: ${ELASTICSEARCH_API_KEY:-YOUR-ELASTICSEARCH_API_KEY}
|
||||||
|
ELASTICSEARCH_VERIFY_CERTS: ${ELASTICSEARCH_VERIFY_CERTS:-False}
|
||||||
|
ELASTICSEARCH_CA_CERTS: ${ELASTICSEARCH_CA_CERTS:-}
|
||||||
|
ELASTICSEARCH_REQUEST_TIMEOUT: ${ELASTICSEARCH_REQUEST_TIMEOUT:-100000}
|
||||||
|
ELASTICSEARCH_RETRY_ON_TIMEOUT: ${ELASTICSEARCH_RETRY_ON_TIMEOUT:-True}
|
||||||
|
ELASTICSEARCH_MAX_RETRIES: ${ELASTICSEARCH_MAX_RETRIES:-10}
|
||||||
BAIDU_VECTOR_DB_ENDPOINT: ${BAIDU_VECTOR_DB_ENDPOINT:-http://127.0.0.1:5287}
|
BAIDU_VECTOR_DB_ENDPOINT: ${BAIDU_VECTOR_DB_ENDPOINT:-http://127.0.0.1:5287}
|
||||||
BAIDU_VECTOR_DB_CONNECTION_TIMEOUT_MS: ${BAIDU_VECTOR_DB_CONNECTION_TIMEOUT_MS:-30000}
|
BAIDU_VECTOR_DB_CONNECTION_TIMEOUT_MS: ${BAIDU_VECTOR_DB_CONNECTION_TIMEOUT_MS:-30000}
|
||||||
BAIDU_VECTOR_DB_ACCOUNT: ${BAIDU_VECTOR_DB_ACCOUNT:-root}
|
BAIDU_VECTOR_DB_ACCOUNT: ${BAIDU_VECTOR_DB_ACCOUNT:-root}
|
||||||
@@ -260,6 +329,8 @@ x-shared-env: &shared-api-worker-env
|
|||||||
BAIDU_VECTOR_DB_DATABASE: ${BAIDU_VECTOR_DB_DATABASE:-dify}
|
BAIDU_VECTOR_DB_DATABASE: ${BAIDU_VECTOR_DB_DATABASE:-dify}
|
||||||
BAIDU_VECTOR_DB_SHARD: ${BAIDU_VECTOR_DB_SHARD:-1}
|
BAIDU_VECTOR_DB_SHARD: ${BAIDU_VECTOR_DB_SHARD:-1}
|
||||||
BAIDU_VECTOR_DB_REPLICAS: ${BAIDU_VECTOR_DB_REPLICAS:-3}
|
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_ACCESS_KEY: ${VIKINGDB_ACCESS_KEY:-your-ak}
|
||||||
VIKINGDB_SECRET_KEY: ${VIKINGDB_SECRET_KEY:-your-sk}
|
VIKINGDB_SECRET_KEY: ${VIKINGDB_SECRET_KEY:-your-sk}
|
||||||
VIKINGDB_REGION: ${VIKINGDB_REGION:-cn-shanghai}
|
VIKINGDB_REGION: ${VIKINGDB_REGION:-cn-shanghai}
|
||||||
@@ -267,18 +338,11 @@ x-shared-env: &shared-api-worker-env
|
|||||||
VIKINGDB_SCHEMA: ${VIKINGDB_SCHEMA:-http}
|
VIKINGDB_SCHEMA: ${VIKINGDB_SCHEMA:-http}
|
||||||
VIKINGDB_CONNECTION_TIMEOUT: ${VIKINGDB_CONNECTION_TIMEOUT:-30}
|
VIKINGDB_CONNECTION_TIMEOUT: ${VIKINGDB_CONNECTION_TIMEOUT:-30}
|
||||||
VIKINGDB_SOCKET_TIMEOUT: ${VIKINGDB_SOCKET_TIMEOUT:-30}
|
VIKINGDB_SOCKET_TIMEOUT: ${VIKINGDB_SOCKET_TIMEOUT:-30}
|
||||||
LINDORM_URL: ${LINDORM_URL:-http://lindorm:30070}
|
LINDORM_URL: ${LINDORM_URL:-http://localhost:30070}
|
||||||
LINDORM_USERNAME: ${LINDORM_USERNAME:-lindorm}
|
LINDORM_USERNAME: ${LINDORM_USERNAME:-admin}
|
||||||
LINDORM_PASSWORD: ${LINDORM_PASSWORD:-lindorm}
|
LINDORM_PASSWORD: ${LINDORM_PASSWORD:-admin}
|
||||||
|
LINDORM_USING_UGC: ${LINDORM_USING_UGC:-True}
|
||||||
LINDORM_QUERY_TIMEOUT: ${LINDORM_QUERY_TIMEOUT:-1}
|
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_HOST: ${OPENGAUSS_HOST:-opengauss}
|
||||||
OPENGAUSS_PORT: ${OPENGAUSS_PORT:-6600}
|
OPENGAUSS_PORT: ${OPENGAUSS_PORT:-6600}
|
||||||
OPENGAUSS_USER: ${OPENGAUSS_USER:-postgres}
|
OPENGAUSS_USER: ${OPENGAUSS_USER:-postgres}
|
||||||
@@ -296,8 +360,39 @@ x-shared-env: &shared-api-worker-env
|
|||||||
TABLESTORE_INSTANCE_NAME: ${TABLESTORE_INSTANCE_NAME:-instance-name}
|
TABLESTORE_INSTANCE_NAME: ${TABLESTORE_INSTANCE_NAME:-instance-name}
|
||||||
TABLESTORE_ACCESS_KEY_ID: ${TABLESTORE_ACCESS_KEY_ID:-xxx}
|
TABLESTORE_ACCESS_KEY_ID: ${TABLESTORE_ACCESS_KEY_ID:-xxx}
|
||||||
TABLESTORE_ACCESS_KEY_SECRET: ${TABLESTORE_ACCESS_KEY_SECRET:-xxx}
|
TABLESTORE_ACCESS_KEY_SECRET: ${TABLESTORE_ACCESS_KEY_SECRET:-xxx}
|
||||||
|
TABLESTORE_NORMALIZE_FULLTEXT_BM25_SCORE: ${TABLESTORE_NORMALIZE_FULLTEXT_BM25_SCORE:-false}
|
||||||
|
CLICKZETTA_USERNAME: ${CLICKZETTA_USERNAME:-}
|
||||||
|
CLICKZETTA_PASSWORD: ${CLICKZETTA_PASSWORD:-}
|
||||||
|
CLICKZETTA_INSTANCE: ${CLICKZETTA_INSTANCE:-}
|
||||||
|
CLICKZETTA_SERVICE: ${CLICKZETTA_SERVICE:-api.clickzetta.com}
|
||||||
|
CLICKZETTA_WORKSPACE: ${CLICKZETTA_WORKSPACE:-quick_start}
|
||||||
|
CLICKZETTA_VCLUSTER: ${CLICKZETTA_VCLUSTER:-default_ap}
|
||||||
|
CLICKZETTA_SCHEMA: ${CLICKZETTA_SCHEMA:-dify}
|
||||||
|
CLICKZETTA_BATCH_SIZE: ${CLICKZETTA_BATCH_SIZE:-100}
|
||||||
|
CLICKZETTA_ENABLE_INVERTED_INDEX: ${CLICKZETTA_ENABLE_INVERTED_INDEX:-true}
|
||||||
|
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_SIZE_LIMIT: ${UPLOAD_FILE_SIZE_LIMIT:-15}
|
||||||
UPLOAD_FILE_BATCH_LIMIT: ${UPLOAD_FILE_BATCH_LIMIT:-5}
|
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}
|
ETL_TYPE: ${ETL_TYPE:-dify}
|
||||||
UNSTRUCTURED_API_URL: ${UNSTRUCTURED_API_URL:-}
|
UNSTRUCTURED_API_URL: ${UNSTRUCTURED_API_URL:-}
|
||||||
UNSTRUCTURED_API_KEY: ${UNSTRUCTURED_API_KEY:-}
|
UNSTRUCTURED_API_KEY: ${UNSTRUCTURED_API_KEY:-}
|
||||||
@@ -314,6 +409,8 @@ x-shared-env: &shared-api-worker-env
|
|||||||
API_SENTRY_TRACES_SAMPLE_RATE: ${API_SENTRY_TRACES_SAMPLE_RATE:-1.0}
|
API_SENTRY_TRACES_SAMPLE_RATE: ${API_SENTRY_TRACES_SAMPLE_RATE:-1.0}
|
||||||
API_SENTRY_PROFILES_SAMPLE_RATE: ${API_SENTRY_PROFILES_SAMPLE_RATE:-1.0}
|
API_SENTRY_PROFILES_SAMPLE_RATE: ${API_SENTRY_PROFILES_SAMPLE_RATE:-1.0}
|
||||||
WEB_SENTRY_DSN: ${WEB_SENTRY_DSN:-}
|
WEB_SENTRY_DSN: ${WEB_SENTRY_DSN:-}
|
||||||
|
PLUGIN_SENTRY_ENABLED: ${PLUGIN_SENTRY_ENABLED:-false}
|
||||||
|
PLUGIN_SENTRY_DSN: ${PLUGIN_SENTRY_DSN:-}
|
||||||
NOTION_INTEGRATION_TYPE: ${NOTION_INTEGRATION_TYPE:-public}
|
NOTION_INTEGRATION_TYPE: ${NOTION_INTEGRATION_TYPE:-public}
|
||||||
NOTION_CLIENT_SECRET: ${NOTION_CLIENT_SECRET:-}
|
NOTION_CLIENT_SECRET: ${NOTION_CLIENT_SECRET:-}
|
||||||
NOTION_CLIENT_ID: ${NOTION_CLIENT_ID:-}
|
NOTION_CLIENT_ID: ${NOTION_CLIENT_ID:-}
|
||||||
@@ -328,34 +425,65 @@ x-shared-env: &shared-api-worker-env
|
|||||||
SMTP_PASSWORD: ${SMTP_PASSWORD:-}
|
SMTP_PASSWORD: ${SMTP_PASSWORD:-}
|
||||||
SMTP_USE_TLS: ${SMTP_USE_TLS:-true}
|
SMTP_USE_TLS: ${SMTP_USE_TLS:-true}
|
||||||
SMTP_OPPORTUNISTIC_TLS: ${SMTP_OPPORTUNISTIC_TLS:-false}
|
SMTP_OPPORTUNISTIC_TLS: ${SMTP_OPPORTUNISTIC_TLS:-false}
|
||||||
|
SMTP_LOCAL_HOSTNAME: ${SMTP_LOCAL_HOSTNAME:-}
|
||||||
SENDGRID_API_KEY: ${SENDGRID_API_KEY:-}
|
SENDGRID_API_KEY: ${SENDGRID_API_KEY:-}
|
||||||
INDEXING_MAX_SEGMENTATION_TOKENS_LENGTH: ${INDEXING_MAX_SEGMENTATION_TOKENS_LENGTH:-4000}
|
INDEXING_MAX_SEGMENTATION_TOKENS_LENGTH: ${INDEXING_MAX_SEGMENTATION_TOKENS_LENGTH:-4000}
|
||||||
INVITE_EXPIRY_HOURS: ${INVITE_EXPIRY_HOURS:-72}
|
INVITE_EXPIRY_HOURS: ${INVITE_EXPIRY_HOURS:-72}
|
||||||
RESET_PASSWORD_TOKEN_EXPIRY_MINUTES: ${RESET_PASSWORD_TOKEN_EXPIRY_MINUTES:-5}
|
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_ENDPOINT: ${CODE_EXECUTION_ENDPOINT:-http://sandbox:8194}
|
||||||
CODE_EXECUTION_API_KEY: ${CODE_EXECUTION_API_KEY:-dify-sandbox}
|
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_MAX_NUMBER: ${CODE_MAX_NUMBER:-9223372036854775807}
|
||||||
CODE_MIN_NUMBER: ${CODE_MIN_NUMBER:--9223372036854775808}
|
CODE_MIN_NUMBER: ${CODE_MIN_NUMBER:--9223372036854775808}
|
||||||
CODE_MAX_DEPTH: ${CODE_MAX_DEPTH:-5}
|
CODE_MAX_DEPTH: ${CODE_MAX_DEPTH:-5}
|
||||||
CODE_MAX_PRECISION: ${CODE_MAX_PRECISION:-20}
|
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_STRING_ARRAY_LENGTH: ${CODE_MAX_STRING_ARRAY_LENGTH:-30}
|
||||||
CODE_MAX_OBJECT_ARRAY_LENGTH: ${CODE_MAX_OBJECT_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_MAX_NUMBER_ARRAY_LENGTH: ${CODE_MAX_NUMBER_ARRAY_LENGTH:-1000}
|
||||||
CODE_EXECUTION_CONNECT_TIMEOUT: ${CODE_EXECUTION_CONNECT_TIMEOUT:-10}
|
CODE_EXECUTION_CONNECT_TIMEOUT: ${CODE_EXECUTION_CONNECT_TIMEOUT:-10}
|
||||||
CODE_EXECUTION_READ_TIMEOUT: ${CODE_EXECUTION_READ_TIMEOUT:-60}
|
CODE_EXECUTION_READ_TIMEOUT: ${CODE_EXECUTION_READ_TIMEOUT:-60}
|
||||||
CODE_EXECUTION_WRITE_TIMEOUT: ${CODE_EXECUTION_WRITE_TIMEOUT:-10}
|
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_STEPS: ${WORKFLOW_MAX_EXECUTION_STEPS:-500}
|
||||||
WORKFLOW_MAX_EXECUTION_TIME: ${WORKFLOW_MAX_EXECUTION_TIME:-1200}
|
WORKFLOW_MAX_EXECUTION_TIME: ${WORKFLOW_MAX_EXECUTION_TIME:-1200}
|
||||||
WORKFLOW_CALL_MAX_DEPTH: ${WORKFLOW_CALL_MAX_DEPTH:-5}
|
WORKFLOW_CALL_MAX_DEPTH: ${WORKFLOW_CALL_MAX_DEPTH:-5}
|
||||||
MAX_VARIABLE_SIZE: ${MAX_VARIABLE_SIZE:-204800}
|
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}
|
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}
|
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}
|
||||||
|
API_WORKFLOW_RUN_REPOSITORY: ${API_WORKFLOW_RUN_REPOSITORY:-repositories.sqlalchemy_api_workflow_run_repository.DifyAPISQLAlchemyWorkflowRunRepository}
|
||||||
|
API_WORKFLOW_NODE_EXECUTION_REPOSITORY: ${API_WORKFLOW_NODE_EXECUTION_REPOSITORY:-repositories.sqlalchemy_api_workflow_node_execution_repository.DifyAPISQLAlchemyWorkflowNodeExecutionRepository}
|
||||||
|
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}
|
||||||
|
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_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_MAX_TEXT_SIZE: ${HTTP_REQUEST_NODE_MAX_TEXT_SIZE:-1048576}
|
||||||
HTTP_REQUEST_NODE_SSL_VERIFY: ${HTTP_REQUEST_NODE_SSL_VERIFY:-True}
|
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}
|
RESPECT_XFORWARD_HEADERS_ENABLED: ${RESPECT_XFORWARD_HEADERS_ENABLED:-false}
|
||||||
SSRF_PROXY_HTTP_URL: ${SSRF_PROXY_HTTP_URL:-http://ssrf_proxy:3128}
|
SSRF_PROXY_HTTP_URL: ${SSRF_PROXY_HTTP_URL:-http://ssrf_proxy:3128}
|
||||||
SSRF_PROXY_HTTPS_URL: ${SSRF_PROXY_HTTPS_URL:-http://ssrf_proxy:3128}
|
SSRF_PROXY_HTTPS_URL: ${SSRF_PROXY_HTTPS_URL:-http://ssrf_proxy:3128}
|
||||||
@@ -364,10 +492,10 @@ x-shared-env: &shared-api-worker-env
|
|||||||
MAX_PARALLEL_LIMIT: ${MAX_PARALLEL_LIMIT:-10}
|
MAX_PARALLEL_LIMIT: ${MAX_PARALLEL_LIMIT:-10}
|
||||||
MAX_ITERATIONS_NUM: ${MAX_ITERATIONS_NUM:-99}
|
MAX_ITERATIONS_NUM: ${MAX_ITERATIONS_NUM:-99}
|
||||||
TEXT_GENERATION_TIMEOUT_MS: ${TEXT_GENERATION_TIMEOUT_MS:-60000}
|
TEXT_GENERATION_TIMEOUT_MS: ${TEXT_GENERATION_TIMEOUT_MS:-60000}
|
||||||
POSTGRES_USER: ${POSTGRES_USER:-${DB_USERNAME}}
|
ALLOW_UNSAFE_DATA_SCHEME: ${ALLOW_UNSAFE_DATA_SCHEME:-false}
|
||||||
POSTGRES_PASSWORD: ${POSTGRES_PASSWORD:-${DB_PASSWORD}}
|
MAX_TREE_DEPTH: ${MAX_TREE_DEPTH:-50}
|
||||||
POSTGRES_DB: ${POSTGRES_DB:-${DB_DATABASE}}
|
|
||||||
PGDATA: ${PGDATA:-/var/lib/postgresql/data/pgdata}
|
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_API_KEY: ${SANDBOX_API_KEY:-dify-sandbox}
|
||||||
SANDBOX_GIN_MODE: ${SANDBOX_GIN_MODE:-release}
|
SANDBOX_GIN_MODE: ${SANDBOX_GIN_MODE:-release}
|
||||||
SANDBOX_WORKER_TIMEOUT: ${SANDBOX_WORKER_TIMEOUT:-15}
|
SANDBOX_WORKER_TIMEOUT: ${SANDBOX_WORKER_TIMEOUT:-15}
|
||||||
@@ -385,6 +513,10 @@ x-shared-env: &shared-api-worker-env
|
|||||||
WEAVIATE_AUTHENTICATION_APIKEY_USERS: ${WEAVIATE_AUTHENTICATION_APIKEY_USERS:-hello@dify.ai}
|
WEAVIATE_AUTHENTICATION_APIKEY_USERS: ${WEAVIATE_AUTHENTICATION_APIKEY_USERS:-hello@dify.ai}
|
||||||
WEAVIATE_AUTHORIZATION_ADMINLIST_ENABLED: ${WEAVIATE_AUTHORIZATION_ADMINLIST_ENABLED:-true}
|
WEAVIATE_AUTHORIZATION_ADMINLIST_ENABLED: ${WEAVIATE_AUTHORIZATION_ADMINLIST_ENABLED:-true}
|
||||||
WEAVIATE_AUTHORIZATION_ADMINLIST_USERS: ${WEAVIATE_AUTHORIZATION_ADMINLIST_USERS:-hello@dify.ai}
|
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_CREDENTIALS: ${CHROMA_SERVER_AUTHN_CREDENTIALS:-difyai123456}
|
||||||
CHROMA_SERVER_AUTHN_PROVIDER: ${CHROMA_SERVER_AUTHN_PROVIDER:-chromadb.auth.token_authn.TokenAuthenticationServerProvider}
|
CHROMA_SERVER_AUTHN_PROVIDER: ${CHROMA_SERVER_AUTHN_PROVIDER:-chromadb.auth.token_authn.TokenAuthenticationServerProvider}
|
||||||
CHROMA_IS_PERSISTENT: ${CHROMA_IS_PERSISTENT:-TRUE}
|
CHROMA_IS_PERSISTENT: ${CHROMA_IS_PERSISTENT:-TRUE}
|
||||||
@@ -418,9 +550,9 @@ x-shared-env: &shared-api-worker-env
|
|||||||
NGINX_SSL_PORT: ${NGINX_SSL_PORT:-443}
|
NGINX_SSL_PORT: ${NGINX_SSL_PORT:-443}
|
||||||
NGINX_SSL_CERT_FILENAME: ${NGINX_SSL_CERT_FILENAME:-dify.crt}
|
NGINX_SSL_CERT_FILENAME: ${NGINX_SSL_CERT_FILENAME:-dify.crt}
|
||||||
NGINX_SSL_CERT_KEY_FILENAME: ${NGINX_SSL_CERT_KEY_FILENAME:-dify.key}
|
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_WORKER_PROCESSES: ${NGINX_WORKER_PROCESSES:-auto}
|
||||||
NGINX_CLIENT_MAX_BODY_SIZE: ${NGINX_CLIENT_MAX_BODY_SIZE:-15M}
|
NGINX_CLIENT_MAX_BODY_SIZE: ${NGINX_CLIENT_MAX_BODY_SIZE:-100M}
|
||||||
NGINX_KEEPALIVE_TIMEOUT: ${NGINX_KEEPALIVE_TIMEOUT:-65}
|
NGINX_KEEPALIVE_TIMEOUT: ${NGINX_KEEPALIVE_TIMEOUT:-65}
|
||||||
NGINX_PROXY_READ_TIMEOUT: ${NGINX_PROXY_READ_TIMEOUT:-3600s}
|
NGINX_PROXY_READ_TIMEOUT: ${NGINX_PROXY_READ_TIMEOUT:-3600s}
|
||||||
NGINX_PROXY_SEND_TIMEOUT: ${NGINX_PROXY_SEND_TIMEOUT:-3600s}
|
NGINX_PROXY_SEND_TIMEOUT: ${NGINX_PROXY_SEND_TIMEOUT:-3600s}
|
||||||
@@ -436,6 +568,9 @@ x-shared-env: &shared-api-worker-env
|
|||||||
SSRF_DEFAULT_CONNECT_TIME_OUT: ${SSRF_DEFAULT_CONNECT_TIME_OUT:-5}
|
SSRF_DEFAULT_CONNECT_TIME_OUT: ${SSRF_DEFAULT_CONNECT_TIME_OUT:-5}
|
||||||
SSRF_DEFAULT_READ_TIME_OUT: ${SSRF_DEFAULT_READ_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_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_PORT: ${EXPOSE_NGINX_PORT:-80}
|
||||||
EXPOSE_NGINX_SSL_PORT: ${EXPOSE_NGINX_SSL_PORT:-443}
|
EXPOSE_NGINX_SSL_PORT: ${EXPOSE_NGINX_SSL_PORT:-443}
|
||||||
POSITION_TOOL_PINS: ${POSITION_TOOL_PINS:-}
|
POSITION_TOOL_PINS: ${POSITION_TOOL_PINS:-}
|
||||||
@@ -465,8 +600,12 @@ x-shared-env: &shared-api-worker-env
|
|||||||
MARKETPLACE_ENABLED: ${MARKETPLACE_ENABLED:-true}
|
MARKETPLACE_ENABLED: ${MARKETPLACE_ENABLED:-true}
|
||||||
MARKETPLACE_API_URL: ${MARKETPLACE_API_URL:-https://marketplace.dify.ai}
|
MARKETPLACE_API_URL: ${MARKETPLACE_API_URL:-https://marketplace.dify.ai}
|
||||||
FORCE_VERIFYING_SIGNATURE: ${FORCE_VERIFYING_SIGNATURE:-true}
|
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_PYTHON_ENV_INIT_TIMEOUT: ${PLUGIN_PYTHON_ENV_INIT_TIMEOUT:-120}
|
||||||
PLUGIN_MAX_EXECUTION_TIMEOUT: ${PLUGIN_MAX_EXECUTION_TIMEOUT:-600}
|
PLUGIN_MAX_EXECUTION_TIMEOUT: ${PLUGIN_MAX_EXECUTION_TIMEOUT:-600}
|
||||||
|
PLUGIN_DAEMON_TIMEOUT: ${PLUGIN_DAEMON_TIMEOUT:-600.0}
|
||||||
PIP_MIRROR_URL: ${PIP_MIRROR_URL:-}
|
PIP_MIRROR_URL: ${PIP_MIRROR_URL:-}
|
||||||
PLUGIN_STORAGE_TYPE: ${PLUGIN_STORAGE_TYPE:-local}
|
PLUGIN_STORAGE_TYPE: ${PLUGIN_STORAGE_TYPE:-local}
|
||||||
PLUGIN_STORAGE_LOCAL_ROOT: ${PLUGIN_STORAGE_LOCAL_ROOT:-/app/storage}
|
PLUGIN_STORAGE_LOCAL_ROOT: ${PLUGIN_STORAGE_LOCAL_ROOT:-/app/storage}
|
||||||
@@ -498,6 +637,8 @@ x-shared-env: &shared-api-worker-env
|
|||||||
PLUGIN_VOLCENGINE_TOS_SECRET_KEY: ${PLUGIN_VOLCENGINE_TOS_SECRET_KEY:-}
|
PLUGIN_VOLCENGINE_TOS_SECRET_KEY: ${PLUGIN_VOLCENGINE_TOS_SECRET_KEY:-}
|
||||||
PLUGIN_VOLCENGINE_TOS_REGION: ${PLUGIN_VOLCENGINE_TOS_REGION:-}
|
PLUGIN_VOLCENGINE_TOS_REGION: ${PLUGIN_VOLCENGINE_TOS_REGION:-}
|
||||||
ENABLE_OTEL: ${ENABLE_OTEL:-false}
|
ENABLE_OTEL: ${ENABLE_OTEL:-false}
|
||||||
|
OTLP_TRACE_ENDPOINT: ${OTLP_TRACE_ENDPOINT:-}
|
||||||
|
OTLP_METRIC_ENDPOINT: ${OTLP_METRIC_ENDPOINT:-}
|
||||||
OTLP_BASE_ENDPOINT: ${OTLP_BASE_ENDPOINT:-http://localhost:4318}
|
OTLP_BASE_ENDPOINT: ${OTLP_BASE_ENDPOINT:-http://localhost:4318}
|
||||||
OTLP_API_KEY: ${OTLP_API_KEY:-}
|
OTLP_API_KEY: ${OTLP_API_KEY:-}
|
||||||
OTEL_EXPORTER_OTLP_PROTOCOL: ${OTEL_EXPORTER_OTLP_PROTOCOL:-}
|
OTEL_EXPORTER_OTLP_PROTOCOL: ${OTEL_EXPORTER_OTLP_PROTOCOL:-}
|
||||||
@@ -513,11 +654,58 @@ x-shared-env: &shared-api-worker-env
|
|||||||
QUEUE_MONITOR_THRESHOLD: ${QUEUE_MONITOR_THRESHOLD:-200}
|
QUEUE_MONITOR_THRESHOLD: ${QUEUE_MONITOR_THRESHOLD:-200}
|
||||||
QUEUE_MONITOR_ALERT_EMAILS: ${QUEUE_MONITOR_ALERT_EMAILS:-}
|
QUEUE_MONITOR_ALERT_EMAILS: ${QUEUE_MONITOR_ALERT_EMAILS:-}
|
||||||
QUEUE_MONITOR_INTERVAL: ${QUEUE_MONITOR_INTERVAL:-30}
|
QUEUE_MONITOR_INTERVAL: ${QUEUE_MONITOR_INTERVAL:-30}
|
||||||
|
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_RETENTION_DAYS: ${SANDBOX_EXPIRED_RECORDS_RETENTION_DAYS:-30}
|
||||||
|
|
||||||
services:
|
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 service
|
||||||
api:
|
api:
|
||||||
image: langgenius/dify-api:1.5.1
|
image: langgenius/dify-api:1.11.4
|
||||||
restart: always
|
restart: always
|
||||||
environment:
|
environment:
|
||||||
# Use the shared environment variables.
|
# Use the shared environment variables.
|
||||||
@@ -530,10 +718,23 @@ services:
|
|||||||
PLUGIN_REMOTE_INSTALL_HOST: ${EXPOSE_PLUGIN_DEBUGGING_HOST:-localhost}
|
PLUGIN_REMOTE_INSTALL_HOST: ${EXPOSE_PLUGIN_DEBUGGING_HOST:-localhost}
|
||||||
PLUGIN_REMOTE_INSTALL_PORT: ${EXPOSE_PLUGIN_DEBUGGING_PORT:-5003}
|
PLUGIN_REMOTE_INSTALL_PORT: ${EXPOSE_PLUGIN_DEBUGGING_PORT:-5003}
|
||||||
PLUGIN_MAX_PACKAGE_SIZE: ${PLUGIN_MAX_PACKAGE_SIZE:-52428800}
|
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}
|
INNER_API_KEY_FOR_PLUGIN: ${PLUGIN_DIFY_INNER_API_KEY:-QaHbTe77CtuXmsfyhR7+vRjI/+XbV1AaFy691iy+kGDv2Jvy0/eAh8Y1}
|
||||||
depends_on:
|
depends_on:
|
||||||
db:
|
init_permissions:
|
||||||
|
condition: service_completed_successfully
|
||||||
|
db_postgres:
|
||||||
condition: service_healthy
|
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:
|
redis:
|
||||||
condition: service_started
|
condition: service_started
|
||||||
volumes:
|
volumes:
|
||||||
@@ -544,14 +745,14 @@ services:
|
|||||||
- default
|
- default
|
||||||
|
|
||||||
# worker service
|
# worker service
|
||||||
# The Celery worker for processing the queue.
|
# The Celery worker for processing all queues (dataset, workflow, mail, etc.)
|
||||||
worker:
|
worker:
|
||||||
image: langgenius/dify-api:1.5.1
|
image: langgenius/dify-api:1.11.4
|
||||||
restart: always
|
restart: always
|
||||||
environment:
|
environment:
|
||||||
# Use the shared environment variables.
|
# Use the shared environment variables.
|
||||||
<<: *shared-api-worker-env
|
<<: *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
|
MODE: worker
|
||||||
SENTRY_DSN: ${API_SENTRY_DSN:-}
|
SENTRY_DSN: ${API_SENTRY_DSN:-}
|
||||||
SENTRY_TRACES_SAMPLE_RATE: ${API_SENTRY_TRACES_SAMPLE_RATE:-1.0}
|
SENTRY_TRACES_SAMPLE_RATE: ${API_SENTRY_TRACES_SAMPLE_RATE:-1.0}
|
||||||
@@ -559,8 +760,20 @@ services:
|
|||||||
PLUGIN_MAX_PACKAGE_SIZE: ${PLUGIN_MAX_PACKAGE_SIZE:-52428800}
|
PLUGIN_MAX_PACKAGE_SIZE: ${PLUGIN_MAX_PACKAGE_SIZE:-52428800}
|
||||||
INNER_API_KEY_FOR_PLUGIN: ${PLUGIN_DIFY_INNER_API_KEY:-QaHbTe77CtuXmsfyhR7+vRjI/+XbV1AaFy691iy+kGDv2Jvy0/eAh8Y1}
|
INNER_API_KEY_FOR_PLUGIN: ${PLUGIN_DIFY_INNER_API_KEY:-QaHbTe77CtuXmsfyhR7+vRjI/+XbV1AaFy691iy+kGDv2Jvy0/eAh8Y1}
|
||||||
depends_on:
|
depends_on:
|
||||||
db:
|
init_permissions:
|
||||||
|
condition: service_completed_successfully
|
||||||
|
db_postgres:
|
||||||
condition: service_healthy
|
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:
|
redis:
|
||||||
condition: service_started
|
condition: service_started
|
||||||
volumes:
|
volumes:
|
||||||
@@ -570,18 +783,52 @@ services:
|
|||||||
- ssrf_proxy_network
|
- ssrf_proxy_network
|
||||||
- default
|
- default
|
||||||
|
|
||||||
|
# worker_beat service
|
||||||
|
# Celery beat for scheduling periodic tasks.
|
||||||
|
worker_beat:
|
||||||
|
image: langgenius/dify-api:1.11.4
|
||||||
|
restart: always
|
||||||
|
environment:
|
||||||
|
# Use the shared environment variables.
|
||||||
|
<<: *shared-api-worker-env
|
||||||
|
# Startup mode, 'worker_beat' starts the Celery beat for scheduling periodic tasks.
|
||||||
|
MODE: beat
|
||||||
|
depends_on:
|
||||||
|
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:
|
||||||
|
- ssrf_proxy_network
|
||||||
|
- default
|
||||||
|
|
||||||
# Frontend web application.
|
# Frontend web application.
|
||||||
web:
|
web:
|
||||||
image: langgenius/dify-web:1.5.1
|
image: langgenius/dify-web:1.11.4
|
||||||
restart: always
|
restart: always
|
||||||
environment:
|
environment:
|
||||||
CONSOLE_API_URL: ${CONSOLE_API_URL:-}
|
CONSOLE_API_URL: ${CONSOLE_API_URL:-}
|
||||||
APP_API_URL: ${APP_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:-}
|
SENTRY_DSN: ${WEB_SENTRY_DSN:-}
|
||||||
NEXT_TELEMETRY_DISABLED: ${NEXT_TELEMETRY_DISABLED:-0}
|
NEXT_TELEMETRY_DISABLED: ${NEXT_TELEMETRY_DISABLED:-0}
|
||||||
TEXT_GENERATION_TIMEOUT_MS: ${TEXT_GENERATION_TIMEOUT_MS:-60000}
|
TEXT_GENERATION_TIMEOUT_MS: ${TEXT_GENERATION_TIMEOUT_MS:-60000}
|
||||||
CSP_WHITELIST: ${CSP_WHITELIST:-}
|
CSP_WHITELIST: ${CSP_WHITELIST:-}
|
||||||
ALLOW_EMBED: ${ALLOW_EMBED:-false}
|
ALLOW_EMBED: ${ALLOW_EMBED:-false}
|
||||||
|
ALLOW_UNSAFE_DATA_SCHEME: ${ALLOW_UNSAFE_DATA_SCHEME:-false}
|
||||||
MARKETPLACE_API_URL: ${MARKETPLACE_API_URL:-https://marketplace.dify.ai}
|
MARKETPLACE_API_URL: ${MARKETPLACE_API_URL:-https://marketplace.dify.ai}
|
||||||
MARKETPLACE_URL: ${MARKETPLACE_URL:-https://marketplace.dify.ai}
|
MARKETPLACE_URL: ${MARKETPLACE_URL:-https://marketplace.dify.ai}
|
||||||
TOP_K_MAX_VALUE: ${TOP_K_MAX_VALUE:-}
|
TOP_K_MAX_VALUE: ${TOP_K_MAX_VALUE:-}
|
||||||
@@ -591,17 +838,21 @@ services:
|
|||||||
MAX_TOOLS_NUM: ${MAX_TOOLS_NUM:-10}
|
MAX_TOOLS_NUM: ${MAX_TOOLS_NUM:-10}
|
||||||
MAX_PARALLEL_LIMIT: ${MAX_PARALLEL_LIMIT:-10}
|
MAX_PARALLEL_LIMIT: ${MAX_PARALLEL_LIMIT:-10}
|
||||||
MAX_ITERATIONS_NUM: ${MAX_ITERATIONS_NUM:-99}
|
MAX_ITERATIONS_NUM: ${MAX_ITERATIONS_NUM:-99}
|
||||||
|
MAX_TREE_DEPTH: ${MAX_TREE_DEPTH:-50}
|
||||||
ENABLE_WEBSITE_JINAREADER: ${ENABLE_WEBSITE_JINAREADER:-true}
|
ENABLE_WEBSITE_JINAREADER: ${ENABLE_WEBSITE_JINAREADER:-true}
|
||||||
ENABLE_WEBSITE_FIRECRAWL: ${ENABLE_WEBSITE_FIRECRAWL:-true}
|
ENABLE_WEBSITE_FIRECRAWL: ${ENABLE_WEBSITE_FIRECRAWL:-true}
|
||||||
ENABLE_WEBSITE_WATERCRAWL: ${ENABLE_WEBSITE_WATERCRAWL:-true}
|
ENABLE_WEBSITE_WATERCRAWL: ${ENABLE_WEBSITE_WATERCRAWL:-true}
|
||||||
# The postgres database.
|
|
||||||
db:
|
# The PostgreSQL database.
|
||||||
|
db_postgres:
|
||||||
image: postgres:15-alpine
|
image: postgres:15-alpine
|
||||||
|
profiles:
|
||||||
|
- postgresql
|
||||||
restart: always
|
restart: always
|
||||||
environment:
|
environment:
|
||||||
POSTGRES_USER: ${POSTGRES_USER:-postgres}
|
POSTGRES_USER: ${DB_USERNAME:-postgres}
|
||||||
POSTGRES_PASSWORD: ${POSTGRES_PASSWORD:-difyai123456}
|
POSTGRES_PASSWORD: ${DB_PASSWORD:-difyai123456}
|
||||||
POSTGRES_DB: ${POSTGRES_DB:-dify}
|
POSTGRES_DB: ${DB_DATABASE:-dify}
|
||||||
PGDATA: ${PGDATA:-/var/lib/postgresql/data/pgdata}
|
PGDATA: ${PGDATA:-/var/lib/postgresql/data/pgdata}
|
||||||
command: >
|
command: >
|
||||||
postgres -c 'max_connections=${POSTGRES_MAX_CONNECTIONS:-100}'
|
postgres -c 'max_connections=${POSTGRES_MAX_CONNECTIONS:-100}'
|
||||||
@@ -609,24 +860,56 @@ services:
|
|||||||
-c 'work_mem=${POSTGRES_WORK_MEM:-4MB}'
|
-c 'work_mem=${POSTGRES_WORK_MEM:-4MB}'
|
||||||
-c 'maintenance_work_mem=${POSTGRES_MAINTENANCE_WORK_MEM:-64MB}'
|
-c 'maintenance_work_mem=${POSTGRES_MAINTENANCE_WORK_MEM:-64MB}'
|
||||||
-c 'effective_cache_size=${POSTGRES_EFFECTIVE_CACHE_SIZE:-4096MB}'
|
-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:
|
||||||
- ./volumes/db/data:/var/lib/postgresql/data
|
- ./volumes/db/data:/var/lib/postgresql/data
|
||||||
healthcheck:
|
healthcheck:
|
||||||
test:
|
test:
|
||||||
[
|
[
|
||||||
'CMD',
|
"CMD",
|
||||||
'pg_isready',
|
"pg_isready",
|
||||||
'-h',
|
"-h",
|
||||||
'db',
|
"db_postgres",
|
||||||
'-U',
|
"-U",
|
||||||
'${PGUSER:-postgres}',
|
"${DB_USERNAME:-postgres}",
|
||||||
'-d',
|
"-d",
|
||||||
'${POSTGRES_DB:-dify}'
|
"${DB_DATABASE:-dify}"
|
||||||
]
|
]
|
||||||
interval: 1s
|
interval: 1s
|
||||||
timeout: 3s
|
timeout: 3s
|
||||||
retries: 60
|
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.
|
# The redis cache.
|
||||||
redis:
|
redis:
|
||||||
image: redis:6-alpine
|
image: redis:6-alpine
|
||||||
@@ -639,7 +922,11 @@ services:
|
|||||||
# Set the redis password when startup redis server.
|
# Set the redis password when startup redis server.
|
||||||
command: redis-server --requirepass ${REDIS_PASSWORD:-difyai123456}
|
command: redis-server --requirepass ${REDIS_PASSWORD:-difyai123456}
|
||||||
healthcheck:
|
healthcheck:
|
||||||
test: [ 'CMD', 'redis-cli', 'ping' ]
|
test:
|
||||||
|
[
|
||||||
|
"CMD-SHELL",
|
||||||
|
"redis-cli -a ${REDIS_PASSWORD:-difyai123456} ping | grep -q PONG"
|
||||||
|
]
|
||||||
|
|
||||||
# The DifySandbox
|
# The DifySandbox
|
||||||
sandbox:
|
sandbox:
|
||||||
@@ -661,13 +948,13 @@ services:
|
|||||||
- ./volumes/sandbox/dependencies:/dependencies
|
- ./volumes/sandbox/dependencies:/dependencies
|
||||||
- ./volumes/sandbox/conf:/conf
|
- ./volumes/sandbox/conf:/conf
|
||||||
healthcheck:
|
healthcheck:
|
||||||
test: [ 'CMD', 'curl', '-f', 'http://localhost:8194/health' ]
|
test: [ "CMD", "curl", "-f", "http://localhost:8194/health" ]
|
||||||
networks:
|
networks:
|
||||||
- ssrf_proxy_network
|
- ssrf_proxy_network
|
||||||
|
|
||||||
# plugin daemon
|
# plugin daemon
|
||||||
plugin_daemon:
|
plugin_daemon:
|
||||||
image: langgenius/dify-plugin-daemon:0.1.3-local
|
image: langgenius/dify-plugin-daemon:0.5.2-local
|
||||||
restart: always
|
restart: always
|
||||||
environment:
|
environment:
|
||||||
# Use the shared environment variables.
|
# Use the shared environment variables.
|
||||||
@@ -685,6 +972,8 @@ services:
|
|||||||
FORCE_VERIFYING_SIGNATURE: ${FORCE_VERIFYING_SIGNATURE:-true}
|
FORCE_VERIFYING_SIGNATURE: ${FORCE_VERIFYING_SIGNATURE:-true}
|
||||||
PYTHON_ENV_INIT_TIMEOUT: ${PLUGIN_PYTHON_ENV_INIT_TIMEOUT:-120}
|
PYTHON_ENV_INIT_TIMEOUT: ${PLUGIN_PYTHON_ENV_INIT_TIMEOUT:-120}
|
||||||
PLUGIN_MAX_EXECUTION_TIMEOUT: ${PLUGIN_MAX_EXECUTION_TIMEOUT:-600}
|
PLUGIN_MAX_EXECUTION_TIMEOUT: ${PLUGIN_MAX_EXECUTION_TIMEOUT:-600}
|
||||||
|
PLUGIN_STDIO_BUFFER_SIZE: ${PLUGIN_STDIO_BUFFER_SIZE:-1024}
|
||||||
|
PLUGIN_STDIO_MAX_BUFFER_SIZE: ${PLUGIN_STDIO_MAX_BUFFER_SIZE:-5242880}
|
||||||
PIP_MIRROR_URL: ${PIP_MIRROR_URL:-}
|
PIP_MIRROR_URL: ${PIP_MIRROR_URL:-}
|
||||||
PLUGIN_STORAGE_TYPE: ${PLUGIN_STORAGE_TYPE:-local}
|
PLUGIN_STORAGE_TYPE: ${PLUGIN_STORAGE_TYPE:-local}
|
||||||
PLUGIN_STORAGE_LOCAL_ROOT: ${PLUGIN_STORAGE_LOCAL_ROOT:-/app/storage}
|
PLUGIN_STORAGE_LOCAL_ROOT: ${PLUGIN_STORAGE_LOCAL_ROOT:-/app/storage}
|
||||||
@@ -714,11 +1003,23 @@ services:
|
|||||||
VOLCENGINE_TOS_ACCESS_KEY: ${PLUGIN_VOLCENGINE_TOS_ACCESS_KEY:-}
|
VOLCENGINE_TOS_ACCESS_KEY: ${PLUGIN_VOLCENGINE_TOS_ACCESS_KEY:-}
|
||||||
VOLCENGINE_TOS_SECRET_KEY: ${PLUGIN_VOLCENGINE_TOS_SECRET_KEY:-}
|
VOLCENGINE_TOS_SECRET_KEY: ${PLUGIN_VOLCENGINE_TOS_SECRET_KEY:-}
|
||||||
VOLCENGINE_TOS_REGION: ${PLUGIN_VOLCENGINE_TOS_REGION:-}
|
VOLCENGINE_TOS_REGION: ${PLUGIN_VOLCENGINE_TOS_REGION:-}
|
||||||
|
SENTRY_ENABLED: ${PLUGIN_SENTRY_ENABLED:-false}
|
||||||
|
SENTRY_DSN: ${PLUGIN_SENTRY_DSN:-}
|
||||||
volumes:
|
volumes:
|
||||||
- ./volumes/plugin_daemon:/app/storage
|
- ./volumes/plugin_daemon:/app/storage
|
||||||
depends_on:
|
depends_on:
|
||||||
db:
|
db_postgres:
|
||||||
condition: service_healthy
|
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
|
# ssrf_proxy server
|
||||||
# for more information, please refer to
|
# for more information, please refer to
|
||||||
@@ -731,8 +1032,8 @@ services:
|
|||||||
- ./ssrf_proxy/docker-entrypoint.sh:/docker-entrypoint-mount.sh
|
- ./ssrf_proxy/docker-entrypoint.sh:/docker-entrypoint-mount.sh
|
||||||
entrypoint:
|
entrypoint:
|
||||||
[
|
[
|
||||||
'sh',
|
"sh",
|
||||||
'-c',
|
"-c",
|
||||||
"cp /docker-entrypoint-mount.sh /docker-entrypoint.sh && sed -i
|
"cp /docker-entrypoint-mount.sh /docker-entrypoint.sh && sed -i
|
||||||
's/\r$$//' /docker-entrypoint.sh && chmod +x /docker-entrypoint.sh &&
|
's/\r$$//' /docker-entrypoint.sh && chmod +x /docker-entrypoint.sh &&
|
||||||
/docker-entrypoint.sh"
|
/docker-entrypoint.sh"
|
||||||
@@ -765,8 +1066,8 @@ services:
|
|||||||
- CERTBOT_EMAIL=${CERTBOT_EMAIL}
|
- CERTBOT_EMAIL=${CERTBOT_EMAIL}
|
||||||
- CERTBOT_DOMAIN=${CERTBOT_DOMAIN}
|
- CERTBOT_DOMAIN=${CERTBOT_DOMAIN}
|
||||||
- CERTBOT_OPTIONS=${CERTBOT_OPTIONS:-}
|
- CERTBOT_OPTIONS=${CERTBOT_OPTIONS:-}
|
||||||
entrypoint: [ '/docker-entrypoint.sh' ]
|
entrypoint: [ "/docker-entrypoint.sh" ]
|
||||||
command: [ 'tail', '-f', '/dev/null' ]
|
command: [ "tail", "-f", "/dev/null" ]
|
||||||
|
|
||||||
# The nginx reverse proxy.
|
# The nginx reverse proxy.
|
||||||
# used for reverse proxying the API service and Web service.
|
# used for reverse proxying the API service and Web service.
|
||||||
@@ -785,8 +1086,8 @@ services:
|
|||||||
- ./volumes/certbot/www:/var/www/html
|
- ./volumes/certbot/www:/var/www/html
|
||||||
entrypoint:
|
entrypoint:
|
||||||
[
|
[
|
||||||
'sh',
|
"sh",
|
||||||
'-c',
|
"-c",
|
||||||
"cp /docker-entrypoint-mount.sh /docker-entrypoint.sh && sed -i
|
"cp /docker-entrypoint-mount.sh /docker-entrypoint.sh && sed -i
|
||||||
's/\r$$//' /docker-entrypoint.sh && chmod +x /docker-entrypoint.sh &&
|
's/\r$$//' /docker-entrypoint.sh && chmod +x /docker-entrypoint.sh &&
|
||||||
/docker-entrypoint.sh"
|
/docker-entrypoint.sh"
|
||||||
@@ -800,9 +1101,9 @@ services:
|
|||||||
# and modify the env vars below in .env if HTTPS_ENABLED is true.
|
# 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_FILENAME: ${NGINX_SSL_CERT_FILENAME:-dify.crt}
|
||||||
NGINX_SSL_CERT_KEY_FILENAME: ${NGINX_SSL_CERT_KEY_FILENAME:-dify.key}
|
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_WORKER_PROCESSES: ${NGINX_WORKER_PROCESSES:-auto}
|
||||||
NGINX_CLIENT_MAX_BODY_SIZE: ${NGINX_CLIENT_MAX_BODY_SIZE:-15M}
|
NGINX_CLIENT_MAX_BODY_SIZE: ${NGINX_CLIENT_MAX_BODY_SIZE:-100M}
|
||||||
NGINX_KEEPALIVE_TIMEOUT: ${NGINX_KEEPALIVE_TIMEOUT:-65}
|
NGINX_KEEPALIVE_TIMEOUT: ${NGINX_KEEPALIVE_TIMEOUT:-65}
|
||||||
NGINX_PROXY_READ_TIMEOUT: ${NGINX_PROXY_READ_TIMEOUT:-3600s}
|
NGINX_PROXY_READ_TIMEOUT: ${NGINX_PROXY_READ_TIMEOUT:-3600s}
|
||||||
NGINX_PROXY_SEND_TIMEOUT: ${NGINX_PROXY_SEND_TIMEOUT:-3600s}
|
NGINX_PROXY_SEND_TIMEOUT: ${NGINX_PROXY_SEND_TIMEOUT:-3600s}
|
||||||
@@ -814,9 +1115,8 @@ services:
|
|||||||
|
|
||||||
# The Weaviate vector store.
|
# The Weaviate vector store.
|
||||||
weaviate:
|
weaviate:
|
||||||
image: semitechnologies/weaviate:1.19.0
|
image: semitechnologies/weaviate:1.27.0
|
||||||
profiles:
|
profiles:
|
||||||
- ''
|
|
||||||
- weaviate
|
- weaviate
|
||||||
restart: always
|
restart: always
|
||||||
volumes:
|
volumes:
|
||||||
@@ -835,11 +1135,69 @@ services:
|
|||||||
AUTHENTICATION_APIKEY_USERS: ${WEAVIATE_AUTHENTICATION_APIKEY_USERS:-hello@dify.ai}
|
AUTHENTICATION_APIKEY_USERS: ${WEAVIATE_AUTHENTICATION_APIKEY_USERS:-hello@dify.ai}
|
||||||
AUTHORIZATION_ADMINLIST_ENABLED: ${WEAVIATE_AUTHORIZATION_ADMINLIST_ENABLED:-true}
|
AUTHORIZATION_ADMINLIST_ENABLED: ${WEAVIATE_AUTHORIZATION_ADMINLIST_ENABLED:-true}
|
||||||
AUTHORIZATION_ADMINLIST_USERS: ${WEAVIATE_AUTHORIZATION_ADMINLIST_USERS:-hello@dify.ai}
|
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.
|
# Qdrant vector store.
|
||||||
# (if used, you need to set VECTOR_STORE to qdrant in the api & worker service.)
|
# (if used, you need to set VECTOR_STORE to qdrant in the api & worker service.)
|
||||||
qdrant:
|
qdrant:
|
||||||
image: langgenius/qdrant:v1.7.3
|
image: langgenius/qdrant:v1.8.3
|
||||||
profiles:
|
profiles:
|
||||||
- qdrant
|
- qdrant
|
||||||
restart: always
|
restart: always
|
||||||
@@ -906,9 +1264,9 @@ services:
|
|||||||
volumes:
|
volumes:
|
||||||
- ./volumes/pgvector/data:/var/lib/postgresql/data
|
- ./volumes/pgvector/data:/var/lib/postgresql/data
|
||||||
- ./pgvector/docker-entrypoint.sh:/docker-entrypoint.sh
|
- ./pgvector/docker-entrypoint.sh:/docker-entrypoint.sh
|
||||||
entrypoint: [ '/docker-entrypoint.sh' ]
|
entrypoint: [ "/docker-entrypoint.sh" ]
|
||||||
healthcheck:
|
healthcheck:
|
||||||
test: [ 'CMD', 'pg_isready' ]
|
test: [ "CMD", "pg_isready" ]
|
||||||
interval: 1s
|
interval: 1s
|
||||||
timeout: 3s
|
timeout: 3s
|
||||||
retries: 30
|
retries: 30
|
||||||
@@ -930,7 +1288,7 @@ services:
|
|||||||
- ./vastbase/backup:/home/vastbase/backup
|
- ./vastbase/backup:/home/vastbase/backup
|
||||||
- ./vastbase/backup_log:/home/vastbase/backup_log
|
- ./vastbase/backup_log:/home/vastbase/backup_log
|
||||||
healthcheck:
|
healthcheck:
|
||||||
test: [ 'CMD', 'pg_isready' ]
|
test: [ "CMD", "pg_isready" ]
|
||||||
interval: 1s
|
interval: 1s
|
||||||
timeout: 3s
|
timeout: 3s
|
||||||
retries: 30
|
retries: 30
|
||||||
@@ -952,7 +1310,7 @@ services:
|
|||||||
volumes:
|
volumes:
|
||||||
- ./volumes/pgvecto_rs/data:/var/lib/postgresql/data
|
- ./volumes/pgvecto_rs/data:/var/lib/postgresql/data
|
||||||
healthcheck:
|
healthcheck:
|
||||||
test: [ 'CMD', 'pg_isready' ]
|
test: [ "CMD", "pg_isready" ]
|
||||||
interval: 1s
|
interval: 1s
|
||||||
timeout: 3s
|
timeout: 3s
|
||||||
retries: 30
|
retries: 30
|
||||||
@@ -970,34 +1328,21 @@ services:
|
|||||||
CHROMA_SERVER_AUTHN_PROVIDER: ${CHROMA_SERVER_AUTHN_PROVIDER:-chromadb.auth.token_authn.TokenAuthenticationServerProvider}
|
CHROMA_SERVER_AUTHN_PROVIDER: ${CHROMA_SERVER_AUTHN_PROVIDER:-chromadb.auth.token_authn.TokenAuthenticationServerProvider}
|
||||||
IS_PERSISTENT: ${CHROMA_IS_PERSISTENT:-TRUE}
|
IS_PERSISTENT: ${CHROMA_IS_PERSISTENT:-TRUE}
|
||||||
|
|
||||||
# OceanBase vector database
|
# InterSystems IRIS vector database
|
||||||
oceanbase:
|
iris:
|
||||||
image: oceanbase/oceanbase-ce:4.3.5-lts
|
image: containers.intersystems.com/intersystems/iris-community:2025.3
|
||||||
profiles:
|
profiles:
|
||||||
- oceanbase
|
- iris
|
||||||
restart: always
|
restart: always
|
||||||
|
init: true
|
||||||
volumes:
|
volumes:
|
||||||
- ./volumes/oceanbase/data:/root/ob
|
- ./volumes/iris:/opt/iris
|
||||||
- ./volumes/oceanbase/conf:/root/.obd/cluster
|
- ./iris/iris-init.script:/iris-init.script
|
||||||
- ./volumes/oceanbase/init.d:/root/boot/init.d
|
- ./iris/docker-entrypoint.sh:/custom-entrypoint.sh
|
||||||
|
entrypoint: [ "/custom-entrypoint.sh" ]
|
||||||
|
tty: true
|
||||||
environment:
|
environment:
|
||||||
OB_MEMORY_LIMIT: ${OCEANBASE_MEMORY_LIMIT:-6G}
|
TZ: ${IRIS_TIMEZONE:-UTC}
|
||||||
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
|
|
||||||
|
|
||||||
# Oracle vector database
|
# Oracle vector database
|
||||||
oracle:
|
oracle:
|
||||||
@@ -1029,7 +1374,7 @@ services:
|
|||||||
command: etcd -advertise-client-urls=http://127.0.0.1:2379 -listen-client-urls
|
command: etcd -advertise-client-urls=http://127.0.0.1:2379 -listen-client-urls
|
||||||
http://0.0.0.0:2379 --data-dir /etcd
|
http://0.0.0.0:2379 --data-dir /etcd
|
||||||
healthcheck:
|
healthcheck:
|
||||||
test: [ 'CMD', 'etcdctl', 'endpoint', 'health' ]
|
test: [ "CMD", "etcdctl", "endpoint", "health" ]
|
||||||
interval: 30s
|
interval: 30s
|
||||||
timeout: 20s
|
timeout: 20s
|
||||||
retries: 3
|
retries: 3
|
||||||
@@ -1047,7 +1392,7 @@ services:
|
|||||||
- ./volumes/milvus/minio:/minio_data
|
- ./volumes/milvus/minio:/minio_data
|
||||||
command: minio server /minio_data --console-address ":9001"
|
command: minio server /minio_data --console-address ":9001"
|
||||||
healthcheck:
|
healthcheck:
|
||||||
test: [ 'CMD', 'curl', '-f', 'http://localhost:9000/minio/health/live' ]
|
test: [ "CMD", "curl", "-f", "http://localhost:9000/minio/health/live" ]
|
||||||
interval: 30s
|
interval: 30s
|
||||||
timeout: 20s
|
timeout: 20s
|
||||||
retries: 3
|
retries: 3
|
||||||
@@ -1055,10 +1400,10 @@ services:
|
|||||||
- milvus
|
- milvus
|
||||||
|
|
||||||
milvus-standalone:
|
milvus-standalone:
|
||||||
image: milvusdb/milvus:v2.5.0-beta
|
image: milvusdb/milvus:v2.6.3
|
||||||
profiles:
|
profiles:
|
||||||
- milvus
|
- milvus
|
||||||
command: [ 'milvus', 'run', 'standalone' ]
|
command: [ "milvus", "run", "standalone" ]
|
||||||
environment:
|
environment:
|
||||||
ETCD_ENDPOINTS: ${ETCD_ENDPOINTS:-etcd:2379}
|
ETCD_ENDPOINTS: ${ETCD_ENDPOINTS:-etcd:2379}
|
||||||
MINIO_ADDRESS: ${MINIO_ADDRESS:-minio:9000}
|
MINIO_ADDRESS: ${MINIO_ADDRESS:-minio:9000}
|
||||||
@@ -1066,7 +1411,7 @@ services:
|
|||||||
volumes:
|
volumes:
|
||||||
- ./volumes/milvus/milvus:/var/lib/milvus
|
- ./volumes/milvus/milvus:/var/lib/milvus
|
||||||
healthcheck:
|
healthcheck:
|
||||||
test: [ 'CMD', 'curl', '-f', 'http://localhost:9091/healthz' ]
|
test: [ "CMD", "curl", "-f", "http://localhost:9091/healthz" ]
|
||||||
interval: 30s
|
interval: 30s
|
||||||
start_period: 90s
|
start_period: 90s
|
||||||
timeout: 20s
|
timeout: 20s
|
||||||
@@ -1173,16 +1518,16 @@ services:
|
|||||||
node.name: dify-es0
|
node.name: dify-es0
|
||||||
discovery.type: single-node
|
discovery.type: single-node
|
||||||
xpack.license.self_generated.type: basic
|
xpack.license.self_generated.type: basic
|
||||||
xpack.security.enabled: 'true'
|
xpack.security.enabled: "true"
|
||||||
xpack.security.enrollment.enabled: 'false'
|
xpack.security.enrollment.enabled: "false"
|
||||||
xpack.security.http.ssl.enabled: 'false'
|
xpack.security.http.ssl.enabled: "false"
|
||||||
deploy:
|
deploy:
|
||||||
resources:
|
resources:
|
||||||
limits:
|
limits:
|
||||||
memory: 2g
|
memory: 2g
|
||||||
entrypoint: [ 'sh', '-c', "sh /docker-entrypoint-mount.sh" ]
|
entrypoint: [ "sh", "-c", "sh /docker-entrypoint-mount.sh" ]
|
||||||
healthcheck:
|
healthcheck:
|
||||||
test: [ 'CMD', 'curl', '-s', 'http://localhost:9200/_cluster/health?pretty' ]
|
test: [ "CMD", "curl", "-s", "http://localhost:9200/_cluster/health?pretty" ]
|
||||||
interval: 30s
|
interval: 30s
|
||||||
timeout: 10s
|
timeout: 10s
|
||||||
retries: 50
|
retries: 50
|
||||||
@@ -1199,15 +1544,15 @@ services:
|
|||||||
environment:
|
environment:
|
||||||
XPACK_ENCRYPTEDSAVEDOBJECTS_ENCRYPTIONKEY: d1a66dfd-c4d3-4a0a-8290-2abcb83ab3aa
|
XPACK_ENCRYPTEDSAVEDOBJECTS_ENCRYPTIONKEY: d1a66dfd-c4d3-4a0a-8290-2abcb83ab3aa
|
||||||
NO_PROXY: localhost,127.0.0.1,elasticsearch,kibana
|
NO_PROXY: localhost,127.0.0.1,elasticsearch,kibana
|
||||||
XPACK_SECURITY_ENABLED: 'true'
|
XPACK_SECURITY_ENABLED: "true"
|
||||||
XPACK_SECURITY_ENROLLMENT_ENABLED: 'false'
|
XPACK_SECURITY_ENROLLMENT_ENABLED: "false"
|
||||||
XPACK_SECURITY_HTTP_SSL_ENABLED: 'false'
|
XPACK_SECURITY_HTTP_SSL_ENABLED: "false"
|
||||||
XPACK_FLEET_ISAIRGAPPED: 'true'
|
XPACK_FLEET_ISAIRGAPPED: "true"
|
||||||
I18N_LOCALE: zh-CN
|
I18N_LOCALE: zh-CN
|
||||||
SERVER_PORT: '5601'
|
SERVER_PORT: "5601"
|
||||||
ELASTICSEARCH_HOSTS: http://elasticsearch:9200
|
ELASTICSEARCH_HOSTS: http://elasticsearch:9200
|
||||||
healthcheck:
|
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
|
interval: 30s
|
||||||
timeout: 10s
|
timeout: 10s
|
||||||
retries: 3
|
retries: 3
|
||||||
|
|||||||
Executable
+38
@@ -0,0 +1,38 @@
|
|||||||
|
#!/bin/bash
|
||||||
|
set -e
|
||||||
|
|
||||||
|
# IRIS configuration flag file
|
||||||
|
IRIS_CONFIG_DONE="/opt/iris/.iris-configured"
|
||||||
|
|
||||||
|
# Function to configure IRIS
|
||||||
|
configure_iris() {
|
||||||
|
echo "Configuring IRIS for first-time setup..."
|
||||||
|
|
||||||
|
# Wait for IRIS to be fully started
|
||||||
|
sleep 5
|
||||||
|
|
||||||
|
# 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
|
# Environment Variables for db Service
|
||||||
# ------------------------------
|
# ------------------------------
|
||||||
POSTGRES_USER=postgres
|
# Database Configuration
|
||||||
# The password for the default postgres user.
|
# Database type, supported values are `postgresql` and `mysql`
|
||||||
POSTGRES_PASSWORD=difyai123456
|
DB_TYPE=postgresql
|
||||||
# The name of the default postgres database.
|
# For MySQL, only `root` user is supported for now
|
||||||
POSTGRES_DB=dify
|
DB_USERNAME=postgres
|
||||||
|
DB_PASSWORD=difyai123456
|
||||||
|
DB_HOST=db_postgres
|
||||||
|
DB_PORT=5432
|
||||||
|
DB_DATABASE=dify
|
||||||
|
|
||||||
|
# PostgreSQL Configuration
|
||||||
# postgres data directory
|
# postgres data directory
|
||||||
PGDATA=/var/lib/postgresql/data/pgdata
|
PGDATA=/var/lib/postgresql/data/pgdata
|
||||||
PGDATA_HOST_VOLUME=./volumes/db/data
|
PGDATA_HOST_VOLUME=./volumes/db/data
|
||||||
@@ -40,6 +46,46 @@ POSTGRES_MAINTENANCE_WORK_MEM=64MB
|
|||||||
# Reference: https://www.postgresql.org/docs/current/runtime-config-query.html#GUC-EFFECTIVE-CACHE-SIZE
|
# Reference: https://www.postgresql.org/docs/current/runtime-config-query.html#GUC-EFFECTIVE-CACHE-SIZE
|
||||||
POSTGRES_EFFECTIVE_CACHE_SIZE=4096MB
|
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
|
# Environment Variables for redis Service
|
||||||
# -----------------------------
|
# -----------------------------
|
||||||
@@ -77,12 +123,21 @@ WEAVIATE_AUTHENTICATION_APIKEY_ALLOWED_KEYS=WVF5YThaHlkYwhGUSmCRgsX3tD5ngdN8pkih
|
|||||||
WEAVIATE_AUTHENTICATION_APIKEY_USERS=hello@dify.ai
|
WEAVIATE_AUTHENTICATION_APIKEY_USERS=hello@dify.ai
|
||||||
WEAVIATE_AUTHORIZATION_ADMINLIST_ENABLED=true
|
WEAVIATE_AUTHORIZATION_ADMINLIST_ENABLED=true
|
||||||
WEAVIATE_AUTHORIZATION_ADMINLIST_USERS=hello@dify.ai
|
WEAVIATE_AUTHORIZATION_ADMINLIST_USERS=hello@dify.ai
|
||||||
|
WEAVIATE_DISABLE_TELEMETRY=false
|
||||||
WEAVIATE_HOST_VOLUME=./volumes/weaviate
|
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
|
# Docker Compose Service Expose Host Port Configurations
|
||||||
# ------------------------------
|
# ------------------------------
|
||||||
EXPOSE_POSTGRES_PORT=5432
|
EXPOSE_POSTGRES_PORT=5432
|
||||||
|
EXPOSE_MYSQL_PORT=3306
|
||||||
EXPOSE_REDIS_PORT=6379
|
EXPOSE_REDIS_PORT=6379
|
||||||
EXPOSE_SANDBOX_PORT=8194
|
EXPOSE_SANDBOX_PORT=8194
|
||||||
EXPOSE_SSRF_PROXY_PORT=3128
|
EXPOSE_SSRF_PROXY_PORT=3128
|
||||||
@@ -158,3 +213,28 @@ PLUGIN_VOLCENGINE_TOS_ENDPOINT=
|
|||||||
PLUGIN_VOLCENGINE_TOS_ACCESS_KEY=
|
PLUGIN_VOLCENGINE_TOS_ACCESS_KEY=
|
||||||
PLUGIN_VOLCENGINE_TOS_SECRET_KEY=
|
PLUGIN_VOLCENGINE_TOS_SECRET_KEY=
|
||||||
PLUGIN_VOLCENGINE_TOS_REGION=
|
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
|
||||||
@@ -40,6 +40,16 @@ server {
|
|||||||
include proxy.conf;
|
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
|
# placeholder for acme challenge location
|
||||||
${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.
|
# Unless the option's size is increased, an error will occur when uploading more than two files.
|
||||||
client_request_buffer_max_size 100 MB
|
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/data:/data
|
||||||
- ./volumes/logs:/logs
|
- ./volumes/logs:/logs
|
||||||
command:
|
command:
|
||||||
- --config=/tiflash.toml
|
- server
|
||||||
|
- --config-file=/tiflash.toml
|
||||||
depends_on:
|
depends_on:
|
||||||
- "tikv"
|
- "tikv"
|
||||||
- "tidb"
|
- "tidb"
|
||||||
|
|||||||
@@ -4,3 +4,15 @@ await utils.cloneOrPullRepo({ repo: "https://github.com/langgenius/dify.git" });
|
|||||||
await utils.copyDir("./repo/docker", "./code");
|
await utils.copyDir("./repo/docker", "./code");
|
||||||
await utils.removeContainerNames("./code/docker-compose.yaml");
|
await utils.removeContainerNames("./code/docker-compose.yaml");
|
||||||
await utils.removePorts("./code/docker-compose.yaml");
|
await utils.removePorts("./code/docker-compose.yaml");
|
||||||
|
|
||||||
|
await utils.searchReplace(
|
||||||
|
"./code/.env.example",
|
||||||
|
"APP_WEB_URL=",
|
||||||
|
"APP_WEB_URL=https://$(PRIMARY_DOMAIN)"
|
||||||
|
);
|
||||||
|
|
||||||
|
await utils.searchReplace(
|
||||||
|
"./code/.env.example",
|
||||||
|
"SECRET_KEY=sk-9f73s3ljTXVcMT3Blb3ljTqtsKiGHXVcMT3BlbkFJLK7U",
|
||||||
|
"SECRET_KEY="
|
||||||
|
);
|
||||||
|
|||||||
@@ -1,13 +0,0 @@
|
|||||||
#!/bin/bash
|
|
||||||
|
|
||||||
if [ ! -d "./repo" ]; then
|
|
||||||
git clone --depth 1 --branch main --single-branch https://github.com/langgenius/dify.git repo
|
|
||||||
else
|
|
||||||
cd repo
|
|
||||||
git pull
|
|
||||||
cd ..
|
|
||||||
fi
|
|
||||||
|
|
||||||
cp -r ./repo/docker/. ./code
|
|
||||||
|
|
||||||
|
|
||||||
+41
-3
@@ -1,4 +1,42 @@
|
|||||||
# Plane
|
# Plane - Project Management Script
|
||||||
|
|
||||||
- copied from https://github.com/makeplane/plane
|
This directory contains the Plane project management tool deployment for Easypanel.
|
||||||
- removed `ports`
|
|
||||||
|
## Update Process
|
||||||
|
|
||||||
|
To update Plane to the latest version, follow these steps in order:
|
||||||
|
|
||||||
|
### Step 1: Run the Setup Script for Upgrade
|
||||||
|
|
||||||
|
First, run the `setup.sh` script and choose the upgrade option:
|
||||||
|
|
||||||
|
```
|
||||||
|
./setup.sh
|
||||||
|
```
|
||||||
|
|
||||||
|
When prompted, select option **5** for "Upgrade". This will:
|
||||||
|
|
||||||
|
* Check for the latest available release
|
||||||
|
* Download the latest stable version
|
||||||
|
|
||||||
|
### Step 2: Run the Update Script
|
||||||
|
|
||||||
|
After the setup script completes successfully, run the `update.js` script:
|
||||||
|
|
||||||
|
```
|
||||||
|
node update.js
|
||||||
|
```
|
||||||
|
|
||||||
|
This script will:
|
||||||
|
|
||||||
|
* Removes the existing code directory and changes the name for the newly fetched directory to code.
|
||||||
|
* Rename `plane.env` to `.env.example`
|
||||||
|
* Rename `docker-compose.yaml` to `docker-compose.yml`
|
||||||
|
* Remove container names and ports from docker-compose.yml
|
||||||
|
* Update environment variables to use Easypanel's `PRIMARY_DOMAIN` variable
|
||||||
|
|
||||||
|
## Important Notes
|
||||||
|
|
||||||
|
* **Always run setup.sh first** - This ensures you get the latest official Plane release
|
||||||
|
* **Then run update.js** - This applies Easypanel-specific customizations
|
||||||
|
* The update process will preserve your existing data and configuration
|
||||||
+27
-5
@@ -1,5 +1,5 @@
|
|||||||
APP_DOMAIN=localhost
|
APP_DOMAIN=$(PRIMARY_DOMAIN)
|
||||||
APP_RELEASE=stable
|
APP_RELEASE=v1.2.1
|
||||||
|
|
||||||
WEB_REPLICAS=1
|
WEB_REPLICAS=1
|
||||||
SPACE_REPLICAS=1
|
SPACE_REPLICAS=1
|
||||||
@@ -9,10 +9,12 @@ WORKER_REPLICAS=1
|
|||||||
BEAT_WORKER_REPLICAS=1
|
BEAT_WORKER_REPLICAS=1
|
||||||
LIVE_REPLICAS=1
|
LIVE_REPLICAS=1
|
||||||
|
|
||||||
NGINX_PORT=80
|
LISTEN_HTTP_PORT=80
|
||||||
WEB_URL=http://${APP_DOMAIN}
|
LISTEN_HTTPS_PORT=443
|
||||||
|
|
||||||
|
WEB_URL=https://$(PRIMARY_DOMAIN)
|
||||||
DEBUG=0
|
DEBUG=0
|
||||||
CORS_ALLOWED_ORIGINS=http://${APP_DOMAIN}
|
CORS_ALLOWED_ORIGINS=https://$(PRIMARY_DOMAIN)
|
||||||
API_BASE_URL=http://api:8000
|
API_BASE_URL=http://api:8000
|
||||||
|
|
||||||
#DB SETTINGS
|
#DB SETTINGS
|
||||||
@@ -38,6 +40,19 @@ RABBITMQ_PASSWORD=plane
|
|||||||
RABBITMQ_VHOST=plane
|
RABBITMQ_VHOST=plane
|
||||||
AMQP_URL=
|
AMQP_URL=
|
||||||
|
|
||||||
|
# If SSL Cert to be generated, set CERT_EMAIl="email <EMAIL_ADDRESS>"
|
||||||
|
CERT_ACME_CA=https://acme-v02.api.letsencrypt.org/directory
|
||||||
|
TRUSTED_PROXIES=0.0.0.0/0
|
||||||
|
SITE_ADDRESS=:80
|
||||||
|
CERT_EMAIL=
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
# For DNS Challenge based certificate generation, set the CERT_ACME_DNS, CERT_EMAIL
|
||||||
|
# CERT_ACME_DNS="acme_dns <CERT_DNS_PROVIDER> <CERT_DNS_PROVIDER_API_KEY>"
|
||||||
|
CERT_ACME_DNS=
|
||||||
|
|
||||||
|
|
||||||
# Secret Key
|
# Secret Key
|
||||||
SECRET_KEY=60gp0byfz2dvffa45cxl20p1scy9xbpf6d8c5y0geejgkyp1b5
|
SECRET_KEY=60gp0byfz2dvffa45cxl20p1scy9xbpf6d8c5y0geejgkyp1b5
|
||||||
|
|
||||||
@@ -61,3 +76,10 @@ MINIO_ENDPOINT_SSL=0
|
|||||||
|
|
||||||
# API key rate limit
|
# API key rate limit
|
||||||
API_KEY_RATE_LIMIT=60/minute
|
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
|
||||||
|
|||||||
@@ -1,630 +0,0 @@
|
|||||||
# Self Hosting
|
|
||||||
|
|
||||||
In this guide, we will walk you through the process of setting up a self-hosted environment. Self-hosting allows you to have full control over your applications and data. It's a great way to ensure privacy, control, and customization.
|
|
||||||
|
|
||||||
We will cover two main options for setting up your self-hosted environment: using a cloud server or using your desktop. For the cloud server, we will use an AWS EC2 instance. For the desktop, we will use Docker to create a local environment.
|
|
||||||
|
|
||||||
Let's get started!
|
|
||||||
|
|
||||||
## Setting up Docker Environment
|
|
||||||
|
|
||||||
<details>
|
|
||||||
<summary>Option 1 - Using Cloud Server</summary>
|
|
||||||
<p>Best way to start is to create EC2 machine on AWS. It must have minimum of 2vCPU and 4GB RAM.</p>
|
|
||||||
<p>Run the below command to install docker engine.</p>
|
|
||||||
|
|
||||||
`curl -fsSL https://get.docker.com | sh -`
|
|
||||||
|
|
||||||
</details>
|
|
||||||
|
|
||||||
---
|
|
||||||
|
|
||||||
<details>
|
|
||||||
<summary>Option 2 - Using Desktop</summary>
|
|
||||||
|
|
||||||
#### For Mac
|
|
||||||
|
|
||||||
<ol>
|
|
||||||
<li> Download Docker Desktop for Mac from the <a href="https://hub.docker.com/editions/community/docker-ce-desktop-mac/" target="_blank">Docker Hub</a>. </li>
|
|
||||||
<li> Double-click the downloaded `.dmg` file and drag the Docker app icon to the Applications folder. </li>
|
|
||||||
<li>Open Docker Desktop from the Applications folder. You might be asked to provide your system password to install additional software.</li>
|
|
||||||
</ol>
|
|
||||||
|
|
||||||
#### For Windows:
|
|
||||||
|
|
||||||
<ol>
|
|
||||||
<li>Download Docker Desktop for Windows from the <a href="https://hub.docker.com/editions/community/docker-ce-desktop-windows/" target="_blank">Docker Hub</a>.</li>
|
|
||||||
<li>Run the installer and follow the instructions. You might be asked to enable Hyper-V and "Containers" Windows features.</li>
|
|
||||||
<li>Open Docker Desktop. You might be asked to log out and log back in, or restart your machine, for changes to take effect.</li>
|
|
||||||
</ol>
|
|
||||||
|
|
||||||
After installation, you can verify the installation by opening a terminal (Command Prompt on Windows, Terminal app on Mac) and running the command `docker --version`. This should display the installed version of Docker.
|
|
||||||
|
|
||||||
</details>
|
|
||||||
|
|
||||||
---
|
|
||||||
|
|
||||||
## Installing Plane
|
|
||||||
|
|
||||||
Installing plane is a very easy and minimal step process.
|
|
||||||
|
|
||||||
### Prerequisite
|
|
||||||
|
|
||||||
- Docker installed and running
|
|
||||||
- OS with bash scripting enabled (Ubuntu, Linux AMI, macos). Windows systems need to have [gitbash](https://git-scm.com/download/win)
|
|
||||||
- User context used must have access to docker services. In most cases, use sudo su to switch as root user
|
|
||||||
- Use the terminal (or gitbash) window to run all the future steps
|
|
||||||
|
|
||||||
### Downloading Latest Release
|
|
||||||
|
|
||||||
```
|
|
||||||
mkdir plane-selfhost
|
|
||||||
|
|
||||||
cd plane-selfhost
|
|
||||||
```
|
|
||||||
|
|
||||||
#### For *Docker Compose* based setup
|
|
||||||
|
|
||||||
```
|
|
||||||
curl -fsSL -o setup.sh https://github.com/makeplane/plane/releases/latest/download/setup.sh
|
|
||||||
|
|
||||||
chmod +x setup.sh
|
|
||||||
```
|
|
||||||
|
|
||||||
#### For *Docker Swarm* based setup
|
|
||||||
|
|
||||||
```
|
|
||||||
curl -fsSL -o setup.sh https://github.com/makeplane/plane/releases/latest/download/swarm.sh
|
|
||||||
|
|
||||||
chmod +x setup.sh
|
|
||||||
```
|
|
||||||
|
|
||||||
---
|
|
||||||
|
|
||||||
### Proceed with setup
|
|
||||||
|
|
||||||
Above steps will set you ready to install and start plane services.
|
|
||||||
|
|
||||||
Lets get started by running the `./setup.sh` command.
|
|
||||||
|
|
||||||
This will prompt you with the below options.
|
|
||||||
|
|
||||||
#### Docker Compose
|
|
||||||
```bash
|
|
||||||
Select an Action you want to perform:
|
|
||||||
1) Install (x86_64)
|
|
||||||
2) Start
|
|
||||||
3) Stop
|
|
||||||
4) Restart
|
|
||||||
5) Upgrade
|
|
||||||
6) View Logs
|
|
||||||
7) Backup Data
|
|
||||||
8) Exit
|
|
||||||
|
|
||||||
Action [2]: 1
|
|
||||||
```
|
|
||||||
|
|
||||||
For the 1st time setup, type "1" as action input.
|
|
||||||
|
|
||||||
This will create a folder `plane-app` and will download 2 files inside that
|
|
||||||
|
|
||||||
- `docker-compose.yaml`
|
|
||||||
- `plane.env`
|
|
||||||
|
|
||||||
Again the `options [1-8]` will be popped up, and this time hit `8` to exit.
|
|
||||||
|
|
||||||
#### Docker Swarm
|
|
||||||
|
|
||||||
```bash
|
|
||||||
Select an Action you want to perform:
|
|
||||||
1) Deploy Stack
|
|
||||||
2) Remove Stack
|
|
||||||
3) View Stack Status
|
|
||||||
4) Redeploy Stack
|
|
||||||
5) Upgrade
|
|
||||||
6) View Logs
|
|
||||||
7) Exit
|
|
||||||
|
|
||||||
Action [3]: 1
|
|
||||||
```
|
|
||||||
|
|
||||||
For the 1st time setup, type "1" as action input.
|
|
||||||
|
|
||||||
This will create a create a folder `plane-app` and will download 2 files inside that
|
|
||||||
|
|
||||||
- `docker-compose.yaml`
|
|
||||||
- `plane.env`
|
|
||||||
|
|
||||||
Again the `options [1-7]` will be popped up, and this time hit `7` to exit.
|
|
||||||
|
|
||||||
---
|
|
||||||
|
|
||||||
### Continue with setup - Environment Settings
|
|
||||||
|
|
||||||
Before proceeding, we suggest used to review `.env` file and set the values.
|
|
||||||
Below are the most import keys you must refer to. _<span style="color: #fcba03">You can use any text editor to edit this file</span>_.
|
|
||||||
|
|
||||||
> `NGINX_PORT` - This is default set to `80`. Make sure the port you choose to use is not preoccupied. (e.g `NGINX_PORT=8080`)
|
|
||||||
|
|
||||||
> `WEB_URL` - This is default set to `http://localhost`. Change this to the FQDN you plan to use along with NGINX_PORT (eg. `https://plane.example.com:8080` or `http://[IP-ADDRESS]:8080`)
|
|
||||||
|
|
||||||
> `CORS_ALLOWED_ORIGINS` - This is default set to `http://localhost`. Change this to the FQDN you plan to use along with NGINX_PORT (eg. `https://plane.example.com:8080` or `http://[IP-ADDRESS]:8080`)
|
|
||||||
|
|
||||||
There are many other settings you can play with, but we suggest you configure `EMAIL SETTINGS` as it will enable you to invite your teammates onto the platform.
|
|
||||||
|
|
||||||
---
|
|
||||||
|
|
||||||
### Continue with setup - Start Server (Docker Compose)
|
|
||||||
|
|
||||||
Lets again run the `./setup.sh` command. You will again be prompted with the below options. This time select `2` to start the sevices
|
|
||||||
|
|
||||||
```bash
|
|
||||||
Select a Action you want to perform:
|
|
||||||
1) Install (x86_64)
|
|
||||||
2) Start
|
|
||||||
3) Stop
|
|
||||||
4) Restart
|
|
||||||
5) Upgrade
|
|
||||||
6) View Logs
|
|
||||||
7) Backup Data
|
|
||||||
8) Exit
|
|
||||||
|
|
||||||
Action [2]: 2
|
|
||||||
```
|
|
||||||
|
|
||||||
Expect something like this.
|
|
||||||

|
|
||||||
|
|
||||||
Be patient as it might take sometime based on download speed and system configuration. If all goes well, you must see something like this
|
|
||||||
|
|
||||||

|
|
||||||
|
|
||||||
This is the confirmation that all images were downloaded and the services are up & running.
|
|
||||||
|
|
||||||
You have successfully self hosted `Plane` instance. Access the application by going to IP or domain you have configured it (e.g `https://plane.example.com:8080` or `http://[IP-ADDRESS]:8080`)
|
|
||||||
|
|
||||||
---
|
|
||||||
|
|
||||||
### Stopping the Server / Remove Stack
|
|
||||||
|
|
||||||
In case you want to make changes to `plane.env` variables, we suggest you to stop the services before doing that.
|
|
||||||
|
|
||||||
#### Docker Compose
|
|
||||||
|
|
||||||
Lets again run the `./setup.sh` command. You will again be prompted with the below options. This time select `3` to stop the sevices
|
|
||||||
|
|
||||||
```bash
|
|
||||||
Select a Action you want to perform:
|
|
||||||
1) Install (x86_64)
|
|
||||||
2) Start
|
|
||||||
3) Stop
|
|
||||||
4) Restart
|
|
||||||
5) Upgrade
|
|
||||||
6) View Logs
|
|
||||||
7) Backup Data
|
|
||||||
8) Exit
|
|
||||||
|
|
||||||
Action [2]: 3
|
|
||||||
```
|
|
||||||
|
|
||||||
If all goes well, you must see something like this
|
|
||||||
|
|
||||||

|
|
||||||
|
|
||||||
#### Docker Swarm
|
|
||||||
|
|
||||||
Lets again run the `./setup.sh` command. You will again be prompted with the below options. This time select `2` to stop the sevices
|
|
||||||
|
|
||||||
```bash
|
|
||||||
Select an Action you want to perform:
|
|
||||||
1) Deploy Stack
|
|
||||||
2) Remove Stack
|
|
||||||
3) View Stack Status
|
|
||||||
4) Redeploy Stack
|
|
||||||
5) Upgrade
|
|
||||||
6) View Logs
|
|
||||||
7) Exit
|
|
||||||
|
|
||||||
Action [3]: 2
|
|
||||||
```
|
|
||||||
|
|
||||||
If all goes well, you will see the confirmation from docker cli
|
|
||||||
|
|
||||||
---
|
|
||||||
|
|
||||||
### Restarting the Server / Redeploy Stack
|
|
||||||
|
|
||||||
In case you want to make changes to `plane.env` variables, without stopping the server or you noticed some abnormalies in services, you can restart the services with `RESTART` / `REDEPLOY` option.
|
|
||||||
|
|
||||||
Lets again run the `./setup.sh` command. You will again be prompted with the below options. This time select `4` to restart the sevices
|
|
||||||
|
|
||||||
#### Docker Compose
|
|
||||||
```bash
|
|
||||||
Select a Action you want to perform:
|
|
||||||
1) Install (x86_64)
|
|
||||||
2) Start
|
|
||||||
3) Stop
|
|
||||||
4) Restart
|
|
||||||
5) Upgrade
|
|
||||||
6) View Logs
|
|
||||||
7) Backup Data
|
|
||||||
8) Exit
|
|
||||||
|
|
||||||
Action [2]: 4
|
|
||||||
```
|
|
||||||
|
|
||||||
If all goes well, you must see something like this
|
|
||||||
|
|
||||||

|
|
||||||
|
|
||||||
#### Docker Swarm
|
|
||||||
|
|
||||||
```bash
|
|
||||||
1) Deploy Stack
|
|
||||||
2) Remove Stack
|
|
||||||
3) View Stack Status
|
|
||||||
4) Redeploy Stack
|
|
||||||
5) Upgrade
|
|
||||||
6) View Logs
|
|
||||||
7) Exit
|
|
||||||
|
|
||||||
Action [3]: 4
|
|
||||||
```
|
|
||||||
|
|
||||||
If all goes well, you will see the confirmation from docker cli
|
|
||||||
|
|
||||||
---
|
|
||||||
|
|
||||||
### Upgrading Plane Version
|
|
||||||
|
|
||||||
It is always advised to keep Plane up to date with the latest release.
|
|
||||||
|
|
||||||
Lets again run the `./setup.sh` command. You will again be prompted with the below options. This time select `5` to upgrade the release.
|
|
||||||
|
|
||||||
#### Docker Compose
|
|
||||||
|
|
||||||
```bash
|
|
||||||
Select a Action you want to perform:
|
|
||||||
1) Install (x86_64)
|
|
||||||
2) Start
|
|
||||||
3) Stop
|
|
||||||
4) Restart
|
|
||||||
5) Upgrade
|
|
||||||
6) View Logs
|
|
||||||
7) Backup Data
|
|
||||||
8) Exit
|
|
||||||
|
|
||||||
Action [2]: 5
|
|
||||||
```
|
|
||||||
|
|
||||||
By choosing this, it will stop the services and then will download the latest `docker-compose.yaml` and `plane.env`.
|
|
||||||
|
|
||||||
You must expect the below message
|
|
||||||
|
|
||||||

|
|
||||||
|
|
||||||
Once done, choose `8` to exit from prompt.
|
|
||||||
|
|
||||||
> It is very important for you to validate the `plane.env` for the new changes.
|
|
||||||
|
|
||||||
Once done with making changes in `plane.env` file, jump on to `Start Server`
|
|
||||||
|
|
||||||
#### Docker Swarm
|
|
||||||
|
|
||||||
Lets again run the `./setup.sh` command. You will again be prompted with the below options. This time select `5` to upgrade the release.
|
|
||||||
|
|
||||||
```bash
|
|
||||||
1) Deploy Stack
|
|
||||||
2) Remove Stack
|
|
||||||
3) View Stack Status
|
|
||||||
4) Redeploy Stack
|
|
||||||
5) Upgrade
|
|
||||||
6) View Logs
|
|
||||||
7) Exit
|
|
||||||
|
|
||||||
Action [3]: 5
|
|
||||||
```
|
|
||||||
|
|
||||||
By choosing this, it will stop the services and then will download the latest `docker-compose.yaml` and `plane.env`.
|
|
||||||
|
|
||||||
Once done, choose `7` to exit from prompt.
|
|
||||||
|
|
||||||
> It is very important for you to validate the `plane.env` for the new changes.
|
|
||||||
|
|
||||||
Once done with making changes in `plane.env` file, jump on to `Redeploy Stack`
|
|
||||||
|
|
||||||
---
|
|
||||||
|
|
||||||
### View Logs
|
|
||||||
|
|
||||||
There would a time when you might want to check what is happening inside the API, Worker or any other container.
|
|
||||||
|
|
||||||
Lets again run the `./setup.sh` command. You will again be prompted with the below options.
|
|
||||||
|
|
||||||
This time select `6` to view logs.
|
|
||||||
|
|
||||||
#### Docker Compose
|
|
||||||
|
|
||||||
```bash
|
|
||||||
Select a Action you want to perform:
|
|
||||||
1) Install (x86_64)
|
|
||||||
2) Start
|
|
||||||
3) Stop
|
|
||||||
4) Restart
|
|
||||||
5) Upgrade
|
|
||||||
6) View Logs
|
|
||||||
7) Backup Data
|
|
||||||
8) Exit
|
|
||||||
|
|
||||||
Action [2]: 6
|
|
||||||
```
|
|
||||||
|
|
||||||
#### Docker Swarm
|
|
||||||
|
|
||||||
|
|
||||||
```bash
|
|
||||||
1) Deploy Stack
|
|
||||||
2) Remove Stack
|
|
||||||
3) View Stack Status
|
|
||||||
4) Redeploy Stack
|
|
||||||
5) Upgrade
|
|
||||||
6) View Logs
|
|
||||||
7) Exit
|
|
||||||
|
|
||||||
Action [3]: 6
|
|
||||||
```
|
|
||||||
|
|
||||||
#### Service Menu Options for Logs
|
|
||||||
This will further open sub-menu with list of services
|
|
||||||
```bash
|
|
||||||
Select a Service you want to view the logs for:
|
|
||||||
1) Web
|
|
||||||
2) Space
|
|
||||||
3) API
|
|
||||||
4) Worker
|
|
||||||
5) Beat-Worker
|
|
||||||
6) Migrator
|
|
||||||
7) Proxy
|
|
||||||
8) Redis
|
|
||||||
9) Postgres
|
|
||||||
10) Minio
|
|
||||||
11) RabbitMQ
|
|
||||||
0) Back to Main Menu
|
|
||||||
|
|
||||||
Service: 3
|
|
||||||
```
|
|
||||||
|
|
||||||
Select any of the service to view the logs e.g. `3`. Expect something similar to this
|
|
||||||
```bash
|
|
||||||
api-1 | Waiting for database...
|
|
||||||
api-1 | Database available!
|
|
||||||
api-1 | Waiting for database migrations to complete...
|
|
||||||
api-1 | Waiting for database migrations to complete...
|
|
||||||
api-1 | Waiting for database migrations to complete...
|
|
||||||
api-1 | Waiting for database migrations to complete...
|
|
||||||
api-1 | Waiting for database migrations to complete...
|
|
||||||
api-1 | Waiting for database migrations to complete...
|
|
||||||
api-1 | Waiting for database migrations to complete...
|
|
||||||
api-1 | No migrations Pending. Starting processes ...
|
|
||||||
api-1 | Instance registered
|
|
||||||
api-1 | ENABLE_SIGNUP loaded with value from environment variable.
|
|
||||||
api-1 | ENABLE_EMAIL_PASSWORD loaded with value from environment variable.
|
|
||||||
api-1 | ENABLE_MAGIC_LINK_LOGIN loaded with value from environment variable.
|
|
||||||
api-1 | GOOGLE_CLIENT_ID loaded with value from environment variable.
|
|
||||||
api-1 | GITHUB_CLIENT_ID loaded with value from environment variable.
|
|
||||||
api-1 | GITHUB_CLIENT_SECRET loaded with value from environment variable.
|
|
||||||
api-1 | EMAIL_HOST loaded with value from environment variable.
|
|
||||||
api-1 | EMAIL_HOST_USER loaded with value from environment variable.
|
|
||||||
api-1 | EMAIL_HOST_PASSWORD loaded with value from environment variable.
|
|
||||||
api-1 | EMAIL_PORT loaded with value from environment variable.
|
|
||||||
api-1 | EMAIL_FROM loaded with value from environment variable.
|
|
||||||
api-1 | EMAIL_USE_TLS loaded with value from environment variable.
|
|
||||||
api-1 | EMAIL_USE_SSL loaded with value from environment variable.
|
|
||||||
api-1 | OPENAI_API_KEY loaded with value from environment variable.
|
|
||||||
api-1 | GPT_ENGINE loaded with value from environment variable.
|
|
||||||
api-1 | UNSPLASH_ACCESS_KEY loaded with value from environment variable.
|
|
||||||
api-1 | Checking bucket...
|
|
||||||
api-1 | Bucket 'uploads' does not exist. Creating bucket...
|
|
||||||
api-1 | Bucket 'uploads' created successfully.
|
|
||||||
api-1 | Public read access policy set for bucket 'uploads'.
|
|
||||||
api-1 | Cache Cleared
|
|
||||||
api-1 | [2024-05-02 03:56:01 +0000] [1] [INFO] Starting gunicorn 21.2.0
|
|
||||||
api-1 | [2024-05-02 03:56:01 +0000] [1] [INFO] Listening at: http://0.0.0.0:8000 (1)
|
|
||||||
api-1 | [2024-05-02 03:56:01 +0000] [1] [INFO] Using worker: uvicorn.workers.UvicornWorker
|
|
||||||
api-1 | [2024-05-02 03:56:01 +0000] [25] [INFO] Booting worker with pid: 25
|
|
||||||
api-1 | [2024-05-02 03:56:03 +0000] [25] [INFO] Started server process [25]
|
|
||||||
api-1 | [2024-05-02 03:56:03 +0000] [25] [INFO] Waiting for application startup.
|
|
||||||
api-1 | [2024-05-02 03:56:03 +0000] [25] [INFO] ASGI 'lifespan' protocol appears unsupported.
|
|
||||||
api-1 | [2024-05-02 03:56:03 +0000] [25] [INFO] Application startup complete.
|
|
||||||
|
|
||||||
```
|
|
||||||
|
|
||||||
To exit this, use `CTRL+C` and then you will land on to the main-menu with the list of actions.
|
|
||||||
|
|
||||||
Similarly, you can view the logs of other services.
|
|
||||||
|
|
||||||
---
|
|
||||||
|
|
||||||
### Backup Data (Docker Compose)
|
|
||||||
|
|
||||||
There would a time when you might want to backup your data from docker volumes to external storage like S3 or drives.
|
|
||||||
|
|
||||||
Lets again run the `./setup.sh` command. You will again be prompted with the below options. This time select `7` to Backup the data.
|
|
||||||
|
|
||||||
```bash
|
|
||||||
Select a Action you want to perform:
|
|
||||||
1) Install (x86_64)
|
|
||||||
2) Start
|
|
||||||
3) Stop
|
|
||||||
4) Restart
|
|
||||||
5) Upgrade
|
|
||||||
6) View Logs
|
|
||||||
7) Backup Data
|
|
||||||
8) Exit
|
|
||||||
|
|
||||||
Action [2]: 7
|
|
||||||
```
|
|
||||||
|
|
||||||
In response, you can find the backup folder
|
|
||||||
|
|
||||||
```bash
|
|
||||||
Backing Up plane-app_pgdata
|
|
||||||
Backing Up plane-app_redisdata
|
|
||||||
Backing Up plane-app_uploads
|
|
||||||
|
|
||||||
Backup completed successfully. Backup files are stored in /....../plane-app/backup/20240502-1120
|
|
||||||
```
|
|
||||||
|
|
||||||
---
|
|
||||||
|
|
||||||
### Restore Data (Docker Compose)
|
|
||||||
|
|
||||||
When you want to restore the previously backed-up data, follow the instructions below.
|
|
||||||
|
|
||||||
1. Make sure that Plane-CE is installed, started, and then stopped. This ensures that the Docker volumes are created.
|
|
||||||
|
|
||||||
1. Download the restore script using the command below. We suggest downloading it in the same folder as `setup.sh`.
|
|
||||||
|
|
||||||
```bash
|
|
||||||
curl -fsSL -o restore.sh https://github.com/makeplane/plane/releases/latest/download/restore.sh
|
|
||||||
chmod +x restore.sh
|
|
||||||
```
|
|
||||||
|
|
||||||
1. Execute the command below to restore your data.
|
|
||||||
|
|
||||||
```bash
|
|
||||||
./restore.sh <path to backup folder containing *.tar.gz files>
|
|
||||||
```
|
|
||||||
|
|
||||||
As an example, for a backup folder `/opt/plane-selfhost/plane-app/backup/20240722-0914`, expect the response below:
|
|
||||||
|
|
||||||
```bash
|
|
||||||
--------------------------------------------
|
|
||||||
____ _ /////////
|
|
||||||
| _ \| | __ _ _ __ ___ /////////
|
|
||||||
| |_) | |/ _` | '_ \ / _ \ ///// /////
|
|
||||||
| __/| | (_| | | | | __/ ///// /////
|
|
||||||
|_| |_|\__,_|_| |_|\___| ////
|
|
||||||
////
|
|
||||||
--------------------------------------------
|
|
||||||
Project management tool from the future
|
|
||||||
--------------------------------------------
|
|
||||||
Found /opt/plane-selfhost/plane-app/backup/20240722-0914/pgdata.tar.gz
|
|
||||||
.....Restoring plane-app_pgdata
|
|
||||||
.....Successfully restored volume plane-app_pgdata from pgdata.tar.gz
|
|
||||||
|
|
||||||
Found /opt/plane-selfhost/plane-app/backup/20240722-0914/redisdata.tar.gz
|
|
||||||
.....Restoring plane-app_redisdata
|
|
||||||
.....Successfully restored volume plane-app_redisdata from redisdata.tar.gz
|
|
||||||
|
|
||||||
Found /opt/plane-selfhost/plane-app/backup/20240722-0914/uploads.tar.gz
|
|
||||||
.....Restoring plane-app_uploads
|
|
||||||
.....Successfully restored volume plane-app_uploads from uploads.tar.gz
|
|
||||||
|
|
||||||
|
|
||||||
Restore completed successfully.
|
|
||||||
```
|
|
||||||
|
|
||||||
1. Start the Plane instance using `./setup.sh start`.
|
|
||||||
|
|
||||||
---
|
|
||||||
|
|
||||||
### Restore for Commercial Air-Gapped (Docker Compose)
|
|
||||||
|
|
||||||
When you want to restore the previously backed-up data on Plane Commercial Air-Gapped version, follow the instructions below.
|
|
||||||
|
|
||||||
1. Download the restore script using the command below
|
|
||||||
|
|
||||||
```bash
|
|
||||||
curl -fsSL -o restore-airgapped.sh https://github.com/makeplane/plane/releases/latest/download/restore-airgapped.sh
|
|
||||||
chmod +x restore-airgapped.sh
|
|
||||||
```
|
|
||||||
|
|
||||||
1. Copy the backup folder and the `restore-airgapped.sh` to `Commercial Airgapped Edition` server
|
|
||||||
|
|
||||||
1. Make sure that Plane Commercial (Airgapped) is extracted and ready to get started. In case it is running, you would need to stop that.
|
|
||||||
|
|
||||||
1. Execute the command below to restore your data.
|
|
||||||
|
|
||||||
```bash
|
|
||||||
./restore-airgapped.sh <path to backup folder containing *.tar.gz files>
|
|
||||||
```
|
|
||||||
|
|
||||||
1. After restoration, you are ready to start Plane Commercial (Airgapped) will all your previously saved data.
|
|
||||||
|
|
||||||
---
|
|
||||||
|
|
||||||
<details>
|
|
||||||
<summary><h2>Upgrading from v0.13.2 to v0.14.x</h2></summary>
|
|
||||||
|
|
||||||
This is one time activity for users who are upgrading from v0.13.2 to v0.14.0
|
|
||||||
|
|
||||||
As there has been significant changes to Self Hosting process, this step mainly covers the data migration from current (v0.13.2) docker volumes from newly created volumes
|
|
||||||
|
|
||||||
> Before we begin with migration, make sure your v0.14.0 was started and then stopped. This is required to know the newly created docker volume names.
|
|
||||||
|
|
||||||
Begin with downloading the migration script using below command
|
|
||||||
|
|
||||||
```
|
|
||||||
|
|
||||||
curl -fsSL -o migrate.sh https://raw.githubusercontent.com/makeplane/plane/master/deploy/selfhost/migration-0.13-0.14.sh
|
|
||||||
|
|
||||||
chmod +x migrate.sh
|
|
||||||
|
|
||||||
```
|
|
||||||
|
|
||||||
Now run the `./migrate.sh` command and expect the instructions as below
|
|
||||||
|
|
||||||
```
|
|
||||||
******************************************************************
|
|
||||||
|
|
||||||
This script is solely for the migration purpose only.
|
|
||||||
This is a 1 time migration of volume data from v0.13.2 => v0.14.x
|
|
||||||
|
|
||||||
Assumption:
|
|
||||||
1. Postgres data volume name ends with _pgdata
|
|
||||||
2. Minio data volume name ends with _uploads
|
|
||||||
3. Redis data volume name ends with _redisdata
|
|
||||||
|
|
||||||
Any changes to this script can break the migration.
|
|
||||||
|
|
||||||
Before you proceed, make sure you run the below command
|
|
||||||
to know the docker volumes
|
|
||||||
|
|
||||||
docker volume ls -q | grep -i "_pgdata"
|
|
||||||
docker volume ls -q | grep -i "_uploads"
|
|
||||||
docker volume ls -q | grep -i "_redisdata"
|
|
||||||
|
|
||||||
*******************************************************
|
|
||||||
|
|
||||||
Given below list of REDIS volumes, identify the prefix of source and destination volumes leaving "_redisdata"
|
|
||||||
---------------------
|
|
||||||
plane-app_redisdata
|
|
||||||
v0132_redisdata
|
|
||||||
|
|
||||||
Provide the Source Volume Prefix :
|
|
||||||
```
|
|
||||||
|
|
||||||
**Open another terminal window**, and run the mentioned 3 command. This may be different for users who have changed the volume names in their previous setup (v0.13.2)
|
|
||||||
|
|
||||||
For every command you must see 2 records something like shown in above example of `redisdata`
|
|
||||||
|
|
||||||
To move forward, you would need PREFIX of old setup and new setup. As per above example, `v0132` is the prefix of v0.13.2 and `plane-app` is the prefix of v0.14.0 setup
|
|
||||||
|
|
||||||
**Back to original terminal window**, _Provide the Source Volume Prefix_ and hit ENTER.
|
|
||||||
|
|
||||||
Now you will be prompted to _Provide Destination Volume Prefix_. Provide the value and hit ENTER
|
|
||||||
|
|
||||||
```
|
|
||||||
Provide the Source Volume Prefix : v0132
|
|
||||||
Provide the Destination Volume Prefix : plane-app
|
|
||||||
```
|
|
||||||
|
|
||||||
In case the suffixes are wrong or the mentioned volumes are not found, you will receive the error shown below. The image below displays an error for source volumes.
|
|
||||||
|
|
||||||

|
|
||||||
|
|
||||||
In case of successful migration, it will be a silent exit without error.
|
|
||||||
|
|
||||||
Now its time to restart v0.14.0 setup.
|
|
||||||
</details>
|
|
||||||
@@ -1,30 +0,0 @@
|
|||||||
services:
|
|
||||||
web:
|
|
||||||
image: ${DOCKERHUB_USER:-local}/plane-frontend:${APP_RELEASE:-latest}
|
|
||||||
build:
|
|
||||||
context: .
|
|
||||||
dockerfile: ./web/Dockerfile.web
|
|
||||||
|
|
||||||
space:
|
|
||||||
image: ${DOCKERHUB_USER:-local}/plane-space:${APP_RELEASE:-latest}
|
|
||||||
build:
|
|
||||||
context: ./
|
|
||||||
dockerfile: ./space/Dockerfile.space
|
|
||||||
|
|
||||||
admin:
|
|
||||||
image: ${DOCKERHUB_USER:-local}/plane-admin:${APP_RELEASE:-latest}
|
|
||||||
build:
|
|
||||||
context: ./
|
|
||||||
dockerfile: ./admin/Dockerfile.admin
|
|
||||||
|
|
||||||
api:
|
|
||||||
image: ${DOCKERHUB_USER:-local}/plane-backend:${APP_RELEASE:-latest}
|
|
||||||
build:
|
|
||||||
context: ./apiserver
|
|
||||||
dockerfile: ./Dockerfile.api
|
|
||||||
|
|
||||||
proxy:
|
|
||||||
image: ${DOCKERHUB_USER:-local}/plane-proxy:${APP_RELEASE:-latest}
|
|
||||||
build:
|
|
||||||
context: ./nginx
|
|
||||||
dockerfile: ./Dockerfile
|
|
||||||
@@ -24,9 +24,15 @@ x-aws-s3-env: &aws-s3-env
|
|||||||
AWS_S3_BUCKET_NAME: ${AWS_S3_BUCKET_NAME:-uploads}
|
AWS_S3_BUCKET_NAME: ${AWS_S3_BUCKET_NAME:-uploads}
|
||||||
|
|
||||||
x-proxy-env: &proxy-env
|
x-proxy-env: &proxy-env
|
||||||
NGINX_PORT: ${NGINX_PORT:-80}
|
APP_DOMAIN: ${APP_DOMAIN:-localhost}
|
||||||
BUCKET_NAME: ${AWS_S3_BUCKET_NAME:-uploads}
|
|
||||||
FILE_SIZE_LIMIT: ${FILE_SIZE_LIMIT:-5242880}
|
FILE_SIZE_LIMIT: ${FILE_SIZE_LIMIT:-5242880}
|
||||||
|
CERT_EMAIL: ${CERT_EMAIL}
|
||||||
|
CERT_ACME_CA: ${CERT_ACME_CA}
|
||||||
|
CERT_ACME_DNS: ${CERT_ACME_DNS}
|
||||||
|
LISTEN_HTTP_PORT: ${LISTEN_HTTP_PORT:-80}
|
||||||
|
LISTEN_HTTPS_PORT: ${LISTEN_HTTPS_PORT:-443}
|
||||||
|
BUCKET_NAME: ${AWS_S3_BUCKET_NAME:-uploads}
|
||||||
|
SITE_ADDRESS: ${SITE_ADDRESS:-:80}
|
||||||
|
|
||||||
x-mq-env:
|
x-mq-env:
|
||||||
# RabbitMQ Settings
|
# RabbitMQ Settings
|
||||||
@@ -40,6 +46,7 @@ x-mq-env:
|
|||||||
|
|
||||||
x-live-env: &live-env
|
x-live-env: &live-env
|
||||||
API_BASE_URL: ${API_BASE_URL:-http://api:8000}
|
API_BASE_URL: ${API_BASE_URL:-http://api:8000}
|
||||||
|
LIVE_SERVER_SECRET_KEY: ${LIVE_SERVER_SECRET_KEY:-2FiJk1U2aiVPEQtzLehYGlTSnTnrs7LW}
|
||||||
|
|
||||||
x-app-env: &app-env
|
x-app-env: &app-env
|
||||||
WEB_URL: ${WEB_URL:-http://localhost}
|
WEB_URL: ${WEB_URL:-http://localhost}
|
||||||
@@ -52,62 +59,59 @@ x-app-env: &app-env
|
|||||||
AMQP_URL: ${AMQP_URL:-amqp://plane:plane@plane-mq:5672/plane}
|
AMQP_URL: ${AMQP_URL:-amqp://plane:plane@plane-mq:5672/plane}
|
||||||
API_KEY_RATE_LIMIT: ${API_KEY_RATE_LIMIT:-60/minute}
|
API_KEY_RATE_LIMIT: ${API_KEY_RATE_LIMIT:-60/minute}
|
||||||
MINIO_ENDPOINT_SSL: ${MINIO_ENDPOINT_SSL:-0}
|
MINIO_ENDPOINT_SSL: ${MINIO_ENDPOINT_SSL:-0}
|
||||||
|
LIVE_SERVER_SECRET_KEY: ${LIVE_SERVER_SECRET_KEY:-2FiJk1U2aiVPEQtzLehYGlTSnTnrs7LW}
|
||||||
|
|
||||||
services:
|
services:
|
||||||
web:
|
web:
|
||||||
image: artifacts.plane.so/makeplane/plane-frontend:${APP_RELEASE:-stable}
|
image: artifacts.plane.so/makeplane/plane-frontend:${APP_RELEASE:-v1.2.1}
|
||||||
command: node web/server.js web
|
|
||||||
deploy:
|
deploy:
|
||||||
replicas: ${WEB_REPLICAS:-1}
|
replicas: ${WEB_REPLICAS:-1}
|
||||||
restart_policy:
|
restart_policy:
|
||||||
condition: on-failure
|
condition: any
|
||||||
depends_on:
|
depends_on:
|
||||||
- api
|
- api
|
||||||
- worker
|
- worker
|
||||||
|
|
||||||
space:
|
space:
|
||||||
image: artifacts.plane.so/makeplane/plane-space:${APP_RELEASE:-stable}
|
image: artifacts.plane.so/makeplane/plane-space:${APP_RELEASE:-v1.2.1}
|
||||||
command: node space/server.js space
|
|
||||||
deploy:
|
deploy:
|
||||||
replicas: ${SPACE_REPLICAS:-1}
|
replicas: ${SPACE_REPLICAS:-1}
|
||||||
restart_policy:
|
restart_policy:
|
||||||
condition: on-failure
|
condition: any
|
||||||
depends_on:
|
depends_on:
|
||||||
- api
|
- api
|
||||||
- worker
|
- worker
|
||||||
- web
|
- web
|
||||||
|
|
||||||
admin:
|
admin:
|
||||||
image: artifacts.plane.so/makeplane/plane-admin:${APP_RELEASE:-stable}
|
image: artifacts.plane.so/makeplane/plane-admin:${APP_RELEASE:-v1.2.1}
|
||||||
command: node admin/server.js admin
|
|
||||||
deploy:
|
deploy:
|
||||||
replicas: ${ADMIN_REPLICAS:-1}
|
replicas: ${ADMIN_REPLICAS:-1}
|
||||||
restart_policy:
|
restart_policy:
|
||||||
condition: on-failure
|
condition: any
|
||||||
depends_on:
|
depends_on:
|
||||||
- api
|
- api
|
||||||
- web
|
- web
|
||||||
|
|
||||||
live:
|
live:
|
||||||
image: artifacts.plane.so/makeplane/plane-live:${APP_RELEASE:-stable}
|
image: artifacts.plane.so/makeplane/plane-live:${APP_RELEASE:-v1.2.1}
|
||||||
command: node live/dist/server.js live
|
|
||||||
environment:
|
environment:
|
||||||
<<: [ *live-env ]
|
<<: [ *live-env, *redis-env ]
|
||||||
deploy:
|
deploy:
|
||||||
replicas: ${LIVE_REPLICAS:-1}
|
replicas: ${LIVE_REPLICAS:-1}
|
||||||
restart_policy:
|
restart_policy:
|
||||||
condition: on-failure
|
condition: any
|
||||||
depends_on:
|
depends_on:
|
||||||
- api
|
- api
|
||||||
- web
|
- web
|
||||||
|
|
||||||
api:
|
api:
|
||||||
image: artifacts.plane.so/makeplane/plane-backend:${APP_RELEASE:-stable}
|
image: artifacts.plane.so/makeplane/plane-backend:${APP_RELEASE:-v1.2.1}
|
||||||
command: ./bin/docker-entrypoint-api.sh
|
command: ./bin/docker-entrypoint-api.sh
|
||||||
deploy:
|
deploy:
|
||||||
replicas: ${API_REPLICAS:-1}
|
replicas: ${API_REPLICAS:-1}
|
||||||
restart_policy:
|
restart_policy:
|
||||||
condition: on-failure
|
condition: any
|
||||||
volumes:
|
volumes:
|
||||||
- logs_api:/code/plane/logs
|
- logs_api:/code/plane/logs
|
||||||
environment:
|
environment:
|
||||||
@@ -118,12 +122,12 @@ services:
|
|||||||
- plane-mq
|
- plane-mq
|
||||||
|
|
||||||
worker:
|
worker:
|
||||||
image: artifacts.plane.so/makeplane/plane-backend:${APP_RELEASE:-stable}
|
image: artifacts.plane.so/makeplane/plane-backend:${APP_RELEASE:-v1.2.1}
|
||||||
command: ./bin/docker-entrypoint-worker.sh
|
command: ./bin/docker-entrypoint-worker.sh
|
||||||
deploy:
|
deploy:
|
||||||
replicas: ${WORKER_REPLICAS:-1}
|
replicas: ${WORKER_REPLICAS:-1}
|
||||||
restart_policy:
|
restart_policy:
|
||||||
condition: on-failure
|
condition: any
|
||||||
volumes:
|
volumes:
|
||||||
- logs_worker:/code/plane/logs
|
- logs_worker:/code/plane/logs
|
||||||
environment:
|
environment:
|
||||||
@@ -135,12 +139,12 @@ services:
|
|||||||
- plane-mq
|
- plane-mq
|
||||||
|
|
||||||
beat-worker:
|
beat-worker:
|
||||||
image: artifacts.plane.so/makeplane/plane-backend:${APP_RELEASE:-stable}
|
image: artifacts.plane.so/makeplane/plane-backend:${APP_RELEASE:-v1.2.1}
|
||||||
command: ./bin/docker-entrypoint-beat.sh
|
command: ./bin/docker-entrypoint-beat.sh
|
||||||
deploy:
|
deploy:
|
||||||
replicas: ${BEAT_WORKER_REPLICAS:-1}
|
replicas: ${BEAT_WORKER_REPLICAS:-1}
|
||||||
restart_policy:
|
restart_policy:
|
||||||
condition: on-failure
|
condition: any
|
||||||
volumes:
|
volumes:
|
||||||
- logs_beat-worker:/code/plane/logs
|
- logs_beat-worker:/code/plane/logs
|
||||||
environment:
|
environment:
|
||||||
@@ -152,7 +156,7 @@ services:
|
|||||||
- plane-mq
|
- plane-mq
|
||||||
|
|
||||||
migrator:
|
migrator:
|
||||||
image: artifacts.plane.so/makeplane/plane-backend:${APP_RELEASE:-stable}
|
image: artifacts.plane.so/makeplane/plane-backend:${APP_RELEASE:-v1.2.1}
|
||||||
command: ./bin/docker-entrypoint-migrator.sh
|
command: ./bin/docker-entrypoint-migrator.sh
|
||||||
deploy:
|
deploy:
|
||||||
replicas: 1
|
replicas: 1
|
||||||
@@ -173,18 +177,18 @@ services:
|
|||||||
deploy:
|
deploy:
|
||||||
replicas: 1
|
replicas: 1
|
||||||
restart_policy:
|
restart_policy:
|
||||||
condition: on-failure
|
condition: any
|
||||||
environment:
|
environment:
|
||||||
<<: *db-env
|
<<: *db-env
|
||||||
volumes:
|
volumes:
|
||||||
- pgdata:/var/lib/postgresql/data
|
- pgdata:/var/lib/postgresql/data
|
||||||
|
|
||||||
plane-redis:
|
plane-redis:
|
||||||
image: valkey/valkey:7.2.5-alpine
|
image: valkey/valkey:7.2.11-alpine
|
||||||
deploy:
|
deploy:
|
||||||
replicas: 1
|
replicas: 1
|
||||||
restart_policy:
|
restart_policy:
|
||||||
condition: on-failure
|
condition: any
|
||||||
volumes:
|
volumes:
|
||||||
- redisdata:/data
|
- redisdata:/data
|
||||||
|
|
||||||
@@ -193,7 +197,7 @@ services:
|
|||||||
deploy:
|
deploy:
|
||||||
replicas: 1
|
replicas: 1
|
||||||
restart_policy:
|
restart_policy:
|
||||||
condition: on-failure
|
condition: any
|
||||||
environment:
|
environment:
|
||||||
<<: *mq-env
|
<<: *mq-env
|
||||||
volumes:
|
volumes:
|
||||||
@@ -206,7 +210,7 @@ services:
|
|||||||
deploy:
|
deploy:
|
||||||
replicas: 1
|
replicas: 1
|
||||||
restart_policy:
|
restart_policy:
|
||||||
condition: on-failure
|
condition: any
|
||||||
environment:
|
environment:
|
||||||
<<: *minio-env
|
<<: *minio-env
|
||||||
volumes:
|
volumes:
|
||||||
@@ -214,17 +218,22 @@ services:
|
|||||||
|
|
||||||
# Comment this if you already have a reverse proxy running
|
# Comment this if you already have a reverse proxy running
|
||||||
proxy:
|
proxy:
|
||||||
image: artifacts.plane.so/makeplane/plane-proxy:${APP_RELEASE:-stable}
|
image: artifacts.plane.so/makeplane/plane-proxy:${APP_RELEASE:-v1.2.1}
|
||||||
environment:
|
|
||||||
<<: *proxy-env
|
|
||||||
deploy:
|
deploy:
|
||||||
replicas: 1
|
replicas: 1
|
||||||
restart_policy:
|
restart_policy:
|
||||||
condition: on-failure
|
condition: any
|
||||||
|
environment:
|
||||||
|
<<: *proxy-env
|
||||||
|
volumes:
|
||||||
|
- proxy_config:/config
|
||||||
|
- proxy_data:/data
|
||||||
depends_on:
|
depends_on:
|
||||||
- web
|
- web
|
||||||
- api
|
- api
|
||||||
- space
|
- space
|
||||||
|
- admin
|
||||||
|
- live
|
||||||
|
|
||||||
volumes:
|
volumes:
|
||||||
pgdata:
|
pgdata:
|
||||||
@@ -235,3 +244,5 @@ volumes:
|
|||||||
logs_beat-worker:
|
logs_beat-worker:
|
||||||
logs_migrator:
|
logs_migrator:
|
||||||
rabbitmq_data:
|
rabbitmq_data:
|
||||||
|
proxy_config:
|
||||||
|
proxy_data:
|
||||||
|
|||||||
Binary file not shown.
|
Before Width: | Height: | Size: 22 KiB |
Binary file not shown.
|
Before Width: | Height: | Size: 14 KiB |
Binary file not shown.
|
Before Width: | Height: | Size: 15 KiB |
Binary file not shown.
|
Before Width: | Height: | Size: 21 KiB |
Binary file not shown.
|
Before Width: | Height: | Size: 16 KiB |
Binary file not shown.
|
Before Width: | Height: | Size: 54 KiB |
@@ -1,118 +0,0 @@
|
|||||||
#!/bin/bash
|
|
||||||
|
|
||||||
echo '
|
|
||||||
******************************************************************
|
|
||||||
|
|
||||||
This script is solely for the migration purpose only.
|
|
||||||
This is a 1 time migration of volume data from v0.13.2 => v0.14.x
|
|
||||||
|
|
||||||
Assumption:
|
|
||||||
1. Postgres data volume name ends with _pgdata
|
|
||||||
2. Minio data volume name ends with _uploads
|
|
||||||
3. Redis data volume name ends with _redisdata
|
|
||||||
|
|
||||||
Any changes to this script can break the migration.
|
|
||||||
|
|
||||||
Before you proceed, make sure you run the below command
|
|
||||||
to know the docker volumes
|
|
||||||
|
|
||||||
docker volume ls -q | grep -i "_pgdata"
|
|
||||||
docker volume ls -q | grep -i "_uploads"
|
|
||||||
docker volume ls -q | grep -i "_redisdata"
|
|
||||||
|
|
||||||
*******************************************************
|
|
||||||
'
|
|
||||||
|
|
||||||
DOWNLOAD_FOL=./download
|
|
||||||
rm -rf ${DOWNLOAD_FOL}
|
|
||||||
mkdir -p ${DOWNLOAD_FOL}
|
|
||||||
|
|
||||||
function volumeExists {
|
|
||||||
if [ "$(docker volume ls -f name=$1 | awk '{print $NF}' | grep -E '^'$1'$')" ]; then
|
|
||||||
return 0
|
|
||||||
else
|
|
||||||
return 1
|
|
||||||
fi
|
|
||||||
}
|
|
||||||
|
|
||||||
function readPrefixes(){
|
|
||||||
echo ''
|
|
||||||
echo 'Given below list of REDIS volumes, identify the prefix of source and destination volumes leaving "_redisdata" '
|
|
||||||
echo '---------------------'
|
|
||||||
docker volume ls -q | grep -i "_redisdata"
|
|
||||||
echo ''
|
|
||||||
|
|
||||||
read -p "Provide the Source Volume Prefix : " SRC_VOL_PREFIX
|
|
||||||
until [ "$SRC_VOL_PREFIX" ]; do
|
|
||||||
read -p "Provide the Source Volume Prefix : " SRC_VOL_PREFIX
|
|
||||||
done
|
|
||||||
|
|
||||||
read -p "Provide the Destination Volume Prefix : " DEST_VOL_PREFIX
|
|
||||||
until [ "$DEST_VOL_PREFIX" ]; do
|
|
||||||
read -p "Provide the Source Volume Prefix : " DEST_VOL_PREFIX
|
|
||||||
done
|
|
||||||
|
|
||||||
echo ''
|
|
||||||
echo 'Prefix Provided '
|
|
||||||
echo " Source : ${SRC_VOL_PREFIX}"
|
|
||||||
echo " Destination : ${DEST_VOL_PREFIX}"
|
|
||||||
echo '---------------------------------------'
|
|
||||||
}
|
|
||||||
|
|
||||||
function migrate(){
|
|
||||||
|
|
||||||
SRC_VOLUME=${SRC_VOL_PREFIX}_${VOL_NAME_SUFFIX}
|
|
||||||
DEST_VOLUME=${DEST_VOL_PREFIX}_${VOL_NAME_SUFFIX}
|
|
||||||
|
|
||||||
if volumeExists $SRC_VOLUME; then
|
|
||||||
if volumeExists $DEST_VOLUME; then
|
|
||||||
GOOD_TO_GO=1
|
|
||||||
else
|
|
||||||
echo "Destination Volume '$DEST_VOLUME' does not exist"
|
|
||||||
echo ''
|
|
||||||
fi
|
|
||||||
else
|
|
||||||
echo "Source Volume '$SRC_VOLUME' does not exist"
|
|
||||||
echo ''
|
|
||||||
fi
|
|
||||||
|
|
||||||
if [ $GOOD_TO_GO = 1 ]; then
|
|
||||||
|
|
||||||
echo "MIGRATING ${VOL_NAME_SUFFIX} FROM ${SRC_VOLUME} => ${DEST_VOLUME}"
|
|
||||||
|
|
||||||
TEMP_CONTAINER=$(docker run -d -v $SRC_VOLUME:$CONTAINER_VOL_FOLDER busybox true)
|
|
||||||
docker cp -q $TEMP_CONTAINER:$CONTAINER_VOL_FOLDER ${DOWNLOAD_FOL}/${VOL_NAME_SUFFIX}
|
|
||||||
docker rm $TEMP_CONTAINER &> /dev/null
|
|
||||||
|
|
||||||
TEMP_CONTAINER=$(docker run -d -v $DEST_VOLUME:$CONTAINER_VOL_FOLDER busybox true)
|
|
||||||
if [ "$VOL_NAME_SUFFIX" = "pgdata" ]; then
|
|
||||||
docker cp -q ${DOWNLOAD_FOL}/${VOL_NAME_SUFFIX} $TEMP_CONTAINER:$CONTAINER_VOL_FOLDER/_temp
|
|
||||||
docker run --rm -v $DEST_VOLUME:$CONTAINER_VOL_FOLDER \
|
|
||||||
-e DATA_FOLDER="${CONTAINER_VOL_FOLDER}" \
|
|
||||||
busybox /bin/sh -c 'cp -Rf $DATA_FOLDER/_temp/* $DATA_FOLDER '
|
|
||||||
else
|
|
||||||
docker cp -q ${DOWNLOAD_FOL}/${VOL_NAME_SUFFIX} $TEMP_CONTAINER:$CONTAINER_VOL_FOLDER
|
|
||||||
fi
|
|
||||||
docker rm $TEMP_CONTAINER &> /dev/null
|
|
||||||
|
|
||||||
echo ''
|
|
||||||
fi
|
|
||||||
}
|
|
||||||
|
|
||||||
readPrefixes
|
|
||||||
|
|
||||||
# MIGRATE DB
|
|
||||||
CONTAINER_VOL_FOLDER=/var/lib/postgresql/data
|
|
||||||
VOL_NAME_SUFFIX=pgdata
|
|
||||||
migrate
|
|
||||||
|
|
||||||
# MIGRATE REDIS
|
|
||||||
CONTAINER_VOL_FOLDER=/data
|
|
||||||
VOL_NAME_SUFFIX=redisdata
|
|
||||||
migrate
|
|
||||||
|
|
||||||
# MIGRATE MINIO
|
|
||||||
CONTAINER_VOL_FOLDER=/export
|
|
||||||
VOL_NAME_SUFFIX=uploads
|
|
||||||
migrate
|
|
||||||
|
|
||||||
@@ -1,144 +0,0 @@
|
|||||||
#!/bin/bash
|
|
||||||
+set -euo pipefail
|
|
||||||
|
|
||||||
function print_header() {
|
|
||||||
clear
|
|
||||||
|
|
||||||
cat <<"EOF"
|
|
||||||
--------------------------------------------
|
|
||||||
____ _ /////////
|
|
||||||
| _ \| | __ _ _ __ ___ /////////
|
|
||||||
| |_) | |/ _` | '_ \ / _ \ ///// /////
|
|
||||||
| __/| | (_| | | | | __/ ///// /////
|
|
||||||
|_| |_|\__,_|_| |_|\___| ////
|
|
||||||
////
|
|
||||||
--------------------------------------------
|
|
||||||
Project management tool from the future
|
|
||||||
--------------------------------------------
|
|
||||||
EOF
|
|
||||||
}
|
|
||||||
|
|
||||||
function restoreData() {
|
|
||||||
|
|
||||||
echo ""
|
|
||||||
echo "****************************************************"
|
|
||||||
echo "We are about to restore your data from the backup files."
|
|
||||||
echo "****************************************************"
|
|
||||||
echo ""
|
|
||||||
|
|
||||||
# set the backup folder path
|
|
||||||
BACKUP_FOLDER=${1}
|
|
||||||
|
|
||||||
if [ -z "$BACKUP_FOLDER" ]; then
|
|
||||||
BACKUP_FOLDER="$PWD/backup"
|
|
||||||
read -p "Enter the backup folder path [$BACKUP_FOLDER]: " BACKUP_FOLDER
|
|
||||||
if [ -z "$BACKUP_FOLDER" ]; then
|
|
||||||
BACKUP_FOLDER="$PWD/backup"
|
|
||||||
fi
|
|
||||||
fi
|
|
||||||
|
|
||||||
# check if the backup folder exists
|
|
||||||
if [ ! -d "$BACKUP_FOLDER" ]; then
|
|
||||||
echo "Error: Backup folder not found at $BACKUP_FOLDER"
|
|
||||||
exit 1
|
|
||||||
fi
|
|
||||||
|
|
||||||
# check if there are any .tar.gz files in the backup folder
|
|
||||||
if ! ls "$BACKUP_FOLDER"/*.tar.gz 1> /dev/null 2>&1; then
|
|
||||||
echo "Error: Backup folder does not contain .tar.gz files"
|
|
||||||
exit 1
|
|
||||||
fi
|
|
||||||
|
|
||||||
echo ""
|
|
||||||
echo "Using backup folder: $BACKUP_FOLDER"
|
|
||||||
echo ""
|
|
||||||
|
|
||||||
# ask for current install path
|
|
||||||
AIRGAPPED_INSTALL_PATH="$HOME/planeairgapped"
|
|
||||||
read -p "Enter the airgapped instance install path [$AIRGAPPED_INSTALL_PATH]: " AIRGAPPED_INSTALL_PATH
|
|
||||||
if [ -z "$AIRGAPPED_INSTALL_PATH" ]; then
|
|
||||||
AIRGAPPED_INSTALL_PATH="$HOME/planeairgapped"
|
|
||||||
fi
|
|
||||||
|
|
||||||
# check if the airgapped instance install path exists
|
|
||||||
if [ ! -d "$AIRGAPPED_INSTALL_PATH" ]; then
|
|
||||||
echo "Error: Airgapped instance install path not found at $AIRGAPPED_INSTALL_PATH"
|
|
||||||
exit 1
|
|
||||||
fi
|
|
||||||
|
|
||||||
echo ""
|
|
||||||
echo "Using airgapped instance install path: $AIRGAPPED_INSTALL_PATH"
|
|
||||||
echo ""
|
|
||||||
|
|
||||||
# check if the docker-compose.yaml exists
|
|
||||||
if [ ! -f "$AIRGAPPED_INSTALL_PATH/docker-compose.yml" ]; then
|
|
||||||
echo "Error: docker-compose.yml not found at $AIRGAPPED_INSTALL_PATH/docker-compose.yml"
|
|
||||||
exit 1
|
|
||||||
fi
|
|
||||||
|
|
||||||
local dockerServiceStatus
|
|
||||||
if command -v jq &> /dev/null; then
|
|
||||||
dockerServiceStatus=$($COMPOSE_CMD ls --filter name=plane-airgapped --format=json | jq -r .[0].Status)
|
|
||||||
else
|
|
||||||
dockerServiceStatus=$($COMPOSE_CMD ls --filter name=plane-airgapped | grep -o "running" | head -n 1)
|
|
||||||
fi
|
|
||||||
|
|
||||||
if [[ $dockerServiceStatus == "running" ]]; then
|
|
||||||
echo "Plane Airgapped is running. Please STOP the Plane Airgapped before restoring data."
|
|
||||||
exit 1
|
|
||||||
fi
|
|
||||||
|
|
||||||
CURRENT_USER_ID=$(id -u)
|
|
||||||
CURRENT_GROUP_ID=$(id -g)
|
|
||||||
|
|
||||||
# if the data folder not exists, create it
|
|
||||||
if [ ! -d "$AIRGAPPED_INSTALL_PATH/data" ]; then
|
|
||||||
mkdir -p "$AIRGAPPED_INSTALL_PATH/data"
|
|
||||||
chown -R $CURRENT_USER_ID:$CURRENT_GROUP_ID "$AIRGAPPED_INSTALL_PATH/data"
|
|
||||||
fi
|
|
||||||
|
|
||||||
for BACKUP_FILE in "$BACKUP_FOLDER/*.tar.gz"; do
|
|
||||||
if [ -e "$BACKUP_FILE" ]; then
|
|
||||||
|
|
||||||
# get the basefilename without the extension
|
|
||||||
BASE_FILE_NAME=$(basename "$BACKUP_FILE" ".tar.gz")
|
|
||||||
|
|
||||||
# extract the restoreFile to the airgapped instance install path
|
|
||||||
echo "Restoring $BASE_FILE_NAME"
|
|
||||||
rm -rf "$AIRGAPPED_INSTALL_PATH/data/$BASE_FILE_NAME" || true
|
|
||||||
|
|
||||||
tar -xvzf "$BACKUP_FILE" -C "$AIRGAPPED_INSTALL_PATH/data/"
|
|
||||||
if [ $? -ne 0 ]; then
|
|
||||||
echo "Error: Failed to extract $BACKUP_FILE"
|
|
||||||
exit 1
|
|
||||||
fi
|
|
||||||
chown -R $CURRENT_USER_ID:$CURRENT_GROUP_ID "$AIRGAPPED_INSTALL_PATH/data/$BASE_FILE_NAME"
|
|
||||||
if [ $? -ne 0 ]; then
|
|
||||||
echo "Error: Failed to change ownership of $AIRGAPPED_INSTALL_PATH/data/$BASE_FILE_NAME"
|
|
||||||
exit 1
|
|
||||||
fi
|
|
||||||
else
|
|
||||||
echo "No .tar.gz files found in the current directory."
|
|
||||||
echo ""
|
|
||||||
echo "Please provide the path to the backup file."
|
|
||||||
echo ""
|
|
||||||
echo "Usage: $0 /path/to/backup"
|
|
||||||
exit 1
|
|
||||||
fi
|
|
||||||
done
|
|
||||||
|
|
||||||
echo ""
|
|
||||||
echo "Restore completed successfully."
|
|
||||||
echo ""
|
|
||||||
}
|
|
||||||
|
|
||||||
# if docker-compose is installed
|
|
||||||
if command -v docker-compose &> /dev/null
|
|
||||||
then
|
|
||||||
COMPOSE_CMD="docker-compose"
|
|
||||||
else
|
|
||||||
COMPOSE_CMD="docker compose"
|
|
||||||
fi
|
|
||||||
|
|
||||||
print_header
|
|
||||||
restoreData "$@"
|
|
||||||
@@ -1,123 +0,0 @@
|
|||||||
#!/bin/bash
|
|
||||||
|
|
||||||
function print_header() {
|
|
||||||
clear
|
|
||||||
|
|
||||||
cat <<"EOF"
|
|
||||||
--------------------------------------------
|
|
||||||
____ _ /////////
|
|
||||||
| _ \| | __ _ _ __ ___ /////////
|
|
||||||
| |_) | |/ _` | '_ \ / _ \ ///// /////
|
|
||||||
| __/| | (_| | | | | __/ ///// /////
|
|
||||||
|_| |_|\__,_|_| |_|\___| ////
|
|
||||||
////
|
|
||||||
--------------------------------------------
|
|
||||||
Project management tool from the future
|
|
||||||
--------------------------------------------
|
|
||||||
EOF
|
|
||||||
}
|
|
||||||
|
|
||||||
function restoreSingleVolume() {
|
|
||||||
selectedVolume=$1
|
|
||||||
backupFolder=$2
|
|
||||||
restoreFile=$3
|
|
||||||
|
|
||||||
docker volume rm "$selectedVolume" > /dev/null 2>&1
|
|
||||||
|
|
||||||
if [ $? -ne 0 ]; then
|
|
||||||
echo "Error: Failed to remove volume $selectedVolume"
|
|
||||||
echo ""
|
|
||||||
return 1
|
|
||||||
fi
|
|
||||||
|
|
||||||
docker volume create "$selectedVolume" > /dev/null 2>&1
|
|
||||||
if [ $? -ne 0 ]; then
|
|
||||||
echo "Error: Failed to create volume $selectedVolume"
|
|
||||||
echo ""
|
|
||||||
return 1
|
|
||||||
fi
|
|
||||||
|
|
||||||
docker run --rm \
|
|
||||||
-e TAR_NAME="$restoreFile" \
|
|
||||||
-v "$selectedVolume":"/vol" \
|
|
||||||
-v "$backupFolder":/backup \
|
|
||||||
busybox sh -c 'mkdir -p /restore && tar -xzf "/backup/${TAR_NAME}.tar.gz" -C /restore && mv /restore/${TAR_NAME}/* /vol'
|
|
||||||
|
|
||||||
if [ $? -ne 0 ]; then
|
|
||||||
echo "Error: Failed to restore volume ${selectedVolume} from ${restoreFile}.tar.gz"
|
|
||||||
echo ""
|
|
||||||
return 1
|
|
||||||
fi
|
|
||||||
echo ".....Successfully restored volume $selectedVolume from ${restoreFile}.tar.gz"
|
|
||||||
echo ""
|
|
||||||
}
|
|
||||||
|
|
||||||
function restoreData() {
|
|
||||||
print_header
|
|
||||||
local BACKUP_FOLDER=${1:-$PWD}
|
|
||||||
|
|
||||||
local dockerServiceStatus
|
|
||||||
dockerServiceStatus=$($COMPOSE_CMD ls --filter name=plane-app --format=json | jq -r .[0].Status)
|
|
||||||
local dockerServicePrefix
|
|
||||||
dockerServicePrefix="running"
|
|
||||||
|
|
||||||
if [[ $dockerServiceStatus == $dockerServicePrefix* ]]; then
|
|
||||||
echo "Plane App is running. Please STOP the Plane App before restoring data."
|
|
||||||
exit 1
|
|
||||||
fi
|
|
||||||
|
|
||||||
local volume_suffix
|
|
||||||
volume_suffix="_pgdata|_redisdata|_uploads|_rabbitmq_data"
|
|
||||||
local volumes
|
|
||||||
volumes=$(docker volume ls -f "name=plane-app" --format "{{.Name}}" | grep -E "$volume_suffix")
|
|
||||||
# Check if there are any matching volumes
|
|
||||||
if [ -z "$volumes" ]; then
|
|
||||||
echo ".....No volumes found starting with 'plane-app'"
|
|
||||||
exit 1
|
|
||||||
fi
|
|
||||||
|
|
||||||
|
|
||||||
for BACKUP_FILE in $BACKUP_FOLDER/*.tar.gz; do
|
|
||||||
if [ -e "$BACKUP_FILE" ]; then
|
|
||||||
|
|
||||||
local restoreFileName
|
|
||||||
restoreFileName=$(basename "$BACKUP_FILE")
|
|
||||||
restoreFileName="${restoreFileName%.tar.gz}"
|
|
||||||
|
|
||||||
local restoreVolName
|
|
||||||
restoreVolName="plane-app_${restoreFileName}"
|
|
||||||
echo "Found $BACKUP_FILE"
|
|
||||||
|
|
||||||
local docVol
|
|
||||||
docVol=$(docker volume ls -f "name=$restoreVolName" --format "{{.Name}}" | grep -E "$volume_suffix")
|
|
||||||
|
|
||||||
if [ -z "$docVol" ]; then
|
|
||||||
echo "Skipping: No volume found with name $restoreVolName"
|
|
||||||
else
|
|
||||||
echo ".....Restoring $docVol"
|
|
||||||
restoreSingleVolume "$docVol" "$BACKUP_FOLDER" "$restoreFileName"
|
|
||||||
fi
|
|
||||||
else
|
|
||||||
echo "No .tar.gz files found in the current directory."
|
|
||||||
echo ""
|
|
||||||
echo "Please provide the path to the backup file."
|
|
||||||
echo ""
|
|
||||||
echo "Usage: ./restore.sh /path/to/backup"
|
|
||||||
exit 1
|
|
||||||
fi
|
|
||||||
done
|
|
||||||
|
|
||||||
echo ""
|
|
||||||
echo "Restore completed successfully."
|
|
||||||
echo ""
|
|
||||||
}
|
|
||||||
|
|
||||||
# if docker-compose is installed
|
|
||||||
if command -v docker-compose &> /dev/null
|
|
||||||
then
|
|
||||||
COMPOSE_CMD="docker-compose"
|
|
||||||
else
|
|
||||||
COMPOSE_CMD="docker compose"
|
|
||||||
fi
|
|
||||||
|
|
||||||
restoreData "$@"
|
|
||||||
@@ -1,612 +0,0 @@
|
|||||||
#!/bin/bash
|
|
||||||
|
|
||||||
BRANCH=${BRANCH:-master}
|
|
||||||
SERVICE_FOLDER=plane-app
|
|
||||||
SCRIPT_DIR=$PWD
|
|
||||||
PLANE_INSTALL_DIR=$PWD/$SERVICE_FOLDER
|
|
||||||
export APP_RELEASE="stable"
|
|
||||||
export DOCKERHUB_USER=artifacts.plane.so/makeplane
|
|
||||||
|
|
||||||
export GH_REPO=makeplane/plane
|
|
||||||
export RELEASE_DOWNLOAD_URL="https://github.com/$GH_REPO/releases/download"
|
|
||||||
export FALLBACK_DOWNLOAD_URL="https://raw.githubusercontent.com/$GH_REPO/$BRANCH/deploy/selfhost"
|
|
||||||
|
|
||||||
OS_NAME=$(uname)
|
|
||||||
|
|
||||||
# Create necessary directories
|
|
||||||
mkdir -p $PLANE_INSTALL_DIR/archive
|
|
||||||
|
|
||||||
DOCKER_FILE_PATH=$PLANE_INSTALL_DIR/docker-compose.yml
|
|
||||||
DOCKER_ENV_PATH=$PLANE_INSTALL_DIR/plane.env
|
|
||||||
|
|
||||||
function print_header() {
|
|
||||||
clear
|
|
||||||
|
|
||||||
cat <<"EOF"
|
|
||||||
--------------------------------------------
|
|
||||||
____ _ /////////
|
|
||||||
| _ \| | __ _ _ __ ___ /////////
|
|
||||||
| |_) | |/ _` | '_ \ / _ \ ///// /////
|
|
||||||
| __/| | (_| | | | | __/ ///// /////
|
|
||||||
|_| |_|\__,_|_| |_|\___| ////
|
|
||||||
////
|
|
||||||
--------------------------------------------
|
|
||||||
Project management tool from the future
|
|
||||||
--------------------------------------------
|
|
||||||
EOF
|
|
||||||
}
|
|
||||||
|
|
||||||
function checkLatestRelease(){
|
|
||||||
echo "Checking for the latest release..." >&2
|
|
||||||
local latest_release=$(curl -s https://api.github.com/repos/$GH_REPO/releases/latest | grep -o '"tag_name": "[^"]*"' | sed 's/"tag_name": "//;s/"//g')
|
|
||||||
if [ -z "$latest_release" ]; then
|
|
||||||
echo "Failed to check for the latest release. Exiting..." >&2
|
|
||||||
exit 1
|
|
||||||
fi
|
|
||||||
|
|
||||||
echo $latest_release
|
|
||||||
}
|
|
||||||
|
|
||||||
# Function to read stack name from env file
|
|
||||||
function readStackName() {
|
|
||||||
if [ -f "$DOCKER_ENV_PATH" ]; then
|
|
||||||
local saved_stack_name=$(grep "^STACK_NAME=" "$DOCKER_ENV_PATH" | cut -d'=' -f2)
|
|
||||||
if [ -n "$saved_stack_name" ]; then
|
|
||||||
stack_name=$saved_stack_name
|
|
||||||
return 1
|
|
||||||
fi
|
|
||||||
fi
|
|
||||||
return 0
|
|
||||||
}
|
|
||||||
|
|
||||||
# Function to get stack name (either from env or user input)
|
|
||||||
function getStackName() {
|
|
||||||
read -p "Enter stack name [plane]: " input_stack_name
|
|
||||||
if [ -z "$input_stack_name" ]; then
|
|
||||||
input_stack_name="plane"
|
|
||||||
fi
|
|
||||||
stack_name=$input_stack_name
|
|
||||||
updateEnvFile "STACK_NAME" "$stack_name" "$DOCKER_ENV_PATH"
|
|
||||||
echo "Using stack name: $stack_name"
|
|
||||||
}
|
|
||||||
|
|
||||||
function syncEnvFile(){
|
|
||||||
echo "Syncing environment variables..." >&2
|
|
||||||
if [ -f "$PLANE_INSTALL_DIR/plane.env.bak" ]; then
|
|
||||||
# READ keys of plane.env and update the values from plane.env.bak
|
|
||||||
while IFS= read -r line
|
|
||||||
do
|
|
||||||
# ignore if the line is empty or starts with #
|
|
||||||
if [ -z "$line" ] || [[ $line == \#* ]]; then
|
|
||||||
continue
|
|
||||||
fi
|
|
||||||
key=$(echo "$line" | cut -d'=' -f1)
|
|
||||||
value=$(getEnvValue "$key" "$PLANE_INSTALL_DIR/plane.env.bak")
|
|
||||||
if [ -n "$value" ]; then
|
|
||||||
updateEnvFile "$key" "$value" "$DOCKER_ENV_PATH"
|
|
||||||
fi
|
|
||||||
done < "$DOCKER_ENV_PATH"
|
|
||||||
|
|
||||||
value=$(getEnvValue "STACK_NAME" "$PLANE_INSTALL_DIR/plane.env.bak")
|
|
||||||
if [ -n "$value" ]; then
|
|
||||||
updateEnvFile "STACK_NAME" "$value" "$DOCKER_ENV_PATH"
|
|
||||||
fi
|
|
||||||
fi
|
|
||||||
echo "Environment variables synced successfully" >&2
|
|
||||||
rm -f $PLANE_INSTALL_DIR/plane.env.bak
|
|
||||||
}
|
|
||||||
|
|
||||||
function getEnvValue() {
|
|
||||||
local key=$1
|
|
||||||
local file=$2
|
|
||||||
|
|
||||||
if [ -z "$key" ] || [ -z "$file" ]; then
|
|
||||||
echo "Invalid arguments supplied"
|
|
||||||
exit 1
|
|
||||||
fi
|
|
||||||
|
|
||||||
if [ -f "$file" ]; then
|
|
||||||
grep -q "^$key=" "$file"
|
|
||||||
if [ $? -eq 0 ]; then
|
|
||||||
local value
|
|
||||||
value=$(grep "^$key=" "$file" | cut -d'=' -f2)
|
|
||||||
echo "$value"
|
|
||||||
else
|
|
||||||
echo ""
|
|
||||||
fi
|
|
||||||
fi
|
|
||||||
}
|
|
||||||
|
|
||||||
function updateEnvFile() {
|
|
||||||
local key=$1
|
|
||||||
local value=$2
|
|
||||||
local file=$3
|
|
||||||
|
|
||||||
if [ -z "$key" ] || [ -z "$value" ] || [ -z "$file" ]; then
|
|
||||||
echo "Invalid arguments supplied"
|
|
||||||
exit 1
|
|
||||||
fi
|
|
||||||
|
|
||||||
if [ -f "$file" ]; then
|
|
||||||
# check if key exists in the file
|
|
||||||
grep -q "^$key=" "$file"
|
|
||||||
if [ $? -ne 0 ]; then
|
|
||||||
echo "$key=$value" >> "$file"
|
|
||||||
return
|
|
||||||
else
|
|
||||||
if [ "$OS_NAME" == "Darwin" ]; then
|
|
||||||
value=$(echo "$value" | sed 's/|/\\|/g')
|
|
||||||
sed -i '' "s|^$key=.*|$key=$value|g" "$file"
|
|
||||||
else
|
|
||||||
sed -i "s/^$key=.*/$key=$value/g" "$file"
|
|
||||||
fi
|
|
||||||
fi
|
|
||||||
else
|
|
||||||
echo "File not found: $file"
|
|
||||||
exit 1
|
|
||||||
fi
|
|
||||||
}
|
|
||||||
|
|
||||||
function download() {
|
|
||||||
cd $SCRIPT_DIR || exit 1
|
|
||||||
TS=$(date +%s)
|
|
||||||
if [ -f "$PLANE_INSTALL_DIR/docker-compose.yml" ]
|
|
||||||
then
|
|
||||||
mv $PLANE_INSTALL_DIR/docker-compose.yml $PLANE_INSTALL_DIR/archive/$TS.docker-compose.yml
|
|
||||||
fi
|
|
||||||
|
|
||||||
echo $RELEASE_DOWNLOAD_URL
|
|
||||||
echo $FALLBACK_DOWNLOAD_URL
|
|
||||||
echo $APP_RELEASE
|
|
||||||
|
|
||||||
RESPONSE=$(curl -H 'Cache-Control: no-cache, no-store' -s -w "HTTPSTATUS:%{http_code}" "$RELEASE_DOWNLOAD_URL/$APP_RELEASE/docker-compose.yml?$(date +%s)")
|
|
||||||
BODY=$(echo "$RESPONSE" | sed -e 's/HTTPSTATUS\:.*//g')
|
|
||||||
STATUS=$(echo "$RESPONSE" | tr -d '\n' | sed -e 's/.*HTTPSTATUS://')
|
|
||||||
|
|
||||||
if [ "$STATUS" -eq 200 ]; then
|
|
||||||
echo "$BODY" > $PLANE_INSTALL_DIR/docker-compose.yml
|
|
||||||
else
|
|
||||||
# Fallback to download from the raw github url
|
|
||||||
RESPONSE=$(curl -H 'Cache-Control: no-cache, no-store' -s -w "HTTPSTATUS:%{http_code}" "$FALLBACK_DOWNLOAD_URL/docker-compose.yml?$(date +%s)")
|
|
||||||
BODY=$(echo "$RESPONSE" | sed -e 's/HTTPSTATUS\:.*//g')
|
|
||||||
STATUS=$(echo "$RESPONSE" | tr -d '\n' | sed -e 's/.*HTTPSTATUS://')
|
|
||||||
|
|
||||||
if [ "$STATUS" -eq 200 ]; then
|
|
||||||
echo "$BODY" > $PLANE_INSTALL_DIR/docker-compose.yml
|
|
||||||
else
|
|
||||||
echo "Failed to download docker-compose.yml. HTTP Status: $STATUS"
|
|
||||||
echo "URL: $RELEASE_DOWNLOAD_URL/$APP_RELEASE/docker-compose.yml"
|
|
||||||
mv $PLANE_INSTALL_DIR/archive/$TS.docker-compose.yml $PLANE_INSTALL_DIR/docker-compose.yml
|
|
||||||
exit 1
|
|
||||||
fi
|
|
||||||
fi
|
|
||||||
|
|
||||||
RESPONSE=$(curl -H 'Cache-Control: no-cache, no-store' -s -w "HTTPSTATUS:%{http_code}" "$RELEASE_DOWNLOAD_URL/$APP_RELEASE/variables.env?$(date +%s)")
|
|
||||||
BODY=$(echo "$RESPONSE" | sed -e 's/HTTPSTATUS\:.*//g')
|
|
||||||
STATUS=$(echo "$RESPONSE" | tr -d '\n' | sed -e 's/.*HTTPSTATUS://')
|
|
||||||
|
|
||||||
if [ "$STATUS" -eq 200 ]; then
|
|
||||||
echo "$BODY" > $PLANE_INSTALL_DIR/variables-upgrade.env
|
|
||||||
else
|
|
||||||
# Fallback to download from the raw github url
|
|
||||||
RESPONSE=$(curl -H 'Cache-Control: no-cache, no-store' -s -w "HTTPSTATUS:%{http_code}" "$FALLBACK_DOWNLOAD_URL/variables.env?$(date +%s)")
|
|
||||||
BODY=$(echo "$RESPONSE" | sed -e 's/HTTPSTATUS\:.*//g')
|
|
||||||
STATUS=$(echo "$RESPONSE" | tr -d '\n' | sed -e 's/.*HTTPSTATUS://')
|
|
||||||
|
|
||||||
if [ "$STATUS" -eq 200 ]; then
|
|
||||||
echo "$BODY" > $PLANE_INSTALL_DIR/variables-upgrade.env
|
|
||||||
else
|
|
||||||
echo "Failed to download variables.env. HTTP Status: $STATUS"
|
|
||||||
echo "URL: $RELEASE_DOWNLOAD_URL/$APP_RELEASE/variables.env"
|
|
||||||
mv $PLANE_INSTALL_DIR/archive/$TS.docker-compose.yml $PLANE_INSTALL_DIR/docker-compose.yml
|
|
||||||
exit 1
|
|
||||||
fi
|
|
||||||
fi
|
|
||||||
|
|
||||||
if [ -f "$DOCKER_ENV_PATH" ];
|
|
||||||
then
|
|
||||||
cp "$DOCKER_ENV_PATH" "$PLANE_INSTALL_DIR/archive/$TS.env"
|
|
||||||
cp "$DOCKER_ENV_PATH" "$PLANE_INSTALL_DIR/plane.env.bak"
|
|
||||||
fi
|
|
||||||
|
|
||||||
mv $PLANE_INSTALL_DIR/variables-upgrade.env $DOCKER_ENV_PATH
|
|
||||||
|
|
||||||
syncEnvFile
|
|
||||||
|
|
||||||
updateEnvFile "APP_RELEASE" "$APP_RELEASE" "$DOCKER_ENV_PATH"
|
|
||||||
|
|
||||||
}
|
|
||||||
function deployStack() {
|
|
||||||
# Check if docker compose file and env file exist
|
|
||||||
if [ ! -f "$DOCKER_FILE_PATH" ] || [ ! -f "$DOCKER_ENV_PATH" ]; then
|
|
||||||
echo "Configuration files not found"
|
|
||||||
echo "Downloading it now......"
|
|
||||||
APP_RELEASE=$(checkLatestRelease)
|
|
||||||
download
|
|
||||||
fi
|
|
||||||
if [ -z "$stack_name" ]; then
|
|
||||||
getStackName
|
|
||||||
fi
|
|
||||||
echo "Starting ${stack_name} stack..."
|
|
||||||
|
|
||||||
# Pull envs
|
|
||||||
if [ -f "$DOCKER_ENV_PATH" ]; then
|
|
||||||
set -o allexport; source $DOCKER_ENV_PATH; set +o allexport;
|
|
||||||
else
|
|
||||||
echo "Environment file not found: $DOCKER_ENV_PATH"
|
|
||||||
exit 1
|
|
||||||
fi
|
|
||||||
|
|
||||||
# Deploy the stack
|
|
||||||
docker stack deploy -c $DOCKER_FILE_PATH $stack_name
|
|
||||||
|
|
||||||
echo "Waiting for services to be deployed..."
|
|
||||||
sleep 10
|
|
||||||
|
|
||||||
# Check migrator service
|
|
||||||
local migrator_service=$(docker service ls --filter name=${stack_name}_migrator -q)
|
|
||||||
if [ -n "$migrator_service" ]; then
|
|
||||||
echo ">> Waiting for Data Migration to finish"
|
|
||||||
while docker service ls --filter name=${stack_name}_migrator | grep -q "running"; do
|
|
||||||
echo -n "."
|
|
||||||
sleep 1
|
|
||||||
done
|
|
||||||
echo ""
|
|
||||||
|
|
||||||
# Get the most recent container for the migrator service
|
|
||||||
local migrator_container=$(docker ps -a --filter name=${stack_name}_migrator --latest -q)
|
|
||||||
|
|
||||||
if [ -n "$migrator_container" ]; then
|
|
||||||
# Get the exit code of the container
|
|
||||||
local exit_code=$(docker inspect --format='{{.State.ExitCode}}' $migrator_container)
|
|
||||||
|
|
||||||
if [ "$exit_code" != "0" ]; then
|
|
||||||
echo "Server failed to start ❌"
|
|
||||||
echo "Migration failed with exit code: $exit_code"
|
|
||||||
echo "Please check the logs for the 'migrator' service and resolve the issue(s)."
|
|
||||||
echo "Stop the services by running the command: ./swarm.sh stop"
|
|
||||||
exit 1
|
|
||||||
else
|
|
||||||
echo " Data Migration completed successfully ✅"
|
|
||||||
fi
|
|
||||||
else
|
|
||||||
echo "Warning: Could not find migrator container to check exit status"
|
|
||||||
fi
|
|
||||||
fi
|
|
||||||
|
|
||||||
# Check API service
|
|
||||||
local api_service=$(docker service ls --filter name=${stack_name}_api -q)
|
|
||||||
while docker service ls --filter name=${stack_name}_api | grep -q "running"; do
|
|
||||||
local running_container=$(docker ps --filter "name=${stack_name}_api" --filter "status=running" -q)
|
|
||||||
if [ -n "$running_container" ]; then
|
|
||||||
if docker container logs $running_container 2>/dev/null | grep -q "Application Startup Complete"; then
|
|
||||||
break
|
|
||||||
fi
|
|
||||||
fi
|
|
||||||
sleep 2
|
|
||||||
done
|
|
||||||
|
|
||||||
if [ -z "$api_service" ]; then
|
|
||||||
echo "Plane Server failed to start ❌"
|
|
||||||
echo "Please check the logs for the 'api' service and resolve the issue(s)."
|
|
||||||
echo "Stop the services by running the command: ./swarm.sh stop"
|
|
||||||
exit 1
|
|
||||||
fi
|
|
||||||
echo " Plane Server started successfully ✅"
|
|
||||||
echo ""
|
|
||||||
echo " You can access the application at $WEB_URL"
|
|
||||||
echo ""
|
|
||||||
}
|
|
||||||
|
|
||||||
function removeStack() {
|
|
||||||
if [ -z "$stack_name" ]; then
|
|
||||||
echo "Stack name not found"
|
|
||||||
exit 1
|
|
||||||
fi
|
|
||||||
echo "Removing ${stack_name} stack..."
|
|
||||||
docker stack rm "$stack_name"
|
|
||||||
echo "Waiting for services to be removed..."
|
|
||||||
while docker stack ls | grep -q "$stack_name"; do
|
|
||||||
sleep 1
|
|
||||||
done
|
|
||||||
sleep 20
|
|
||||||
echo "Services stopped successfully ✅"
|
|
||||||
}
|
|
||||||
|
|
||||||
function viewStatus() {
|
|
||||||
echo "Checking status of ${stack_name} stack..."
|
|
||||||
if [ -z "$stack_name" ]; then
|
|
||||||
echo "Stack name not found"
|
|
||||||
exit 1
|
|
||||||
fi
|
|
||||||
docker stack ps "$stack_name"
|
|
||||||
}
|
|
||||||
|
|
||||||
function redeployStack() {
|
|
||||||
removeStack
|
|
||||||
echo "ReDeploying ${stack_name} stack..."
|
|
||||||
deployStack
|
|
||||||
}
|
|
||||||
|
|
||||||
function upgrade() {
|
|
||||||
|
|
||||||
echo "Checking status of ${stack_name} stack..."
|
|
||||||
if [ -z "$stack_name" ]; then
|
|
||||||
echo "Stack name not found"
|
|
||||||
exit 1
|
|
||||||
fi
|
|
||||||
|
|
||||||
local latest_release=$(checkLatestRelease)
|
|
||||||
|
|
||||||
echo ""
|
|
||||||
echo "Current release: $APP_RELEASE"
|
|
||||||
|
|
||||||
if [ "$latest_release" == "$APP_RELEASE" ]; then
|
|
||||||
echo ""
|
|
||||||
echo "You are already using the latest release"
|
|
||||||
exit 0
|
|
||||||
fi
|
|
||||||
|
|
||||||
echo "Latest release: $latest_release"
|
|
||||||
echo ""
|
|
||||||
|
|
||||||
# Check for confirmation to upgrade
|
|
||||||
echo "Do you want to upgrade to the latest release ($latest_release)?"
|
|
||||||
read -p "Continue? [y/N]: " confirm
|
|
||||||
|
|
||||||
if [[ ! "$confirm" =~ ^[Yy]$ ]]; then
|
|
||||||
echo "Exiting..."
|
|
||||||
exit 0
|
|
||||||
fi
|
|
||||||
|
|
||||||
export APP_RELEASE=$latest_release
|
|
||||||
|
|
||||||
# check if stack exists
|
|
||||||
echo "Upgrading ${stack_name} stack..."
|
|
||||||
|
|
||||||
# check env file and take backup
|
|
||||||
if [ -f "$DOCKER_ENV_PATH" ]; then
|
|
||||||
cp "$DOCKER_ENV_PATH" "${DOCKER_ENV_PATH}.bak"
|
|
||||||
fi
|
|
||||||
|
|
||||||
download
|
|
||||||
redeployStack
|
|
||||||
}
|
|
||||||
|
|
||||||
function viewSpecificLogs() {
|
|
||||||
local service=$1
|
|
||||||
|
|
||||||
# Input validation
|
|
||||||
if [ -z "$service" ]; then
|
|
||||||
echo "Error: Please specify a service name"
|
|
||||||
return 1
|
|
||||||
fi
|
|
||||||
|
|
||||||
# Main loop for service logs
|
|
||||||
while true; do
|
|
||||||
# Get all running containers for the service
|
|
||||||
local running_containers=$(docker ps --filter "name=${stack_name}_${service}" --filter "status=running" -q)
|
|
||||||
|
|
||||||
# If no running containers found, try service logs
|
|
||||||
if [ -z "$running_containers" ]; then
|
|
||||||
echo "No running containers found for ${stack_name}_${service}, checking service logs..."
|
|
||||||
if docker service inspect ${stack_name}_${service} >/dev/null 2>&1; then
|
|
||||||
echo "Press Ctrl+C or 'q' to exit logs"
|
|
||||||
docker service logs ${stack_name}_${service} -f
|
|
||||||
break
|
|
||||||
else
|
|
||||||
echo "Error: No running containers or services found for ${stack_name}_${service}"
|
|
||||||
return 1
|
|
||||||
fi
|
|
||||||
return
|
|
||||||
fi
|
|
||||||
|
|
||||||
# If multiple containers are running, let user choose
|
|
||||||
if [ $(echo "$running_containers" | grep -v '^$' | wc -l) -gt 1 ]; then
|
|
||||||
clear
|
|
||||||
echo "Multiple containers found for ${stack_name}_${service}:"
|
|
||||||
local i=1
|
|
||||||
# Use regular arrays instead of associative arrays
|
|
||||||
container_ids=()
|
|
||||||
container_names=()
|
|
||||||
|
|
||||||
while read -r container_id; do
|
|
||||||
if [ -n "$container_id" ]; then
|
|
||||||
local container_name=$(docker inspect --format '{{.Name}}' "$container_id" | sed 's/\///')
|
|
||||||
container_ids[$i]=$container_id
|
|
||||||
container_names[$i]=$container_name
|
|
||||||
echo "[$i] ${container_names[$i]} (${container_ids[$i]})"
|
|
||||||
i=$((i+1))
|
|
||||||
fi
|
|
||||||
done <<< "$running_containers"
|
|
||||||
|
|
||||||
echo -e "\nPlease select a container number:"
|
|
||||||
read -r selection
|
|
||||||
|
|
||||||
if [[ "$selection" =~ ^[0-9]+$ ]] && [ -n "${container_ids[$selection]}" ]; then
|
|
||||||
local selected_container=${container_ids[$selection]}
|
|
||||||
clear
|
|
||||||
echo "Showing logs for container: ${container_names[$selection]}"
|
|
||||||
echo "Press Ctrl+C or 'q' to return to container selection"
|
|
||||||
|
|
||||||
# Start watching logs in the background
|
|
||||||
docker container logs -f "$selected_container" &
|
|
||||||
local log_pid=$!
|
|
||||||
|
|
||||||
while true; do
|
|
||||||
read -r -n 1 input
|
|
||||||
if [[ $input == "q" ]]; then
|
|
||||||
kill $log_pid 2>/dev/null
|
|
||||||
wait $log_pid 2>/dev/null
|
|
||||||
break
|
|
||||||
fi
|
|
||||||
done
|
|
||||||
clear
|
|
||||||
else
|
|
||||||
echo "Error: Invalid selection"
|
|
||||||
sleep 2
|
|
||||||
fi
|
|
||||||
else
|
|
||||||
# Single container case
|
|
||||||
local container_name=$(docker inspect --format '{{.Name}}' "$running_containers" | sed 's/\///')
|
|
||||||
echo "Showing logs for container: $container_name"
|
|
||||||
echo "Press Ctrl+C or 'q' to exit logs"
|
|
||||||
docker container logs -f "$running_containers" &
|
|
||||||
local log_pid=$!
|
|
||||||
|
|
||||||
while true; do
|
|
||||||
read -r -n 1 input
|
|
||||||
if [[ $input == "q" ]]; then
|
|
||||||
kill $log_pid 2>/dev/null
|
|
||||||
wait $log_pid 2>/dev/null
|
|
||||||
break
|
|
||||||
fi
|
|
||||||
done
|
|
||||||
break
|
|
||||||
fi
|
|
||||||
done
|
|
||||||
}
|
|
||||||
|
|
||||||
function viewLogs(){
|
|
||||||
|
|
||||||
ARG_SERVICE_NAME=$2
|
|
||||||
if [ -z "$ARG_SERVICE_NAME" ];
|
|
||||||
then
|
|
||||||
echo
|
|
||||||
echo "Select a Service you want to view the logs for:"
|
|
||||||
echo " 1) Web"
|
|
||||||
echo " 2) Space"
|
|
||||||
echo " 3) API"
|
|
||||||
echo " 4) Worker"
|
|
||||||
echo " 5) Beat-Worker"
|
|
||||||
echo " 6) Migrator"
|
|
||||||
echo " 7) Proxy"
|
|
||||||
echo " 8) Redis"
|
|
||||||
echo " 9) Postgres"
|
|
||||||
echo " 10) Minio"
|
|
||||||
echo " 11) RabbitMQ"
|
|
||||||
echo " 0) Back to Main Menu"
|
|
||||||
echo
|
|
||||||
read -p "Service: " DOCKER_SERVICE_NAME
|
|
||||||
|
|
||||||
until (( DOCKER_SERVICE_NAME >= 0 && DOCKER_SERVICE_NAME <= 11 )); do
|
|
||||||
echo "Invalid selection. Please enter a number between 0 and 11."
|
|
||||||
read -p "Service: " DOCKER_SERVICE_NAME
|
|
||||||
done
|
|
||||||
|
|
||||||
if [ -z "$DOCKER_SERVICE_NAME" ];
|
|
||||||
then
|
|
||||||
echo "INVALID SERVICE NAME SUPPLIED"
|
|
||||||
else
|
|
||||||
case $DOCKER_SERVICE_NAME in
|
|
||||||
1) viewSpecificLogs "web";;
|
|
||||||
2) viewSpecificLogs "space";;
|
|
||||||
3) viewSpecificLogs "api";;
|
|
||||||
4) viewSpecificLogs "worker";;
|
|
||||||
5) viewSpecificLogs "beat-worker";;
|
|
||||||
6) viewSpecificLogs "migrator";;
|
|
||||||
7) viewSpecificLogs "proxy";;
|
|
||||||
8) viewSpecificLogs "plane-redis";;
|
|
||||||
9) viewSpecificLogs "plane-db";;
|
|
||||||
10) viewSpecificLogs "plane-minio";;
|
|
||||||
11) viewSpecificLogs "plane-mq";;
|
|
||||||
0) askForAction;;
|
|
||||||
*) echo "INVALID SERVICE NAME SUPPLIED";;
|
|
||||||
esac
|
|
||||||
fi
|
|
||||||
elif [ -n "$ARG_SERVICE_NAME" ];
|
|
||||||
then
|
|
||||||
ARG_SERVICE_NAME=$(echo "$ARG_SERVICE_NAME" | tr '[:upper:]' '[:lower:]')
|
|
||||||
case $ARG_SERVICE_NAME in
|
|
||||||
web) viewSpecificLogs "web";;
|
|
||||||
space) viewSpecificLogs "space";;
|
|
||||||
api) viewSpecificLogs "api";;
|
|
||||||
worker) viewSpecificLogs "worker";;
|
|
||||||
beat-worker) viewSpecificLogs "beat-worker";;
|
|
||||||
migrator) viewSpecificLogs "migrator";;
|
|
||||||
proxy) viewSpecificLogs "proxy";;
|
|
||||||
redis) viewSpecificLogs "plane-redis";;
|
|
||||||
postgres) viewSpecificLogs "plane-db";;
|
|
||||||
minio) viewSpecificLogs "plane-minio";;
|
|
||||||
rabbitmq) viewSpecificLogs "plane-mq";;
|
|
||||||
*) echo "INVALID SERVICE NAME SUPPLIED";;
|
|
||||||
esac
|
|
||||||
else
|
|
||||||
echo "INVALID SERVICE NAME SUPPLIED"
|
|
||||||
fi
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
function askForAction() {
|
|
||||||
# Rest of askForAction remains the same but use $stack_name instead of $STACK_NAME
|
|
||||||
local DEFAULT_ACTION=$1
|
|
||||||
|
|
||||||
if [ -z "$DEFAULT_ACTION" ]; then
|
|
||||||
echo
|
|
||||||
echo "Select an Action you want to perform:"
|
|
||||||
echo " 1) Deploy Stack"
|
|
||||||
echo " 2) Remove Stack"
|
|
||||||
echo " 3) View Stack Status"
|
|
||||||
echo " 4) Redeploy Stack"
|
|
||||||
echo " 5) Upgrade"
|
|
||||||
echo " 6) View Logs"
|
|
||||||
echo " 7) Exit"
|
|
||||||
echo
|
|
||||||
read -p "Action [3]: " ACTION
|
|
||||||
until [[ -z "$ACTION" || "$ACTION" =~ ^[1-6]$ ]]; do
|
|
||||||
echo "$ACTION: invalid selection."
|
|
||||||
read -p "Action [3]: " ACTION
|
|
||||||
done
|
|
||||||
|
|
||||||
if [ -z "$ACTION" ]; then
|
|
||||||
ACTION=3
|
|
||||||
fi
|
|
||||||
echo
|
|
||||||
fi
|
|
||||||
|
|
||||||
if [ "$ACTION" == "1" ] || [ "$DEFAULT_ACTION" == "deploy" ]; then
|
|
||||||
deployStack
|
|
||||||
elif [ "$ACTION" == "2" ] || [ "$DEFAULT_ACTION" == "remove" ]; then
|
|
||||||
removeStack
|
|
||||||
elif [ "$ACTION" == "3" ] || [ "$DEFAULT_ACTION" == "status" ]; then
|
|
||||||
viewStatus
|
|
||||||
elif [ "$ACTION" == "4" ] || [ "$DEFAULT_ACTION" == "redeploy" ]; then
|
|
||||||
redeployStack
|
|
||||||
elif [ "$ACTION" == "5" ] || [ "$DEFAULT_ACTION" == "upgrade" ]; then
|
|
||||||
upgrade
|
|
||||||
elif [ "$ACTION" == "6" ] || [ "$DEFAULT_ACTION" == "logs" ]; then
|
|
||||||
viewLogs "$@"
|
|
||||||
elif [ "$ACTION" == "7" ] || [ "$DEFAULT_ACTION" == "exit" ]; then
|
|
||||||
exit 0
|
|
||||||
else
|
|
||||||
echo "INVALID ACTION SUPPLIED"
|
|
||||||
fi
|
|
||||||
}
|
|
||||||
|
|
||||||
# Initialize stack name at script start
|
|
||||||
|
|
||||||
if [ -z "$stack_name" ]; then
|
|
||||||
readStackName
|
|
||||||
fi
|
|
||||||
|
|
||||||
# Sync environment variables
|
|
||||||
if [ -f "$DOCKER_ENV_PATH" ]; then
|
|
||||||
DOCKERHUB_USER=$(getEnvValue "DOCKERHUB_USER" "$DOCKER_ENV_PATH")
|
|
||||||
APP_RELEASE=$(getEnvValue "APP_RELEASE" "$DOCKER_ENV_PATH")
|
|
||||||
|
|
||||||
if [ -z "$DOCKERHUB_USER" ]; then
|
|
||||||
DOCKERHUB_USER=artifacts.plane.so/makeplane
|
|
||||||
updateEnvFile "DOCKERHUB_USER" "$DOCKERHUB_USER" "$DOCKER_ENV_PATH"
|
|
||||||
fi
|
|
||||||
|
|
||||||
if [ -z "$APP_RELEASE" ]; then
|
|
||||||
APP_RELEASE=stable
|
|
||||||
updateEnvFile "APP_RELEASE" "$APP_RELEASE" "$DOCKER_ENV_PATH"
|
|
||||||
fi
|
|
||||||
fi
|
|
||||||
|
|
||||||
|
|
||||||
# Main execution
|
|
||||||
print_header
|
|
||||||
askForAction "$@"
|
|
||||||
@@ -2,14 +2,14 @@
|
|||||||
|
|
||||||
BRANCH=${BRANCH:-master}
|
BRANCH=${BRANCH:-master}
|
||||||
SCRIPT_DIR=$PWD
|
SCRIPT_DIR=$PWD
|
||||||
SERVICE_FOLDER=plane-app
|
SERVICE_FOLDER=plane-code
|
||||||
PLANE_INSTALL_DIR=$PWD/$SERVICE_FOLDER
|
PLANE_INSTALL_DIR=$PWD/$SERVICE_FOLDER
|
||||||
export APP_RELEASE=stable
|
export APP_RELEASE=stable
|
||||||
export DOCKERHUB_USER=artifacts.plane.so/makeplane
|
export DOCKERHUB_USER=artifacts.plane.so/makeplane
|
||||||
export PULL_POLICY=${PULL_POLICY:-if_not_present}
|
export PULL_POLICY=${PULL_POLICY:-if_not_present}
|
||||||
export GH_REPO=makeplane/plane
|
export GH_REPO=makeplane/plane
|
||||||
export RELEASE_DOWNLOAD_URL="https://github.com/$GH_REPO/releases/download"
|
export RELEASE_DOWNLOAD_URL="https://github.com/$GH_REPO/releases/download"
|
||||||
export FALLBACK_DOWNLOAD_URL="https://raw.githubusercontent.com/$GH_REPO/$BRANCH/deploy/selfhost"
|
export FALLBACK_DOWNLOAD_URL="https://raw.githubusercontent.com/$GH_REPO/$BRANCH/deployments/cli/community"
|
||||||
|
|
||||||
CPU_ARCH=$(uname -m)
|
CPU_ARCH=$(uname -m)
|
||||||
OS_NAME=$(uname)
|
OS_NAME=$(uname)
|
||||||
@@ -57,7 +57,7 @@ function spinner() {
|
|||||||
|
|
||||||
function checkLatestRelease(){
|
function checkLatestRelease(){
|
||||||
echo "Checking for the latest release..." >&2
|
echo "Checking for the latest release..." >&2
|
||||||
local latest_release=$(curl -s https://api.github.com/repos/$GH_REPO/releases/latest | grep -o '"tag_name": "[^"]*"' | sed 's/"tag_name": "//;s/"//g')
|
local latest_release=$(curl -fsSL https://api.github.com/repos/$GH_REPO/releases/latest | grep -o '"tag_name": "[^"]*"' | sed 's/"tag_name": "//;s/"//g')
|
||||||
if [ -z "$latest_release" ]; then
|
if [ -z "$latest_release" ]; then
|
||||||
echo "Failed to check for the latest release. Exiting..." >&2
|
echo "Failed to check for the latest release. Exiting..." >&2
|
||||||
exit 1
|
exit 1
|
||||||
@@ -196,7 +196,7 @@ function buildYourOwnImage(){
|
|||||||
REPO=https://github.com/$GH_REPO.git
|
REPO=https://github.com/$GH_REPO.git
|
||||||
git clone "$REPO" "$PLANE_TEMP_CODE_DIR" --branch "$BRANCH" --single-branch --depth 1
|
git clone "$REPO" "$PLANE_TEMP_CODE_DIR" --branch "$BRANCH" --single-branch --depth 1
|
||||||
|
|
||||||
cp "$PLANE_TEMP_CODE_DIR/deploy/selfhost/build.yml" "$PLANE_TEMP_CODE_DIR/build.yml"
|
cp "$PLANE_TEMP_CODE_DIR/deployments/cli/community/build.yml" "$PLANE_TEMP_CODE_DIR/build.yml"
|
||||||
|
|
||||||
cd "$PLANE_TEMP_CODE_DIR" || exit
|
cd "$PLANE_TEMP_CODE_DIR" || exit
|
||||||
|
|
||||||
@@ -247,7 +247,7 @@ function download() {
|
|||||||
mv $PLANE_INSTALL_DIR/docker-compose.yaml $PLANE_INSTALL_DIR/archive/$TS.docker-compose.yaml
|
mv $PLANE_INSTALL_DIR/docker-compose.yaml $PLANE_INSTALL_DIR/archive/$TS.docker-compose.yaml
|
||||||
fi
|
fi
|
||||||
|
|
||||||
RESPONSE=$(curl -H 'Cache-Control: no-cache, no-store' -s -w "HTTPSTATUS:%{http_code}" "$RELEASE_DOWNLOAD_URL/$APP_RELEASE/docker-compose.yml?$(date +%s)")
|
RESPONSE=$(curl -fsSL -H 'Cache-Control: no-cache, no-store' -s -w "HTTPSTATUS:%{http_code}" "$RELEASE_DOWNLOAD_URL/$APP_RELEASE/docker-compose.yml?$(date +%s)")
|
||||||
BODY=$(echo "$RESPONSE" | sed -e 's/HTTPSTATUS\:.*//g')
|
BODY=$(echo "$RESPONSE" | sed -e 's/HTTPSTATUS\:.*//g')
|
||||||
STATUS=$(echo "$RESPONSE" | tr -d '\n' | sed -e 's/.*HTTPSTATUS://')
|
STATUS=$(echo "$RESPONSE" | tr -d '\n' | sed -e 's/.*HTTPSTATUS://')
|
||||||
|
|
||||||
@@ -255,7 +255,7 @@ function download() {
|
|||||||
echo "$BODY" > $PLANE_INSTALL_DIR/docker-compose.yaml
|
echo "$BODY" > $PLANE_INSTALL_DIR/docker-compose.yaml
|
||||||
else
|
else
|
||||||
# Fallback to download from the raw github url
|
# Fallback to download from the raw github url
|
||||||
RESPONSE=$(curl -H 'Cache-Control: no-cache, no-store' -s -w "HTTPSTATUS:%{http_code}" "$FALLBACK_DOWNLOAD_URL/docker-compose.yml?$(date +%s)")
|
RESPONSE=$(curl -fsSL -H 'Cache-Control: no-cache, no-store' -s -w "HTTPSTATUS:%{http_code}" "$FALLBACK_DOWNLOAD_URL/docker-compose.yml?$(date +%s)")
|
||||||
BODY=$(echo "$RESPONSE" | sed -e 's/HTTPSTATUS\:.*//g')
|
BODY=$(echo "$RESPONSE" | sed -e 's/HTTPSTATUS\:.*//g')
|
||||||
STATUS=$(echo "$RESPONSE" | tr -d '\n' | sed -e 's/.*HTTPSTATUS://')
|
STATUS=$(echo "$RESPONSE" | tr -d '\n' | sed -e 's/.*HTTPSTATUS://')
|
||||||
|
|
||||||
@@ -269,7 +269,7 @@ function download() {
|
|||||||
fi
|
fi
|
||||||
fi
|
fi
|
||||||
|
|
||||||
RESPONSE=$(curl -H 'Cache-Control: no-cache, no-store' -s -w "HTTPSTATUS:%{http_code}" "$RELEASE_DOWNLOAD_URL/$APP_RELEASE/variables.env?$(date +%s)")
|
RESPONSE=$(curl -fsSL -H 'Cache-Control: no-cache, no-store' -s -w "HTTPSTATUS:%{http_code}" "$RELEASE_DOWNLOAD_URL/$APP_RELEASE/variables.env?$(date +%s)")
|
||||||
BODY=$(echo "$RESPONSE" | sed -e 's/HTTPSTATUS\:.*//g')
|
BODY=$(echo "$RESPONSE" | sed -e 's/HTTPSTATUS\:.*//g')
|
||||||
STATUS=$(echo "$RESPONSE" | tr -d '\n' | sed -e 's/.*HTTPSTATUS://')
|
STATUS=$(echo "$RESPONSE" | tr -d '\n' | sed -e 's/.*HTTPSTATUS://')
|
||||||
|
|
||||||
@@ -277,7 +277,7 @@ function download() {
|
|||||||
echo "$BODY" > $PLANE_INSTALL_DIR/variables-upgrade.env
|
echo "$BODY" > $PLANE_INSTALL_DIR/variables-upgrade.env
|
||||||
else
|
else
|
||||||
# Fallback to download from the raw github url
|
# Fallback to download from the raw github url
|
||||||
RESPONSE=$(curl -H 'Cache-Control: no-cache, no-store' -s -w "HTTPSTATUS:%{http_code}" "$FALLBACK_DOWNLOAD_URL/variables.env?$(date +%s)")
|
RESPONSE=$(curl -fsSL -H 'Cache-Control: no-cache, no-store' -s -w "HTTPSTATUS:%{http_code}" "$FALLBACK_DOWNLOAD_URL/variables.env?$(date +%s)")
|
||||||
BODY=$(echo "$RESPONSE" | sed -e 's/HTTPSTATUS\:.*//g')
|
BODY=$(echo "$RESPONSE" | sed -e 's/HTTPSTATUS\:.*//g')
|
||||||
STATUS=$(echo "$RESPONSE" | tr -d '\n' | sed -e 's/.*HTTPSTATUS://')
|
STATUS=$(echo "$RESPONSE" | tr -d '\n' | sed -e 's/.*HTTPSTATUS://')
|
||||||
|
|
||||||
+23
-8
@@ -1,13 +1,28 @@
|
|||||||
import utils from "../utils.js";
|
import utils from "../utils.js";
|
||||||
|
|
||||||
await utils.cloneOrPullRepo({
|
await utils.removeDir("./code");
|
||||||
repo: "https://github.com/makeplane/plane.git",
|
await utils.renameDir("./plane-code", "./code");
|
||||||
path: "./repo",
|
await utils.removeDir("./code/archive");
|
||||||
branch: "preview",
|
await utils.renameFile("./code/plane.env", "./code/.env.example");
|
||||||
});
|
await utils.renameFile("./code/docker-compose.yaml", "./code/docker-compose.yml");
|
||||||
|
|
||||||
await utils.copyDir("./repo/deploy/selfhost", "./code");
|
|
||||||
await utils.renameFile("./code/variables.env", "./code/.env.example");
|
|
||||||
|
|
||||||
await utils.removeContainerNames("./code/docker-compose.yml");
|
await utils.removeContainerNames("./code/docker-compose.yml");
|
||||||
await utils.removePorts("./code/docker-compose.yml");
|
await utils.removePorts("./code/docker-compose.yml");
|
||||||
|
|
||||||
|
await utils.searchReplace(
|
||||||
|
"./code/.env.example",
|
||||||
|
"APP_DOMAIN=localhost",
|
||||||
|
"APP_DOMAIN=$(PRIMARY_DOMAIN)"
|
||||||
|
);
|
||||||
|
|
||||||
|
await utils.searchReplace(
|
||||||
|
"./code/.env.example",
|
||||||
|
"WEB_URL=http://${APP_DOMAIN}",
|
||||||
|
"WEB_URL=https://$(PRIMARY_DOMAIN)"
|
||||||
|
);
|
||||||
|
|
||||||
|
await utils.searchReplace(
|
||||||
|
"./code/.env.example",
|
||||||
|
"CORS_ALLOWED_ORIGINS=http://${APP_DOMAIN}",
|
||||||
|
"CORS_ALLOWED_ORIGINS=https://$(PRIMARY_DOMAIN)"
|
||||||
|
);
|
||||||
|
|||||||
@@ -1,14 +0,0 @@
|
|||||||
#!/bin/bash
|
|
||||||
|
|
||||||
if [ ! -d "./repo" ]; then
|
|
||||||
git clone --depth 1 --branch preview --single-branch https://github.com/makeplane/plane.git repo
|
|
||||||
else
|
|
||||||
cd repo
|
|
||||||
git pull
|
|
||||||
cd ..
|
|
||||||
fi
|
|
||||||
|
|
||||||
cp -r ./repo/deploy/selfhost/. ./code
|
|
||||||
mv ./code/variables.env ./code/.env.example
|
|
||||||
|
|
||||||
|
|
||||||
@@ -10,7 +10,8 @@ SERVICE_ROLE_KEY=eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyAgCiAgICAicm9sZSI6ICJzZX
|
|||||||
DASHBOARD_USERNAME=supabase
|
DASHBOARD_USERNAME=supabase
|
||||||
DASHBOARD_PASSWORD=this_password_is_insecure_and_should_be_updated
|
DASHBOARD_PASSWORD=this_password_is_insecure_and_should_be_updated
|
||||||
SECRET_KEY_BASE=UpNVntn3cDxHJpq99YMc1T1AQgQpc8kfYTuRgBiYa15BLrx8etQoXz3gZv1/u2oq
|
SECRET_KEY_BASE=UpNVntn3cDxHJpq99YMc1T1AQgQpc8kfYTuRgBiYa15BLrx8etQoXz3gZv1/u2oq
|
||||||
VAULT_ENC_KEY=your-encryption-key-32-chars-min
|
VAULT_ENC_KEY=your-32-character-encryption-key
|
||||||
|
PG_META_CRYPTO_KEY=your-encryption-key-32-chars-min
|
||||||
|
|
||||||
|
|
||||||
############
|
############
|
||||||
@@ -59,7 +60,7 @@ PGRST_DB_SCHEMAS=public,storage,graphql_public
|
|||||||
############
|
############
|
||||||
|
|
||||||
## General
|
## General
|
||||||
SITE_URL=http://localhost:3000
|
SITE_URL=https://$(PRIMARY_DOMAIN)
|
||||||
ADDITIONAL_REDIRECT_URLS=
|
ADDITIONAL_REDIRECT_URLS=
|
||||||
JWT_EXPIRY=3600
|
JWT_EXPIRY=3600
|
||||||
DISABLE_SIGNUP=false
|
DISABLE_SIGNUP=false
|
||||||
@@ -94,7 +95,6 @@ ENABLE_PHONE_AUTOCONFIRM=true
|
|||||||
STUDIO_DEFAULT_ORGANIZATION=Default Organization
|
STUDIO_DEFAULT_ORGANIZATION=Default Organization
|
||||||
STUDIO_DEFAULT_PROJECT=Default Project
|
STUDIO_DEFAULT_PROJECT=Default Project
|
||||||
|
|
||||||
STUDIO_PORT=3000
|
|
||||||
# replace if you intend to use Studio outside of localhost
|
# replace if you intend to use Studio outside of localhost
|
||||||
SUPABASE_PUBLIC_URL=http://localhost:8000
|
SUPABASE_PUBLIC_URL=http://localhost:8000
|
||||||
|
|
||||||
|
|||||||
@@ -0,0 +1,272 @@
|
|||||||
|
# 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
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## [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 potential 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 potential 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
|
target: dev
|
||||||
ports:
|
ports:
|
||||||
- 8082:8082
|
- 8082:8082
|
||||||
|
develop:
|
||||||
|
watch:
|
||||||
|
- action: sync
|
||||||
|
path: ../apps/studio
|
||||||
|
target: /app/apps/studio
|
||||||
|
ignore:
|
||||||
|
- node_modules/
|
||||||
|
- action: rebuild
|
||||||
|
path: package.json
|
||||||
|
|
||||||
mail:
|
mail:
|
||||||
container_name: supabase-mail
|
container_name: supabase-mail
|
||||||
image: inbucket/inbucket:3.0.3
|
image: inbucket/inbucket:3.0.3
|
||||||
|
|||||||
@@ -10,7 +10,7 @@ name: supabase
|
|||||||
services:
|
services:
|
||||||
|
|
||||||
studio:
|
studio:
|
||||||
image: supabase/studio:2025.06.30-sha-6f5982d
|
image: supabase/studio:2025.12.17-sha-43f4f7f
|
||||||
restart: unless-stopped
|
restart: unless-stopped
|
||||||
healthcheck:
|
healthcheck:
|
||||||
test:
|
test:
|
||||||
@@ -28,8 +28,15 @@ services:
|
|||||||
analytics:
|
analytics:
|
||||||
condition: service_healthy
|
condition: service_healthy
|
||||||
environment:
|
environment:
|
||||||
|
# Binds nestjs listener to both IPv4 and IPv6 network interfaces
|
||||||
|
HOSTNAME: "::"
|
||||||
|
|
||||||
STUDIO_PG_META_URL: http://meta:8080
|
STUDIO_PG_META_URL: http://meta:8080
|
||||||
|
POSTGRES_PORT: ${POSTGRES_PORT}
|
||||||
|
POSTGRES_HOST: ${POSTGRES_HOST}
|
||||||
|
POSTGRES_DB: ${POSTGRES_DB}
|
||||||
POSTGRES_PASSWORD: ${POSTGRES_PASSWORD}
|
POSTGRES_PASSWORD: ${POSTGRES_PASSWORD}
|
||||||
|
PG_META_CRYPTO_KEY: ${PG_META_CRYPTO_KEY}
|
||||||
|
|
||||||
DEFAULT_ORGANIZATION_NAME: ${STUDIO_DEFAULT_ORGANIZATION}
|
DEFAULT_ORGANIZATION_NAME: ${STUDIO_DEFAULT_ORGANIZATION}
|
||||||
DEFAULT_PROJECT_NAME: ${STUDIO_DEFAULT_PROJECT}
|
DEFAULT_PROJECT_NAME: ${STUDIO_DEFAULT_PROJECT}
|
||||||
@@ -41,7 +48,11 @@ services:
|
|||||||
SUPABASE_SERVICE_KEY: ${SERVICE_ROLE_KEY}
|
SUPABASE_SERVICE_KEY: ${SERVICE_ROLE_KEY}
|
||||||
AUTH_JWT_SECRET: ${JWT_SECRET}
|
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_PRIVATE_ACCESS_TOKEN: ${LOGFLARE_PRIVATE_ACCESS_TOKEN}
|
||||||
|
|
||||||
LOGFLARE_URL: http://analytics:4000
|
LOGFLARE_URL: http://analytics:4000
|
||||||
NEXT_PUBLIC_ENABLE_LOGS: true
|
NEXT_PUBLIC_ENABLE_LOGS: true
|
||||||
# Comment to use Big Query backend for analytics
|
# Comment to use Big Query backend for analytics
|
||||||
@@ -63,7 +74,7 @@ services:
|
|||||||
KONG_DECLARATIVE_CONFIG: /home/kong/kong.yml
|
KONG_DECLARATIVE_CONFIG: /home/kong/kong.yml
|
||||||
# https://github.com/supabase/cli/issues/14
|
# https://github.com/supabase/cli/issues/14
|
||||||
KONG_DNS_ORDER: LAST,A,CNAME
|
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_BUFFER_SIZE: 160k
|
||||||
KONG_NGINX_PROXY_PROXY_BUFFERS: 64 160k
|
KONG_NGINX_PROXY_PROXY_BUFFERS: 64 160k
|
||||||
SUPABASE_ANON_KEY: ${ANON_KEY}
|
SUPABASE_ANON_KEY: ${ANON_KEY}
|
||||||
@@ -75,7 +86,7 @@ services:
|
|||||||
/docker-entrypoint.sh kong docker-start'
|
/docker-entrypoint.sh kong docker-start'
|
||||||
|
|
||||||
auth:
|
auth:
|
||||||
image: supabase/gotrue:v2.176.1
|
image: supabase/gotrue:v2.184.0
|
||||||
restart: unless-stopped
|
restart: unless-stopped
|
||||||
healthcheck:
|
healthcheck:
|
||||||
test:
|
test:
|
||||||
@@ -157,7 +168,7 @@ services:
|
|||||||
# GOTRUE_HOOK_SEND_EMAIL_SECRETS: "v1,whsec_VGhpcyBpcyBhbiBleGFtcGxlIG9mIGEgc2hvcnRlciBCYXNlNjQgc3RyaW5n"
|
# GOTRUE_HOOK_SEND_EMAIL_SECRETS: "v1,whsec_VGhpcyBpcyBhbiBleGFtcGxlIG9mIGEgc2hvcnRlciBCYXNlNjQgc3RyaW5n"
|
||||||
|
|
||||||
rest:
|
rest:
|
||||||
image: postgrest/postgrest:v12.2.12
|
image: postgrest/postgrest:v14.1
|
||||||
restart: unless-stopped
|
restart: unless-stopped
|
||||||
depends_on:
|
depends_on:
|
||||||
db:
|
db:
|
||||||
@@ -177,7 +188,7 @@ services:
|
|||||||
|
|
||||||
realtime:
|
realtime:
|
||||||
# This container name looks inconsistent but is correct because realtime constructs tenant id by parsing the subdomain
|
# 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.68.0
|
||||||
restart: unless-stopped
|
restart: unless-stopped
|
||||||
depends_on:
|
depends_on:
|
||||||
db:
|
db:
|
||||||
@@ -188,15 +199,9 @@ services:
|
|||||||
healthcheck:
|
healthcheck:
|
||||||
test:
|
test:
|
||||||
[
|
[
|
||||||
"CMD",
|
"CMD-SHELL",
|
||||||
"curl",
|
"curl -sSfL --head -o /dev/null -H \"Authorization: Bearer
|
||||||
"-sSfL",
|
${ANON_KEY}\" http://localhost:4000/api/tenants/realtime-dev/health"
|
||||||
"--head",
|
|
||||||
"-o",
|
|
||||||
"/dev/null",
|
|
||||||
"-H",
|
|
||||||
"Authorization: Bearer ${ANON_KEY}",
|
|
||||||
"http://localhost:4000/api/tenants/realtime-dev/health"
|
|
||||||
]
|
]
|
||||||
timeout: 5s
|
timeout: 5s
|
||||||
interval: 5s
|
interval: 5s
|
||||||
@@ -216,12 +221,12 @@ services:
|
|||||||
DNS_NODES: "''"
|
DNS_NODES: "''"
|
||||||
RLIMIT_NOFILE: "10000"
|
RLIMIT_NOFILE: "10000"
|
||||||
APP_NAME: realtime
|
APP_NAME: realtime
|
||||||
SEED_SELF_HOST: true
|
SEED_SELF_HOST: "true"
|
||||||
RUN_JANITOR: true
|
RUN_JANITOR: "true"
|
||||||
|
|
||||||
# To use S3 backed storage: docker compose -f docker-compose.yml -f docker-compose.s3.yml up
|
# To use S3 backed storage: docker compose -f docker-compose.yml -f docker-compose.s3.yml up
|
||||||
storage:
|
storage:
|
||||||
image: supabase/storage-api:v1.24.7
|
image: supabase/storage-api:v1.33.0
|
||||||
restart: unless-stopped
|
restart: unless-stopped
|
||||||
volumes:
|
volumes:
|
||||||
- ./volumes/storage:/var/lib/storage:z
|
- ./volumes/storage:/var/lib/storage:z
|
||||||
@@ -252,6 +257,7 @@ services:
|
|||||||
POSTGREST_URL: http://rest:3000
|
POSTGREST_URL: http://rest:3000
|
||||||
PGRST_JWT_SECRET: ${JWT_SECRET}
|
PGRST_JWT_SECRET: ${JWT_SECRET}
|
||||||
DATABASE_URL: postgres://supabase_storage_admin:${POSTGRES_PASSWORD}@${POSTGRES_HOST}:${POSTGRES_PORT}/${POSTGRES_DB}
|
DATABASE_URL: postgres://supabase_storage_admin:${POSTGRES_PASSWORD}@${POSTGRES_HOST}:${POSTGRES_PORT}/${POSTGRES_DB}
|
||||||
|
REQUEST_ALLOW_X_FORWARDED_PATH: "true"
|
||||||
FILE_SIZE_LIMIT: 52428800
|
FILE_SIZE_LIMIT: 52428800
|
||||||
STORAGE_BACKEND: file
|
STORAGE_BACKEND: file
|
||||||
FILE_STORAGE_BACKEND_PATH: /var/lib/storage
|
FILE_STORAGE_BACKEND_PATH: /var/lib/storage
|
||||||
@@ -279,7 +285,7 @@ services:
|
|||||||
IMGPROXY_ENABLE_WEBP_DETECTION: ${IMGPROXY_ENABLE_WEBP_DETECTION}
|
IMGPROXY_ENABLE_WEBP_DETECTION: ${IMGPROXY_ENABLE_WEBP_DETECTION}
|
||||||
|
|
||||||
meta:
|
meta:
|
||||||
image: supabase/postgres-meta:v0.89.3
|
image: supabase/postgres-meta:v0.95.1
|
||||||
restart: unless-stopped
|
restart: unless-stopped
|
||||||
depends_on:
|
depends_on:
|
||||||
db:
|
db:
|
||||||
@@ -294,9 +300,10 @@ services:
|
|||||||
PG_META_DB_NAME: ${POSTGRES_DB}
|
PG_META_DB_NAME: ${POSTGRES_DB}
|
||||||
PG_META_DB_USER: supabase_admin
|
PG_META_DB_USER: supabase_admin
|
||||||
PG_META_DB_PASSWORD: ${POSTGRES_PASSWORD}
|
PG_META_DB_PASSWORD: ${POSTGRES_PASSWORD}
|
||||||
|
CRYPTO_KEY: ${PG_META_CRYPTO_KEY}
|
||||||
|
|
||||||
functions:
|
functions:
|
||||||
image: supabase/edge-runtime:v1.67.4
|
image: supabase/edge-runtime:v1.69.28
|
||||||
restart: unless-stopped
|
restart: unless-stopped
|
||||||
volumes:
|
volumes:
|
||||||
- ./volumes/functions:/home/deno/functions:Z
|
- ./volumes/functions:/home/deno/functions:Z
|
||||||
@@ -314,7 +321,7 @@ services:
|
|||||||
command: [ "start", "--main-service", "/home/deno/functions/main" ]
|
command: [ "start", "--main-service", "/home/deno/functions/main" ]
|
||||||
|
|
||||||
analytics:
|
analytics:
|
||||||
image: supabase/logflare:1.14.2
|
image: supabase/logflare:1.27.0
|
||||||
restart: unless-stopped
|
restart: unless-stopped
|
||||||
# Uncomment to use Big Query backend for analytics
|
# Uncomment to use Big Query backend for analytics
|
||||||
# volumes:
|
# volumes:
|
||||||
@@ -343,7 +350,6 @@ services:
|
|||||||
LOGFLARE_PRIVATE_ACCESS_TOKEN: ${LOGFLARE_PRIVATE_ACCESS_TOKEN}
|
LOGFLARE_PRIVATE_ACCESS_TOKEN: ${LOGFLARE_PRIVATE_ACCESS_TOKEN}
|
||||||
LOGFLARE_SINGLE_TENANT: true
|
LOGFLARE_SINGLE_TENANT: true
|
||||||
LOGFLARE_SUPABASE_MODE: true
|
LOGFLARE_SUPABASE_MODE: true
|
||||||
LOGFLARE_MIN_CLUSTER_SIZE: 1
|
|
||||||
|
|
||||||
# Comment variables to use Big Query backend for analytics
|
# Comment variables to use Big Query backend for analytics
|
||||||
POSTGRES_BACKEND_URL: postgresql://supabase_admin:${POSTGRES_PASSWORD}@${POSTGRES_HOST}:${POSTGRES_PORT}/_supabase
|
POSTGRES_BACKEND_URL: postgresql://supabase_admin:${POSTGRES_PASSWORD}@${POSTGRES_HOST}:${POSTGRES_PORT}/_supabase
|
||||||
@@ -355,7 +361,7 @@ services:
|
|||||||
|
|
||||||
# Comment out everything below this point if you are using an external Postgres database
|
# Comment out everything below this point if you are using an external Postgres database
|
||||||
db:
|
db:
|
||||||
image: supabase/postgres:15.8.1.060
|
image: supabase/postgres:15.8.1.085
|
||||||
restart: unless-stopped
|
restart: unless-stopped
|
||||||
volumes:
|
volumes:
|
||||||
- ./volumes/db/realtime.sql:/docker-entrypoint-initdb.d/migrations/99-realtime.sql:Z
|
- ./volumes/db/realtime.sql:/docker-entrypoint-initdb.d/migrations/99-realtime.sql:Z
|
||||||
@@ -429,7 +435,7 @@ services:
|
|||||||
|
|
||||||
# Update the DATABASE_URL if you are using an external Postgres database
|
# Update the DATABASE_URL if you are using an external Postgres database
|
||||||
supavisor:
|
supavisor:
|
||||||
image: supabase/supavisor:2.5.6
|
image: supabase/supavisor:2.7.4
|
||||||
restart: unless-stopped
|
restart: unless-stopped
|
||||||
volumes:
|
volumes:
|
||||||
- ./volumes/pooler/pooler.exs:/etc/pooler/pooler.exs:ro,z
|
- ./volumes/pooler/pooler.exs:/etc/pooler/pooler.exs:ro,z
|
||||||
|
|||||||
+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!"
|
set -e
|
||||||
read -p "Are you sure you want to proceed? (y/N) " -n 1 -r
|
|
||||||
echo # Move to a new line
|
auto_confirm=0
|
||||||
if [[ ! $REPLY =~ ^[Yy]$ ]]
|
|
||||||
then
|
confirm () {
|
||||||
echo "Operation cancelled."
|
if [ "$auto_confirm" = "1" ]; then
|
||||||
exit 1
|
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
|
fi
|
||||||
|
|
||||||
echo "Stopping and removing all containers..."
|
echo ""
|
||||||
docker compose -f docker-compose.yml -f ./dev/docker-compose.dev.yml down -v --remove-orphans
|
echo "*** WARNING: This will remove all containers and container data, and optionally reset .env ***"
|
||||||
|
echo ""
|
||||||
|
|
||||||
echo "Cleaning up bind-mounted directories..."
|
confirm
|
||||||
BIND_MOUNTS=(
|
|
||||||
"./volumes/db/data"
|
|
||||||
)
|
|
||||||
|
|
||||||
for DIR in "${BIND_MOUNTS[@]}"; do
|
echo "===> Stopping and removing all containers..."
|
||||||
if [ -d "$DIR" ]; then
|
|
||||||
echo "Deleting $DIR..."
|
if [ -f ".env" ]; then
|
||||||
rm -rf "$DIR"
|
docker compose -f docker-compose.yml -f ./dev/docker-compose.dev.yml down -v --remove-orphans
|
||||||
else
|
elif [ -f ".env.example" ]; then
|
||||||
echo "Directory $DIR does not exist. Skipping bind mount deletion step..."
|
echo "No .env found, using .env.example for docker compose down..."
|
||||||
fi
|
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
|
done
|
||||||
|
|
||||||
echo "Resetting .env file..."
|
echo "===> Resetting .env file (will save backup to .env.old)..."
|
||||||
if [ -f ".env" ]; then
|
confirm
|
||||||
echo "Removing existing .env file..."
|
if [ -f ".env" ] || [ -L ".env" ]; then
|
||||||
rm -f .env
|
echo "Renaming existing .env file to .env.old"
|
||||||
|
mv .env .env.old
|
||||||
else
|
else
|
||||||
echo "No .env file found. Skipping .env removal step..."
|
echo "No .env file found."
|
||||||
fi
|
fi
|
||||||
|
|
||||||
if [ -f ".env.example" ]; then
|
if [ -f ".env.example" ]; then
|
||||||
echo "Copying .env.example to .env..."
|
echo "===> Copying .env.example to .env"
|
||||||
cp .env.example .env
|
cp .env.example .env
|
||||||
else
|
else
|
||||||
echo ".env.example file not found. Skipping .env reset step..."
|
echo "No .env.example found, can't restore .env to default values."
|
||||||
fi
|
fi
|
||||||
|
|
||||||
echo "Cleanup complete!"
|
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,119 @@
|
|||||||
|
#!/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)
|
||||||
|
|
||||||
|
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 ""
|
||||||
|
|
||||||
|
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|^POSTGRES_PASSWORD=.*$|POSTGRES_PASSWORD=${postgres_password}|" \
|
||||||
|
-e "s|^DASHBOARD_PASSWORD=.*$|DASHBOARD_PASSWORD=${dashboard_password}|" \
|
||||||
|
.env
|
||||||
@@ -0,0 +1,83 @@
|
|||||||
|
# Docker Image Versions
|
||||||
|
|
||||||
|
## 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)
|
||||||
@@ -225,6 +225,48 @@ services:
|
|||||||
allow:
|
allow:
|
||||||
- admin
|
- 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
|
## Protected Dashboard - catch all remaining routes
|
||||||
- name: dashboard
|
- name: dashboard
|
||||||
_comment: 'Studio: /* -> http://studio:3000/*'
|
_comment: 'Studio: /* -> http://studio:3000/*'
|
||||||
|
|||||||
@@ -33,9 +33,9 @@ transforms:
|
|||||||
kong: '.appname == "supabase-kong"'
|
kong: '.appname == "supabase-kong"'
|
||||||
auth: '.appname == "supabase-auth"'
|
auth: '.appname == "supabase-auth"'
|
||||||
rest: '.appname == "supabase-rest"'
|
rest: '.appname == "supabase-rest"'
|
||||||
realtime: '.appname == "supabase-realtime"'
|
realtime: '.appname == "realtime-dev.supabase-realtime"'
|
||||||
storage: '.appname == "supabase-storage"'
|
storage: '.appname == "supabase-storage"'
|
||||||
functions: '.appname == "supabase-functions"'
|
functions: '.appname == "supabase-edge-functions"'
|
||||||
db: '.appname == "supabase-db"'
|
db: '.appname == "supabase-db"'
|
||||||
# Ignores non nginx errors since they are related with kong booting up
|
# Ignores non nginx errors since they are related with kong booting up
|
||||||
kong_logs:
|
kong_logs:
|
||||||
@@ -117,6 +117,13 @@ transforms:
|
|||||||
.event_message = parsed.msg
|
.event_message = parsed.msg
|
||||||
.metadata.level = parsed.level
|
.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 may contain json objects so we parse them for completeness
|
||||||
storage_logs:
|
storage_logs:
|
||||||
type: remap
|
type: remap
|
||||||
@@ -210,7 +217,7 @@ sinks:
|
|||||||
logflare_functions:
|
logflare_functions:
|
||||||
type: 'http'
|
type: 'http'
|
||||||
inputs:
|
inputs:
|
||||||
- router.functions
|
- functions_logs
|
||||||
encoding:
|
encoding:
|
||||||
codec: 'json'
|
codec: 'json'
|
||||||
method: 'post'
|
method: 'post'
|
||||||
|
|||||||
+7
-1
@@ -1,7 +1,13 @@
|
|||||||
import utils from "../utils.js";
|
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.copyDir("./repo/docker", "./code");
|
||||||
|
|
||||||
await utils.removeContainerNames("./code/docker-compose.yml");
|
await utils.removeContainerNames("./code/docker-compose.yml");
|
||||||
await utils.removePorts("./code/docker-compose.yml");
|
await utils.removePorts("./code/docker-compose.yml");
|
||||||
|
|
||||||
|
await utils.searchReplace(
|
||||||
|
"./code/.env.example",
|
||||||
|
"SITE_URL=http://localhost:3000",
|
||||||
|
"SITE_URL=https://$(PRIMARY_DOMAIN)"
|
||||||
|
);
|
||||||
|
|||||||
@@ -1,11 +0,0 @@
|
|||||||
#!/bin/bash
|
|
||||||
|
|
||||||
if [ ! -d "./repo" ]; then
|
|
||||||
git clone --depth 1 --branch master --single-branch https://github.com/supabase/supabase repo
|
|
||||||
else
|
|
||||||
cd repo
|
|
||||||
git pull
|
|
||||||
cd ..
|
|
||||||
fi
|
|
||||||
|
|
||||||
cp -r ./repo/docker/. ./code
|
|
||||||
@@ -1,4 +0,0 @@
|
|||||||
# Twenty
|
|
||||||
|
|
||||||
- copied from https://github.com/twentyhq/twenty
|
|
||||||
- removed `ports`
|
|
||||||
@@ -1,18 +0,0 @@
|
|||||||
TAG=latest
|
|
||||||
|
|
||||||
#PG_DATABASE_USER=postgres
|
|
||||||
#PG_DATABASE_PASSWORD=replace_me_with_a_strong_password_without_special_characters
|
|
||||||
#PG_DATABASE_HOST=db
|
|
||||||
#PG_DATABASE_PORT=5432
|
|
||||||
REDIS_URL=redis://redis:6379
|
|
||||||
|
|
||||||
SERVER_URL=https://$(PRIMARY_DOMAIN)
|
|
||||||
|
|
||||||
# Use openssl rand -base64 32 for each secret
|
|
||||||
APP_SECRET=replace_me_with_a_random_string
|
|
||||||
|
|
||||||
STORAGE_TYPE=local
|
|
||||||
|
|
||||||
# STORAGE_S3_REGION=eu-west3
|
|
||||||
# STORAGE_S3_NAME=my-bucket
|
|
||||||
# STORAGE_S3_ENDPOINT=
|
|
||||||
@@ -1,27 +0,0 @@
|
|||||||
# Makefile for building Twenty CRM docker images.
|
|
||||||
# Set the tag and/or target build platform using make command-line variables assignments.
|
|
||||||
#
|
|
||||||
# Optional make variables:
|
|
||||||
# PLATFORM - defaults to 'linux/amd64'
|
|
||||||
# TAG - defaults to 'latest'
|
|
||||||
#
|
|
||||||
# Example: make
|
|
||||||
# Example: make PLATFORM=linux/aarch64 TAG=my-tag
|
|
||||||
|
|
||||||
PLATFORM ?= linux/amd64
|
|
||||||
TAG ?= latest
|
|
||||||
|
|
||||||
prod-build:
|
|
||||||
@cd ../.. && docker build -f ./packages/twenty-docker/twenty/Dockerfile --platform $(PLATFORM) --tag twenty:$(TAG) . && cd -
|
|
||||||
|
|
||||||
prod-run:
|
|
||||||
@docker run -d -p 3000:3000 --name twenty twenty:$(TAG)
|
|
||||||
|
|
||||||
prod-postgres-run:
|
|
||||||
@docker run -d -p 5432:5432 -e POSTGRES_USER=postgres -e POSTGRES_PASSWORD=postgres --name twenty-postgres twenty-postgres:$(TAG)
|
|
||||||
|
|
||||||
prod-website-build:
|
|
||||||
@cd ../.. && docker build -f ./packages/twenty-docker/twenty-website/Dockerfile --platform $(PLATFORM) --tag twenty-website:$(TAG) . && cd -
|
|
||||||
|
|
||||||
prod-website-run:
|
|
||||||
@docker run -d -p 3000:3000 --name twenty-website twenty-website:$(TAG)
|
|
||||||
@@ -1,126 +0,0 @@
|
|||||||
name: twenty
|
|
||||||
|
|
||||||
services:
|
|
||||||
server:
|
|
||||||
image: twentycrm/twenty:${TAG:-latest}
|
|
||||||
volumes:
|
|
||||||
- server-local-data:/app/packages/twenty-server/.local-storage
|
|
||||||
environment:
|
|
||||||
NODE_PORT: 3000
|
|
||||||
PG_DATABASE_URL: postgres://${PG_DATABASE_USER:-postgres}:${PG_DATABASE_PASSWORD:-postgres}@${PG_DATABASE_HOST:-db}:${PG_DATABASE_PORT:-5432}/default
|
|
||||||
SERVER_URL: ${SERVER_URL}
|
|
||||||
REDIS_URL: ${REDIS_URL:-redis://redis:6379}
|
|
||||||
DISABLE_DB_MIGRATIONS: ${DISABLE_DB_MIGRATIONS}
|
|
||||||
DISABLE_CRON_JOBS_REGISTRATION: ${DISABLE_CRON_JOBS_REGISTRATION}
|
|
||||||
|
|
||||||
STORAGE_TYPE: ${STORAGE_TYPE}
|
|
||||||
STORAGE_S3_REGION: ${STORAGE_S3_REGION}
|
|
||||||
STORAGE_S3_NAME: ${STORAGE_S3_NAME}
|
|
||||||
STORAGE_S3_ENDPOINT: ${STORAGE_S3_ENDPOINT}
|
|
||||||
|
|
||||||
APP_SECRET: ${APP_SECRET:-replace_me_with_a_random_string}
|
|
||||||
# MESSAGING_PROVIDER_GMAIL_ENABLED: ${MESSAGING_PROVIDER_GMAIL_ENABLED}
|
|
||||||
# CALENDAR_PROVIDER_GOOGLE_ENABLED: ${CALENDAR_PROVIDER_GOOGLE_ENABLED}
|
|
||||||
# AUTH_GOOGLE_CLIENT_ID: ${AUTH_GOOGLE_CLIENT_ID}
|
|
||||||
# AUTH_GOOGLE_CLIENT_SECRET: ${AUTH_GOOGLE_CLIENT_SECRET}
|
|
||||||
# AUTH_GOOGLE_CALLBACK_URL: ${AUTH_GOOGLE_CALLBACK_URL}
|
|
||||||
# AUTH_GOOGLE_APIS_CALLBACK_URL: ${AUTH_GOOGLE_APIS_CALLBACK_URL}
|
|
||||||
|
|
||||||
# CALENDAR_PROVIDER_MICROSOFT_ENABLED: ${CALENDAR_PROVIDER_MICROSOFT_ENABLED}
|
|
||||||
# MESSAGING_PROVIDER_MICROSOFT_ENABLED: ${MESSAGING_PROVIDER_MICROSOFT_ENABLED}
|
|
||||||
# AUTH_MICROSOFT_ENABLED: ${AUTH_MICROSOFT_ENABLED}
|
|
||||||
# AUTH_MICROSOFT_CLIENT_ID: ${AUTH_MICROSOFT_CLIENT_ID}
|
|
||||||
# AUTH_MICROSOFT_CLIENT_SECRET: ${AUTH_MICROSOFT_CLIENT_SECRET}
|
|
||||||
# AUTH_MICROSOFT_CALLBACK_URL: ${AUTH_MICROSOFT_CALLBACK_URL}
|
|
||||||
# AUTH_MICROSOFT_APIS_CALLBACK_URL: ${AUTH_MICROSOFT_APIS_CALLBACK_URL}
|
|
||||||
|
|
||||||
# EMAIL_FROM_ADDRESS: ${EMAIL_FROM_ADDRESS:-contact@yourdomain.com}
|
|
||||||
# EMAIL_FROM_NAME: ${EMAIL_FROM_NAME:-"John from YourDomain"}
|
|
||||||
# EMAIL_SYSTEM_ADDRESS: ${EMAIL_SYSTEM_ADDRESS:-system@yourdomain.com}
|
|
||||||
# EMAIL_DRIVER: ${EMAIL_DRIVER:-smtp}
|
|
||||||
# EMAIL_SMTP_HOST: ${EMAIL_SMTP_HOST:-smtp.gmail.com}
|
|
||||||
# EMAIL_SMTP_PORT: ${EMAIL_SMTP_PORT:-465}
|
|
||||||
# EMAIL_SMTP_USER: ${EMAIL_SMTP_USER:-}
|
|
||||||
# EMAIL_SMTP_PASSWORD: ${EMAIL_SMTP_PASSWORD:-}
|
|
||||||
|
|
||||||
depends_on:
|
|
||||||
db:
|
|
||||||
condition: service_healthy
|
|
||||||
healthcheck:
|
|
||||||
test: curl --fail http://localhost:3000/healthz
|
|
||||||
interval: 5s
|
|
||||||
timeout: 5s
|
|
||||||
retries: 20
|
|
||||||
restart: always
|
|
||||||
|
|
||||||
worker:
|
|
||||||
image: twentycrm/twenty:${TAG:-latest}
|
|
||||||
volumes:
|
|
||||||
- server-local-data:/app/packages/twenty-server/.local-storage
|
|
||||||
command: [ "yarn", "worker:prod" ]
|
|
||||||
environment:
|
|
||||||
PG_DATABASE_URL: postgres://${PG_DATABASE_USER:-postgres}:${PG_DATABASE_PASSWORD:-postgres}@${PG_DATABASE_HOST:-db}:${PG_DATABASE_PORT:-5432}/default
|
|
||||||
SERVER_URL: ${SERVER_URL}
|
|
||||||
REDIS_URL: ${REDIS_URL:-redis://redis:6379}
|
|
||||||
DISABLE_DB_MIGRATIONS: "true" # it already runs on the server
|
|
||||||
DISABLE_CRON_JOBS_REGISTRATION: "true" # it already runs on the server
|
|
||||||
|
|
||||||
STORAGE_TYPE: ${STORAGE_TYPE}
|
|
||||||
STORAGE_S3_REGION: ${STORAGE_S3_REGION}
|
|
||||||
STORAGE_S3_NAME: ${STORAGE_S3_NAME}
|
|
||||||
STORAGE_S3_ENDPOINT: ${STORAGE_S3_ENDPOINT}
|
|
||||||
|
|
||||||
APP_SECRET: ${APP_SECRET:-replace_me_with_a_random_string}
|
|
||||||
# MESSAGING_PROVIDER_GMAIL_ENABLED: ${MESSAGING_PROVIDER_GMAIL_ENABLED}
|
|
||||||
# CALENDAR_PROVIDER_GOOGLE_ENABLED: ${CALENDAR_PROVIDER_GOOGLE_ENABLED}
|
|
||||||
# AUTH_GOOGLE_CLIENT_ID: ${AUTH_GOOGLE_CLIENT_ID}
|
|
||||||
# AUTH_GOOGLE_CLIENT_SECRET: ${AUTH_GOOGLE_CLIENT_SECRET}
|
|
||||||
# AUTH_GOOGLE_CALLBACK_URL: ${AUTH_GOOGLE_CALLBACK_URL}
|
|
||||||
# AUTH_GOOGLE_APIS_CALLBACK_URL: ${AUTH_GOOGLE_APIS_CALLBACK_URL}
|
|
||||||
|
|
||||||
# CALENDAR_PROVIDER_MICROSOFT_ENABLED: ${CALENDAR_PROVIDER_MICROSOFT_ENABLED}
|
|
||||||
# MESSAGING_PROVIDER_MICROSOFT_ENABLED: ${MESSAGING_PROVIDER_MICROSOFT_ENABLED}
|
|
||||||
# AUTH_MICROSOFT_ENABLED: ${AUTH_MICROSOFT_ENABLED}
|
|
||||||
# AUTH_MICROSOFT_CLIENT_ID: ${AUTH_MICROSOFT_CLIENT_ID}
|
|
||||||
# AUTH_MICROSOFT_CLIENT_SECRET: ${AUTH_MICROSOFT_CLIENT_SECRET}
|
|
||||||
# AUTH_MICROSOFT_CALLBACK_URL: ${AUTH_MICROSOFT_CALLBACK_URL}
|
|
||||||
# AUTH_MICROSOFT_APIS_CALLBACK_URL: ${AUTH_MICROSOFT_APIS_CALLBACK_URL}
|
|
||||||
|
|
||||||
# EMAIL_FROM_ADDRESS: ${EMAIL_FROM_ADDRESS:-contact@yourdomain.com}
|
|
||||||
# EMAIL_FROM_NAME: ${EMAIL_FROM_NAME:-"John from YourDomain"}
|
|
||||||
# EMAIL_SYSTEM_ADDRESS: ${EMAIL_SYSTEM_ADDRESS:-system@yourdomain.com}
|
|
||||||
# EMAIL_DRIVER: ${EMAIL_DRIVER:-smtp}
|
|
||||||
# EMAIL_SMTP_HOST: ${EMAIL_SMTP_HOST:-smtp.gmail.com}
|
|
||||||
# EMAIL_SMTP_PORT: ${EMAIL_SMTP_PORT:-465}
|
|
||||||
# EMAIL_SMTP_USER: ${EMAIL_SMTP_USER:-}
|
|
||||||
# EMAIL_SMTP_PASSWORD: ${EMAIL_SMTP_PASSWORD:-}
|
|
||||||
|
|
||||||
depends_on:
|
|
||||||
db:
|
|
||||||
condition: service_healthy
|
|
||||||
server:
|
|
||||||
condition: service_healthy
|
|
||||||
restart: always
|
|
||||||
|
|
||||||
db:
|
|
||||||
image: postgres:16
|
|
||||||
volumes:
|
|
||||||
- db-data:/var/lib/postgresql/data
|
|
||||||
environment:
|
|
||||||
POSTGRES_USER: ${PG_DATABASE_USER:-postgres}
|
|
||||||
POSTGRES_PASSWORD: ${PG_DATABASE_PASSWORD:-postgres}
|
|
||||||
healthcheck:
|
|
||||||
test: pg_isready -U ${PG_DATABASE_USER:-postgres} -h localhost -d postgres
|
|
||||||
interval: 5s
|
|
||||||
timeout: 5s
|
|
||||||
retries: 10
|
|
||||||
restart: always
|
|
||||||
|
|
||||||
redis:
|
|
||||||
image: redis
|
|
||||||
restart: always
|
|
||||||
command: [ "--maxmemory-policy", "noeviction" ]
|
|
||||||
|
|
||||||
volumes:
|
|
||||||
db-data:
|
|
||||||
server-local-data:
|
|
||||||
@@ -1,15 +0,0 @@
|
|||||||
apiVersion: 1
|
|
||||||
|
|
||||||
datasources:
|
|
||||||
- name: ClickHouse
|
|
||||||
type: grafana-clickhouse-datasource
|
|
||||||
uid: clickhouse_datasource
|
|
||||||
jsonData:
|
|
||||||
server: twenty_clickhouse
|
|
||||||
defaultDatabase: twenty_dev
|
|
||||||
port: 9000
|
|
||||||
protocol: native
|
|
||||||
tlsSkipVerify: true
|
|
||||||
username: default
|
|
||||||
secureJsonData:
|
|
||||||
password: devPassword
|
|
||||||
@@ -1,116 +0,0 @@
|
|||||||
# README
|
|
||||||
DISCLAIMER: The k8s and podman deployments are not maintained by the core team.
|
|
||||||
These files are provided and maintained by the community. Twenty core team
|
|
||||||
maintains support for docker deployment.
|
|
||||||
|
|
||||||
## Overview
|
|
||||||
|
|
||||||
This repository contains Kubernetes manifests and Terraform files to help you deploy and manage the TwentyCRM application. The files are located in the `packages/twenty-docker/k8s` directory.
|
|
||||||
|
|
||||||
## Prerequisites
|
|
||||||
|
|
||||||
Before using these files, ensure you have the following installed and configured on your system:
|
|
||||||
|
|
||||||
- Kubernetes cluster (e.g., Minikube, EKS, GKE)
|
|
||||||
- kubectl
|
|
||||||
- Terraform
|
|
||||||
- Docker
|
|
||||||
|
|
||||||
## Setup Instructions
|
|
||||||
|
|
||||||
### Step 1: Clone the Repository
|
|
||||||
|
|
||||||
Clone the repository to your local machine:
|
|
||||||
|
|
||||||
``` bash
|
|
||||||
git clone https://github.com/twentyhq/twenty.git
|
|
||||||
cd twentycrm/packages/twenty-docker/k8s
|
|
||||||
```
|
|
||||||
|
|
||||||
### Step 2: Customize the Manifests and Terraform Files
|
|
||||||
|
|
||||||
**Important:** These files require customization for your specific implementation. Update the placeholders and configurations according to your environment and requirements.
|
|
||||||
|
|
||||||
### Step 3: Deploy with Terraform
|
|
||||||
|
|
||||||
1. Navigate to the Terraform directory:
|
|
||||||
|
|
||||||
```bash
|
|
||||||
cd terraform
|
|
||||||
```
|
|
||||||
|
|
||||||
2. Initialize Terraform:
|
|
||||||
|
|
||||||
```bash
|
|
||||||
terraform init
|
|
||||||
```
|
|
||||||
|
|
||||||
3. Plan the deployment:
|
|
||||||
|
|
||||||
```bash
|
|
||||||
terraform plan
|
|
||||||
```
|
|
||||||
|
|
||||||
4. Apply the deployment:
|
|
||||||
|
|
||||||
```bash
|
|
||||||
terraform apply
|
|
||||||
```
|
|
||||||
|
|
||||||
## OR
|
|
||||||
|
|
||||||
### Step 3: Deploy with Kubernetes Manifests
|
|
||||||
|
|
||||||
1. Navigate to the Kubernetes manifests directory:
|
|
||||||
|
|
||||||
```bash
|
|
||||||
cd ../k8s
|
|
||||||
```
|
|
||||||
|
|
||||||
2. Create Server Secret
|
|
||||||
|
|
||||||
``` bash
|
|
||||||
kubectl create secret generic -n twentycrm tokens --from-literal accessToken=changeme --from-literal loginToken="changeme" --from-literal refreshToken="changeme" --from-literal fileToken="changeme"
|
|
||||||
```
|
|
||||||
|
|
||||||
3. Apply the manifests:
|
|
||||||
|
|
||||||
```bash
|
|
||||||
kubectl apply -f .
|
|
||||||
```
|
|
||||||
|
|
||||||
## Customization
|
|
||||||
|
|
||||||
### Kubernetes Manifests
|
|
||||||
|
|
||||||
- **Namespace:** Update the `namespace` in the manifests as needed.
|
|
||||||
- **Resource Limits:** Adjust the resource limits and requests according to your application's requirements.
|
|
||||||
- **Environment Variables:** Configure server tokens in the `Secret` command above.
|
|
||||||
|
|
||||||
### Terraform Files
|
|
||||||
|
|
||||||
- **Variables:** Update the variables in the `variables.tf` file to match your environment.
|
|
||||||
- **Locals:** Update the locals in the `main.tf` file to match your environment.
|
|
||||||
- **Providers:** Ensure the provider configurations (e.g., AWS, GCP) are correct for your setup.
|
|
||||||
- **Resources:** Modify the resource definitions as needed to fit your infrastructure.
|
|
||||||
|
|
||||||
## Troubleshooting
|
|
||||||
|
|
||||||
### Common Issues
|
|
||||||
|
|
||||||
- **Connectivity:** Ensure your Kubernetes cluster is accessible and configured correctly.
|
|
||||||
- **Permissions:** Verify that you have the necessary permissions to deploy resources in your cloud provider.
|
|
||||||
- **Resource Limits:** Adjust resource limits if you encounter issues related to insufficient resources.
|
|
||||||
|
|
||||||
### Logs and Debugging
|
|
||||||
|
|
||||||
- Use `kubectl logs` to check the logs of your Kubernetes pods.
|
|
||||||
- Use `terraform show` and `terraform state` to inspect your Terraform state and configurations.
|
|
||||||
|
|
||||||
## Conclusion
|
|
||||||
|
|
||||||
This setup provides a basic structure for deploying the TwentyCRM application using Kubernetes and Terraform. Ensure you thoroughly customize the manifests and Terraform files to suit your specific needs. For any issues or questions, please refer to the official documentation of Kubernetes and Terraform or seek support from your cloud provider.
|
|
||||||
|
|
||||||
---
|
|
||||||
|
|
||||||
Feel free to contribute and improve this repository by submitting pull requests or opening issues. Happy deploying!
|
|
||||||
@@ -1,58 +0,0 @@
|
|||||||
apiVersion: apps/v1
|
|
||||||
kind: Deployment
|
|
||||||
metadata:
|
|
||||||
labels:
|
|
||||||
app: twentycrm-db
|
|
||||||
name: twentycrm-db
|
|
||||||
namespace: twentycrm
|
|
||||||
spec:
|
|
||||||
progressDeadlineSeconds: 600
|
|
||||||
replicas: 1
|
|
||||||
strategy:
|
|
||||||
rollingUpdate:
|
|
||||||
maxSurge: 1
|
|
||||||
maxUnavailable: 1
|
|
||||||
type: RollingUpdate
|
|
||||||
selector:
|
|
||||||
matchLabels:
|
|
||||||
app: twentycrm-db
|
|
||||||
template:
|
|
||||||
metadata:
|
|
||||||
labels:
|
|
||||||
app: twentycrm-db
|
|
||||||
spec:
|
|
||||||
volumes:
|
|
||||||
- name: twentycrm-db-data
|
|
||||||
persistentVolumeClaim:
|
|
||||||
claimName: twentycrm-db-pvc
|
|
||||||
containers:
|
|
||||||
- name: twentycrm
|
|
||||||
image: twentycrm/twenty-postgres-spilo:latest
|
|
||||||
imagePullPolicy: Always
|
|
||||||
env:
|
|
||||||
- name: PGUSER_SUPERUSER
|
|
||||||
value: "postgres"
|
|
||||||
- name: PGPASSWORD_SUPERUSER
|
|
||||||
value: "postgres"
|
|
||||||
- name: SPILO_PROVIDER
|
|
||||||
value: "local"
|
|
||||||
- name: ALLOW_NOSSL
|
|
||||||
value: "true"
|
|
||||||
ports:
|
|
||||||
- containerPort: 5432
|
|
||||||
name: tcp
|
|
||||||
protocol: TCP
|
|
||||||
resources:
|
|
||||||
requests:
|
|
||||||
memory: "256Mi"
|
|
||||||
cpu: "250m"
|
|
||||||
limits:
|
|
||||||
memory: "1024Mi"
|
|
||||||
cpu: "1000m"
|
|
||||||
stdin: true
|
|
||||||
tty: true
|
|
||||||
volumeMounts:
|
|
||||||
- mountPath: /home/postgres/pgdata
|
|
||||||
name: twentycrm-db-data
|
|
||||||
dnsPolicy: ClusterFirst
|
|
||||||
restartPolicy: Always
|
|
||||||
@@ -1,45 +0,0 @@
|
|||||||
apiVersion: apps/v1
|
|
||||||
kind: Deployment
|
|
||||||
metadata:
|
|
||||||
labels:
|
|
||||||
app: twentycrm-redis
|
|
||||||
name: twentycrm-redis
|
|
||||||
namespace: twentycrm
|
|
||||||
spec:
|
|
||||||
progressDeadlineSeconds: 600
|
|
||||||
replicas: 1
|
|
||||||
strategy:
|
|
||||||
rollingUpdate:
|
|
||||||
maxSurge: 1
|
|
||||||
maxUnavailable: 1
|
|
||||||
type: RollingUpdate
|
|
||||||
selector:
|
|
||||||
matchLabels:
|
|
||||||
app: twentycrm-redis
|
|
||||||
template:
|
|
||||||
metadata:
|
|
||||||
labels:
|
|
||||||
app: twentycrm-redis
|
|
||||||
spec:
|
|
||||||
containers:
|
|
||||||
- name: redis
|
|
||||||
image: redis/redis-stack-server:latest
|
|
||||||
imagePullPolicy: Always
|
|
||||||
args: ["--maxmemory-policy", "noeviction"]
|
|
||||||
env:
|
|
||||||
- name: PORT
|
|
||||||
value: "6379"
|
|
||||||
ports:
|
|
||||||
- containerPort: 6379
|
|
||||||
name: redis
|
|
||||||
protocol: TCP
|
|
||||||
resources:
|
|
||||||
requests:
|
|
||||||
memory: "1024Mi"
|
|
||||||
cpu: "250m"
|
|
||||||
limits:
|
|
||||||
memory: "2048Mi"
|
|
||||||
cpu: "500m"
|
|
||||||
|
|
||||||
dnsPolicy: ClusterFirst
|
|
||||||
restartPolicy: Always
|
|
||||||
@@ -1,76 +0,0 @@
|
|||||||
apiVersion: apps/v1
|
|
||||||
kind: Deployment
|
|
||||||
metadata:
|
|
||||||
labels:
|
|
||||||
app: twentycrm-server
|
|
||||||
name: twentycrm-server
|
|
||||||
namespace: twentycrm
|
|
||||||
spec:
|
|
||||||
progressDeadlineSeconds: 600
|
|
||||||
replicas: 1
|
|
||||||
strategy:
|
|
||||||
rollingUpdate:
|
|
||||||
maxSurge: 1
|
|
||||||
maxUnavailable: 1
|
|
||||||
type: RollingUpdate
|
|
||||||
selector:
|
|
||||||
matchLabels:
|
|
||||||
app: twentycrm-server
|
|
||||||
template:
|
|
||||||
metadata:
|
|
||||||
labels:
|
|
||||||
app: twentycrm-server
|
|
||||||
spec:
|
|
||||||
volumes:
|
|
||||||
- name: twentycrm-server-data
|
|
||||||
persistentVolumeClaim:
|
|
||||||
claimName: twentycrm-server-pvc
|
|
||||||
- name: twentycrm-docker-data
|
|
||||||
persistentVolumeClaim:
|
|
||||||
claimName: twentycrm-docker-data-pvc
|
|
||||||
containers:
|
|
||||||
- name: twentycrm
|
|
||||||
image: twentycrm/twenty:latest
|
|
||||||
imagePullPolicy: Always
|
|
||||||
env:
|
|
||||||
- name: NODE_PORT
|
|
||||||
value: 3000
|
|
||||||
- name: SERVER_URL
|
|
||||||
value: "https://crm.example.com:443"
|
|
||||||
- name: "PG_DATABASE_URL"
|
|
||||||
value: "postgres://postgres:postgres@twentycrm-db.twentycrm.svc.cluster.local/default"
|
|
||||||
- name: "REDIS_URL"
|
|
||||||
value: "redis://twentycrm-redis.twentycrm.svc.cluster.local:6379"
|
|
||||||
- name: SIGN_IN_PREFILLED
|
|
||||||
value: "false"
|
|
||||||
- name: STORAGE_TYPE
|
|
||||||
value: "local"
|
|
||||||
- name: "ACCESS_TOKEN_EXPIRES_IN"
|
|
||||||
value: "7d"
|
|
||||||
- name: "LOGIN_TOKEN_EXPIRES_IN"
|
|
||||||
value: "1h"
|
|
||||||
- name: APP_SECRET
|
|
||||||
valueFrom:
|
|
||||||
secretKeyRef:
|
|
||||||
name: tokens
|
|
||||||
key: accessToken
|
|
||||||
ports:
|
|
||||||
- containerPort: 3000
|
|
||||||
name: http-tcp
|
|
||||||
protocol: TCP
|
|
||||||
resources:
|
|
||||||
requests:
|
|
||||||
memory: "256Mi"
|
|
||||||
cpu: "250m"
|
|
||||||
limits:
|
|
||||||
memory: "1024Mi"
|
|
||||||
cpu: "1000m"
|
|
||||||
stdin: true
|
|
||||||
tty: true
|
|
||||||
volumeMounts:
|
|
||||||
- mountPath: /app/docker-data
|
|
||||||
name: twentycrm-docker-data
|
|
||||||
- mountPath: /app/packages/twenty-server/.local-storage
|
|
||||||
name: twentycrm-server-data
|
|
||||||
dnsPolicy: ClusterFirst
|
|
||||||
restartPolicy: Always
|
|
||||||
@@ -1,57 +0,0 @@
|
|||||||
apiVersion: apps/v1
|
|
||||||
kind: Deployment
|
|
||||||
metadata:
|
|
||||||
labels:
|
|
||||||
app: twentycrm-worker
|
|
||||||
name: twentycrm-worker
|
|
||||||
namespace: twentycrm
|
|
||||||
spec:
|
|
||||||
progressDeadlineSeconds: 600
|
|
||||||
replicas: 1
|
|
||||||
strategy:
|
|
||||||
rollingUpdate:
|
|
||||||
maxSurge: 1
|
|
||||||
maxUnavailable: 1
|
|
||||||
type: RollingUpdate
|
|
||||||
selector:
|
|
||||||
matchLabels:
|
|
||||||
app: twentycrm-worker
|
|
||||||
template:
|
|
||||||
metadata:
|
|
||||||
labels:
|
|
||||||
app: twentycrm-worker
|
|
||||||
spec:
|
|
||||||
containers:
|
|
||||||
- name: twentycrm
|
|
||||||
image: twentycrm/twenty:latest
|
|
||||||
imagePullPolicy: Always
|
|
||||||
env:
|
|
||||||
- name: SERVER_URL
|
|
||||||
value: "https://crm.example.com:443"
|
|
||||||
- name: PG_DATABASE_URL
|
|
||||||
value: "postgres://postgres:postgres@twentycrm-db.twentycrm.svc.cluster.local/default"
|
|
||||||
- name: DISABLE_DB_MIGRATIONS
|
|
||||||
value: "false" # it already runs on the server
|
|
||||||
- name: STORAGE_TYPE
|
|
||||||
value: "local"
|
|
||||||
- name: "REDIS_URL"
|
|
||||||
value: "redis://twentycrm-redis.twentycrm.svc.cluster.local:6379"
|
|
||||||
- name: APP_SECRET
|
|
||||||
valueFrom:
|
|
||||||
secretKeyRef:
|
|
||||||
name: tokens
|
|
||||||
key: accessToken
|
|
||||||
command:
|
|
||||||
- yarn
|
|
||||||
- worker:prod
|
|
||||||
resources:
|
|
||||||
requests:
|
|
||||||
memory: "1024Mi"
|
|
||||||
cpu: "250m"
|
|
||||||
limits:
|
|
||||||
memory: "2048Mi"
|
|
||||||
cpu: "1000m"
|
|
||||||
stdin: true
|
|
||||||
tty: true
|
|
||||||
dnsPolicy: ClusterFirst
|
|
||||||
restartPolicy: Always
|
|
||||||
@@ -1,24 +0,0 @@
|
|||||||
apiVersion: networking.k8s.io/v1
|
|
||||||
kind: Ingress
|
|
||||||
metadata:
|
|
||||||
name: twentycrm
|
|
||||||
namespace: twentycrm
|
|
||||||
annotations:
|
|
||||||
nginx.ingress.kubernetes.io/configuration-snippet: |
|
|
||||||
more_set_headers "X-Forwarded-For $http_x_forwarded_for";
|
|
||||||
nginx.ingress.kubernetes.io/force-ssl-redirect: "false"
|
|
||||||
kubernetes.io/ingress.class: "nginx"
|
|
||||||
nginx.ingress.kubernetes.io/backend-protocol: "HTTP"
|
|
||||||
spec:
|
|
||||||
ingressClassName: nginx
|
|
||||||
rules:
|
|
||||||
- host: crm.example.com
|
|
||||||
http:
|
|
||||||
paths:
|
|
||||||
- path: /
|
|
||||||
pathType: Prefix
|
|
||||||
backend:
|
|
||||||
service:
|
|
||||||
name: twentycrm-server
|
|
||||||
port:
|
|
||||||
name: http-tcp
|
|
||||||
@@ -1,11 +0,0 @@
|
|||||||
apiVersion: v1
|
|
||||||
kind: PersistentVolume
|
|
||||||
metadata:
|
|
||||||
name: twentycrm-db-pv
|
|
||||||
spec:
|
|
||||||
storageClassName: default
|
|
||||||
capacity:
|
|
||||||
storage: 10Gi
|
|
||||||
accessModes:
|
|
||||||
- ReadWriteOnce
|
|
||||||
persistentVolumeReclaimPolicy: Retain
|
|
||||||
@@ -1,11 +0,0 @@
|
|||||||
apiVersion: v1
|
|
||||||
kind: PersistentVolume
|
|
||||||
metadata:
|
|
||||||
name: twentycrm-docker-data-pv
|
|
||||||
spec:
|
|
||||||
storageClassName: default
|
|
||||||
capacity:
|
|
||||||
storage: 100Mi
|
|
||||||
accessModes:
|
|
||||||
- ReadWriteOnce
|
|
||||||
persistentVolumeReclaimPolicy: Retain
|
|
||||||
@@ -1,12 +0,0 @@
|
|||||||
apiVersion: v1
|
|
||||||
kind: PersistentVolume
|
|
||||||
metadata:
|
|
||||||
name: twentycrm-server-pv
|
|
||||||
namespace: twentycrm
|
|
||||||
spec:
|
|
||||||
storageClassName: default
|
|
||||||
capacity:
|
|
||||||
storage: 10Gi
|
|
||||||
accessModes:
|
|
||||||
- ReadWriteOnce
|
|
||||||
persistentVolumeReclaimPolicy: Retain
|
|
||||||
@@ -1,13 +0,0 @@
|
|||||||
apiVersion: v1
|
|
||||||
kind: PersistentVolumeClaim
|
|
||||||
metadata:
|
|
||||||
name: twentycrm-db-pvc
|
|
||||||
namespace: twentycrm
|
|
||||||
spec:
|
|
||||||
storageClassName: default
|
|
||||||
volumeName: twentycrm-db-pv
|
|
||||||
accessModes:
|
|
||||||
- ReadWriteOnce
|
|
||||||
resources:
|
|
||||||
requests:
|
|
||||||
storage: 10Gi
|
|
||||||
@@ -1,13 +0,0 @@
|
|||||||
apiVersion: v1
|
|
||||||
kind: PersistentVolumeClaim
|
|
||||||
metadata:
|
|
||||||
name: twentycrm-docker-data-pvc
|
|
||||||
namespace: twentycrm
|
|
||||||
spec:
|
|
||||||
storageClassName: default
|
|
||||||
volumeName: twentycrm-docker-data-pv
|
|
||||||
accessModes:
|
|
||||||
- ReadWriteOnce
|
|
||||||
resources:
|
|
||||||
requests:
|
|
||||||
storage: 100Mi
|
|
||||||
@@ -1,13 +0,0 @@
|
|||||||
apiVersion: v1
|
|
||||||
kind: PersistentVolumeClaim
|
|
||||||
metadata:
|
|
||||||
name: twentycrm-server-pvc
|
|
||||||
namespace: twentycrm
|
|
||||||
spec:
|
|
||||||
storageClassName: default
|
|
||||||
volumeName: twentycrm-server-pv
|
|
||||||
accessModes:
|
|
||||||
- ReadWriteOnce
|
|
||||||
resources:
|
|
||||||
requests:
|
|
||||||
storage: 10Gi
|
|
||||||
@@ -1,18 +0,0 @@
|
|||||||
apiVersion: v1
|
|
||||||
kind: Service
|
|
||||||
metadata:
|
|
||||||
name: twentycrm-db
|
|
||||||
namespace: twentycrm
|
|
||||||
spec:
|
|
||||||
internalTrafficPolicy: Cluster
|
|
||||||
ports:
|
|
||||||
- port: 5432
|
|
||||||
protocol: TCP
|
|
||||||
targetPort: 5432
|
|
||||||
selector:
|
|
||||||
app: twentycrm-db
|
|
||||||
sessionAffinity: ClientIP
|
|
||||||
sessionAffinityConfig:
|
|
||||||
clientIP:
|
|
||||||
timeoutSeconds: 10800
|
|
||||||
type: ClusterIP
|
|
||||||
@@ -1,18 +0,0 @@
|
|||||||
apiVersion: v1
|
|
||||||
kind: Service
|
|
||||||
metadata:
|
|
||||||
name: twentycrm-redis
|
|
||||||
namespace: twentycrm
|
|
||||||
spec:
|
|
||||||
internalTrafficPolicy: Cluster
|
|
||||||
ports:
|
|
||||||
- port: 6379
|
|
||||||
protocol: TCP
|
|
||||||
targetPort: 6379
|
|
||||||
selector:
|
|
||||||
app: twentycrm-redis
|
|
||||||
sessionAffinity: ClientIP
|
|
||||||
sessionAffinityConfig:
|
|
||||||
clientIP:
|
|
||||||
timeoutSeconds: 10800
|
|
||||||
type: ClusterIP
|
|
||||||
@@ -1,19 +0,0 @@
|
|||||||
apiVersion: v1
|
|
||||||
kind: Service
|
|
||||||
metadata:
|
|
||||||
name: twentycrm-server
|
|
||||||
namespace: twentycrm
|
|
||||||
spec:
|
|
||||||
internalTrafficPolicy: Cluster
|
|
||||||
ports:
|
|
||||||
- name: http-tcp
|
|
||||||
port: 3000
|
|
||||||
protocol: TCP
|
|
||||||
targetPort: 3000
|
|
||||||
selector:
|
|
||||||
app: twentycrm-server
|
|
||||||
sessionAffinity: ClientIP
|
|
||||||
sessionAffinityConfig:
|
|
||||||
clientIP:
|
|
||||||
timeoutSeconds: 10800
|
|
||||||
type: ClusterIP
|
|
||||||
@@ -1,48 +0,0 @@
|
|||||||
formatter: "markdown table" # this is required
|
|
||||||
|
|
||||||
version: ""
|
|
||||||
|
|
||||||
header-from: main.tf
|
|
||||||
|
|
||||||
recursive:
|
|
||||||
enabled: false
|
|
||||||
path: modules
|
|
||||||
|
|
||||||
output:
|
|
||||||
file: "README.md"
|
|
||||||
mode: inject
|
|
||||||
template: |-
|
|
||||||
<!-- BEGIN_TF_DOCS -->
|
|
||||||
# TwentyCRM Terraform Docs
|
|
||||||
|
|
||||||
This file was generated by [terraform-docs](https://terraform-docs.io/), for more information on how to install, configure, and use visit their website.
|
|
||||||
|
|
||||||
To update this `README.md` after changes to the Terraform code in this folder, run: `terraform-docs -c `./.terraform-docs.yml .`
|
|
||||||
|
|
||||||
To make configuration changes to how this doc is generated, see `./.terraform-docs.yml`
|
|
||||||
|
|
||||||
{{ .Content }}
|
|
||||||
<!-- END_TF_DOCS -->
|
|
||||||
|
|
||||||
output-values:
|
|
||||||
enabled: false
|
|
||||||
from: "outputs.tf"
|
|
||||||
|
|
||||||
sort:
|
|
||||||
enabled: true
|
|
||||||
by: required
|
|
||||||
|
|
||||||
settings:
|
|
||||||
anchor: true
|
|
||||||
color: true
|
|
||||||
default: true
|
|
||||||
description: true
|
|
||||||
escape: true
|
|
||||||
hide-empty: true
|
|
||||||
html: true
|
|
||||||
indent: 2
|
|
||||||
lockfile: true
|
|
||||||
read-comments: true
|
|
||||||
required: true
|
|
||||||
sensitive: true
|
|
||||||
type: true
|
|
||||||
@@ -1,73 +0,0 @@
|
|||||||
<!-- BEGIN_TF_DOCS -->
|
|
||||||
# TwentyCRM Terraform Docs
|
|
||||||
|
|
||||||
This file was generated by [terraform-docs](https://terraform-docs.io/), for more information on how to install, configure, and use visit their website.
|
|
||||||
|
|
||||||
To update this `README.md` after changes to the Terraform code in this folder, run: `terraform-docs -c `./.terraform-docs.yml .`
|
|
||||||
|
|
||||||
To make configuration changes to how this doc is generated, see `./.terraform-docs.yml`
|
|
||||||
|
|
||||||
## Requirements
|
|
||||||
|
|
||||||
| Name | Version |
|
|
||||||
|------|---------|
|
|
||||||
| <a name="requirement_terraform"></a> [terraform](#requirement\_terraform) | >= 1.9.2 |
|
|
||||||
| <a name="requirement_kubernetes"></a> [kubernetes](#requirement\_kubernetes) | >= 2.32.0 |
|
|
||||||
| <a name="requirement_random"></a> [random](#requirement\_random) | >= 3.6.3 |
|
|
||||||
|
|
||||||
## Providers
|
|
||||||
|
|
||||||
| Name | Version |
|
|
||||||
|------|---------|
|
|
||||||
| <a name="provider_kubernetes"></a> [kubernetes](#provider\_kubernetes) | >= 2.32.0 |
|
|
||||||
| <a name="provider_random"></a> [random](#provider\_random) | >= 3.6.3 |
|
|
||||||
|
|
||||||
## Resources
|
|
||||||
|
|
||||||
| Name | Type |
|
|
||||||
|------|------|
|
|
||||||
| [kubernetes_deployment.twentycrm_db](https://registry.terraform.io/providers/hashicorp/kubernetes/latest/docs/resources/deployment) | resource |
|
|
||||||
| [kubernetes_deployment.twentycrm_redis](https://registry.terraform.io/providers/hashicorp/kubernetes/latest/docs/resources/deployment) | resource |
|
|
||||||
| [kubernetes_deployment.twentycrm_server](https://registry.terraform.io/providers/hashicorp/kubernetes/latest/docs/resources/deployment) | resource |
|
|
||||||
| [kubernetes_deployment.twentycrm_worker](https://registry.terraform.io/providers/hashicorp/kubernetes/latest/docs/resources/deployment) | resource |
|
|
||||||
| [kubernetes_ingress.twentycrm](https://registry.terraform.io/providers/hashicorp/kubernetes/latest/docs/resources/ingress) | resource |
|
|
||||||
| [kubernetes_namespace.twentycrm](https://registry.terraform.io/providers/hashicorp/kubernetes/latest/docs/resources/namespace) | resource |
|
|
||||||
| [kubernetes_persistent_volume.db](https://registry.terraform.io/providers/hashicorp/kubernetes/latest/docs/resources/persistent_volume) | resource |
|
|
||||||
| [kubernetes_persistent_volume.docker_data](https://registry.terraform.io/providers/hashicorp/kubernetes/latest/docs/resources/persistent_volume) | resource |
|
|
||||||
| [kubernetes_persistent_volume.server](https://registry.terraform.io/providers/hashicorp/kubernetes/latest/docs/resources/persistent_volume) | resource |
|
|
||||||
| [kubernetes_persistent_volume_claim.db](https://registry.terraform.io/providers/hashicorp/kubernetes/latest/docs/resources/persistent_volume_claim) | resource |
|
|
||||||
| [kubernetes_persistent_volume_claim.docker_data](https://registry.terraform.io/providers/hashicorp/kubernetes/latest/docs/resources/persistent_volume_claim) | resource |
|
|
||||||
| [kubernetes_persistent_volume_claim.server](https://registry.terraform.io/providers/hashicorp/kubernetes/latest/docs/resources/persistent_volume_claim) | resource |
|
|
||||||
| [kubernetes_secret.twentycrm_tokens](https://registry.terraform.io/providers/hashicorp/kubernetes/latest/docs/resources/secret) | resource |
|
|
||||||
| [kubernetes_service.twentycrm_db](https://registry.terraform.io/providers/hashicorp/kubernetes/latest/docs/resources/service) | resource |
|
|
||||||
| [kubernetes_service.twentycrm_redis](https://registry.terraform.io/providers/hashicorp/kubernetes/latest/docs/resources/service) | resource |
|
|
||||||
| [kubernetes_service.twentycrm_server](https://registry.terraform.io/providers/hashicorp/kubernetes/latest/docs/resources/service) | resource |
|
|
||||||
| [random_bytes.this](https://registry.terraform.io/providers/hashicorp/random/latest/docs/resources/bytes) | resource |
|
|
||||||
|
|
||||||
## Inputs
|
|
||||||
|
|
||||||
| Name | Description | Type | Default | Required |
|
|
||||||
|------|-------------|------|---------|:--------:|
|
|
||||||
| <a name="input_twentycrm_app_hostname"></a> [twentycrm\_app\_hostname](#input\_twentycrm\_app\_hostname) | The protocol, DNS fully qualified hostname, and port used to access TwentyCRM in your environment. Ex: https://crm.example.com:443 | `string` | n/a | yes |
|
|
||||||
| <a name="input_twentycrm_pgdb_admin_password"></a> [twentycrm\_pgdb\_admin\_password](#input\_twentycrm\_pgdb\_admin\_password) | TwentyCRM password for postgres database. | `string` | n/a | yes |
|
|
||||||
| <a name="input_twentycrm_app_name"></a> [twentycrm\_app\_name](#input\_twentycrm\_app\_name) | A friendly name prefix to use for every component deployed. | `string` | `"twentycrm"` | no |
|
|
||||||
| <a name="input_twentycrm_db_image"></a> [twentycrm\_db\_image](#input\_twentycrm\_db\_image) | TwentyCRM image for database deployment. This defaults to latest. | `string` | `"twentycrm/twenty-postgres-spilo:latest"` | no |
|
|
||||||
| <a name="input_twentycrm_db_pv_capacity"></a> [twentycrm\_db\_pv\_capacity](#input\_twentycrm\_db\_pv\_capacity) | Storage capacity provisioned for database persistent volume. | `string` | `"10Gi"` | no |
|
|
||||||
| <a name="input_twentycrm_db_pv_path"></a> [twentycrm\_db\_pv\_path](#input\_twentycrm\_db\_pv\_path) | Local path to use to store the physical volume if using local storage on nodes. | `string` | `""` | no |
|
|
||||||
| <a name="input_twentycrm_db_pvc_requests"></a> [twentycrm\_db\_pvc\_requests](#input\_twentycrm\_db\_pvc\_requests) | Storage capacity reservation for database persistent volume claim. | `string` | `"10Gi"` | no |
|
|
||||||
| <a name="input_twentycrm_db_replicas"></a> [twentycrm\_db\_replicas](#input\_twentycrm\_db\_replicas) | Number of replicas for the TwentyCRM database deployment. This defaults to 1. | `number` | `1` | no |
|
|
||||||
| <a name="input_twentycrm_docker_data_mount_path"></a> [twentycrm\_docker\_data\_mount\_path](#input\_twentycrm\_docker\_data\_mount\_path) | TwentyCRM mount path for servers application data. Defaults to '/app/docker-data'. | `string` | `"/app/docker-data"` | no |
|
|
||||||
| <a name="input_twentycrm_docker_data_pv_capacity"></a> [twentycrm\_docker\_data\_pv\_capacity](#input\_twentycrm\_docker\_data\_pv\_capacity) | Storage capacity provisioned for server persistent volume. | `string` | `"10Gi"` | no |
|
|
||||||
| <a name="input_twentycrm_docker_data_pv_path"></a> [twentycrm\_docker\_data\_pv\_path](#input\_twentycrm\_docker\_data\_pv\_path) | Local path to use to store the physical volume if using local storage on nodes. | `string` | `""` | no |
|
|
||||||
| <a name="input_twentycrm_docker_data_pvc_requests"></a> [twentycrm\_docker\_data\_pvc\_requests](#input\_twentycrm\_docker\_data\_pvc\_requests) | Storage capacity reservation for server persistent volume claim. | `string` | `"10Gi"` | no |
|
|
||||||
| <a name="input_twentycrm_namespace"></a> [twentycrm\_namespace](#input\_twentycrm\_namespace) | Namespace for all TwentyCRM resources | `string` | `"twentycrm"` | no |
|
|
||||||
| <a name="input_twentycrm_redis_image"></a> [twentycrm\_redis\_image](#input\_twentycrm\_redis\_image) | TwentyCRM image for Redis deployment. This defaults to latest. | `string` | `"redis/redis-stack-server:latest"` | no |
|
|
||||||
| <a name="input_twentycrm_redis_replicas"></a> [twentycrm\_redis\_replicas](#input\_twentycrm\_redis\_replicas) | Number of replicas for the TwentyCRM Redis deployment. This defaults to 1. | `number` | `1` | no |
|
|
||||||
| <a name="input_twentycrm_server_data_mount_path"></a> [twentycrm\_server\_data\_mount\_path](#input\_twentycrm\_server\_data\_mount\_path) | TwentyCRM mount path for servers application data. Defaults to '/app/packages/twenty-server/.local-storage'. | `string` | `"/app/packages/twenty-server/.local-storage"` | no |
|
|
||||||
| <a name="input_twentycrm_server_image"></a> [twentycrm\_server\_image](#input\_twentycrm\_server\_image) | TwentyCRM server image for the server deployment. This defaults to latest. This value is also used for the workers image. | `string` | `"twentycrm/twenty:latest"` | no |
|
|
||||||
| <a name="input_twentycrm_server_pv_capacity"></a> [twentycrm\_server\_pv\_capacity](#input\_twentycrm\_server\_pv\_capacity) | Storage capacity provisioned for server persistent volume. | `string` | `"10Gi"` | no |
|
|
||||||
| <a name="input_twentycrm_server_pv_path"></a> [twentycrm\_server\_pv\_path](#input\_twentycrm\_server\_pv\_path) | Local path to use to store the physical volume if using local storage on nodes. | `string` | `""` | no |
|
|
||||||
| <a name="input_twentycrm_server_pvc_requests"></a> [twentycrm\_server\_pvc\_requests](#input\_twentycrm\_server\_pvc\_requests) | Storage capacity reservation for server persistent volume claim. | `string` | `"10Gi"` | no |
|
|
||||||
| <a name="input_twentycrm_server_replicas"></a> [twentycrm\_server\_replicas](#input\_twentycrm\_server\_replicas) | Number of replicas for the TwentyCRM server deployment. This defaults to 1. | `number` | `1` | no |
|
|
||||||
| <a name="input_twentycrm_worker_replicas"></a> [twentycrm\_worker\_replicas](#input\_twentycrm\_worker\_replicas) | Number of replicas for the TwentyCRM worker deployment. This defaults to 1. | `number` | `1` | no |
|
|
||||||
<!-- END_TF_DOCS -->
|
|
||||||
@@ -1,87 +0,0 @@
|
|||||||
resource "kubernetes_deployment" "twentycrm_db" {
|
|
||||||
metadata {
|
|
||||||
name = "${var.twentycrm_app_name}-db"
|
|
||||||
namespace = kubernetes_namespace.twentycrm.metadata.0.name
|
|
||||||
labels = {
|
|
||||||
app = "${var.twentycrm_app_name}-db"
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
spec {
|
|
||||||
replicas = var.twentycrm_db_replicas
|
|
||||||
selector {
|
|
||||||
match_labels = {
|
|
||||||
app = "${var.twentycrm_app_name}-db"
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
strategy {
|
|
||||||
type = "RollingUpdate"
|
|
||||||
rolling_update {
|
|
||||||
max_surge = "1"
|
|
||||||
max_unavailable = "1"
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
template {
|
|
||||||
metadata {
|
|
||||||
labels = {
|
|
||||||
app = "${var.twentycrm_app_name}-db"
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
spec {
|
|
||||||
container {
|
|
||||||
image = var.twentycrm_db_image
|
|
||||||
name = var.twentycrm_app_name
|
|
||||||
stdin = true
|
|
||||||
tty = true
|
|
||||||
security_context {
|
|
||||||
allow_privilege_escalation = true
|
|
||||||
}
|
|
||||||
|
|
||||||
env {
|
|
||||||
name = "POSTGRES_PASSWORD"
|
|
||||||
value = var.twentycrm_pgdb_admin_password
|
|
||||||
}
|
|
||||||
env {
|
|
||||||
name = "BITNAMI_DEBUG"
|
|
||||||
value = true
|
|
||||||
}
|
|
||||||
|
|
||||||
port {
|
|
||||||
container_port = 5432
|
|
||||||
protocol = "TCP"
|
|
||||||
}
|
|
||||||
|
|
||||||
resources {
|
|
||||||
requests = {
|
|
||||||
cpu = "250m"
|
|
||||||
memory = "256Mi"
|
|
||||||
}
|
|
||||||
limits = {
|
|
||||||
cpu = "1000m"
|
|
||||||
memory = "1024Mi"
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
volume_mount {
|
|
||||||
name = "db-data"
|
|
||||||
mount_path = "/bitnami/postgresql"
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
volume {
|
|
||||||
name = "db-data"
|
|
||||||
|
|
||||||
persistent_volume_claim {
|
|
||||||
claim_name = kubernetes_persistent_volume_claim.db.metadata.0.name
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
dns_policy = "ClusterFirst"
|
|
||||||
restart_policy = "Always"
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
@@ -1,60 +0,0 @@
|
|||||||
resource "kubernetes_deployment" "twentycrm_redis" {
|
|
||||||
metadata {
|
|
||||||
name = "${var.twentycrm_app_name}-redis"
|
|
||||||
namespace = kubernetes_namespace.twentycrm.metadata.0.name
|
|
||||||
|
|
||||||
labels = {
|
|
||||||
app = "${var.twentycrm_app_name}-redis"
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
spec {
|
|
||||||
replicas = var.twentycrm_redis_replicas
|
|
||||||
selector {
|
|
||||||
match_labels = {
|
|
||||||
app = "${var.twentycrm_app_name}-redis"
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
strategy {
|
|
||||||
type = "RollingUpdate"
|
|
||||||
rolling_update {
|
|
||||||
max_surge = "1"
|
|
||||||
max_unavailable = "1"
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
template {
|
|
||||||
metadata {
|
|
||||||
labels = {
|
|
||||||
app = "${var.twentycrm_app_name}-redis"
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
spec {
|
|
||||||
container {
|
|
||||||
image = var.twentycrm_redis_image
|
|
||||||
name = "redis"
|
|
||||||
|
|
||||||
port {
|
|
||||||
container_port = 6379
|
|
||||||
protocol = "TCP"
|
|
||||||
}
|
|
||||||
|
|
||||||
resources {
|
|
||||||
requests = {
|
|
||||||
cpu = "250m"
|
|
||||||
memory = "1024Mi"
|
|
||||||
}
|
|
||||||
limits = {
|
|
||||||
cpu = "500m"
|
|
||||||
memory = "2048Mi"
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
dns_policy = "ClusterFirst"
|
|
||||||
restart_policy = "Always"
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
@@ -1,138 +0,0 @@
|
|||||||
resource "kubernetes_deployment" "twentycrm_server" {
|
|
||||||
metadata {
|
|
||||||
name = "${var.twentycrm_app_name}-server"
|
|
||||||
namespace = kubernetes_namespace.twentycrm.metadata.0.name
|
|
||||||
labels = {
|
|
||||||
app = "${var.twentycrm_app_name}-server"
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
spec {
|
|
||||||
replicas = var.twentycrm_server_replicas
|
|
||||||
selector {
|
|
||||||
match_labels = {
|
|
||||||
app = "${var.twentycrm_app_name}-server"
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
strategy {
|
|
||||||
type = "RollingUpdate"
|
|
||||||
rolling_update {
|
|
||||||
max_surge = "1"
|
|
||||||
max_unavailable = "1"
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
template {
|
|
||||||
metadata {
|
|
||||||
labels = {
|
|
||||||
app = "${var.twentycrm_app_name}-server"
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
spec {
|
|
||||||
container {
|
|
||||||
image = var.twentycrm_server_image
|
|
||||||
name = var.twentycrm_app_name
|
|
||||||
stdin = true
|
|
||||||
tty = true
|
|
||||||
|
|
||||||
env {
|
|
||||||
name = "NODE_PORT"
|
|
||||||
value = "3000"
|
|
||||||
}
|
|
||||||
|
|
||||||
env {
|
|
||||||
name = "SERVER_URL"
|
|
||||||
value = var.twentycrm_app_hostname
|
|
||||||
}
|
|
||||||
|
|
||||||
env {
|
|
||||||
name = "PG_DATABASE_URL"
|
|
||||||
value = "postgres://twenty:${var.twentycrm_pgdb_admin_password}@${kubernetes_service.twentycrm_db.metadata.0.name}.${kubernetes_namespace.twentycrm.metadata.0.name}.svc.cluster.local/default"
|
|
||||||
}
|
|
||||||
env {
|
|
||||||
name = "REDIS_URL"
|
|
||||||
value = "redis://${kubernetes_service.twentycrm_redis.metadata.0.name}.${kubernetes_namespace.twentycrm.metadata.0.name}.svc.cluster.local:6379"
|
|
||||||
}
|
|
||||||
env {
|
|
||||||
name = "DISABLE_DB_MIGRATIONS"
|
|
||||||
value = "false"
|
|
||||||
}
|
|
||||||
|
|
||||||
env {
|
|
||||||
name = "STORAGE_TYPE"
|
|
||||||
value = "local"
|
|
||||||
}
|
|
||||||
env {
|
|
||||||
name = "ACCESS_TOKEN_EXPIRES_IN"
|
|
||||||
value = "7d"
|
|
||||||
}
|
|
||||||
env {
|
|
||||||
name = "LOGIN_TOKEN_EXPIRES_IN"
|
|
||||||
value = "1h"
|
|
||||||
}
|
|
||||||
env {
|
|
||||||
name = "APP_SECRET"
|
|
||||||
value_from {
|
|
||||||
secret_key_ref {
|
|
||||||
name = "tokens"
|
|
||||||
key = "accessToken"
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
port {
|
|
||||||
container_port = 3000
|
|
||||||
protocol = "TCP"
|
|
||||||
}
|
|
||||||
|
|
||||||
resources {
|
|
||||||
requests = {
|
|
||||||
cpu = "250m"
|
|
||||||
memory = "256Mi"
|
|
||||||
}
|
|
||||||
limits = {
|
|
||||||
cpu = "1000m"
|
|
||||||
memory = "1024Mi"
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
volume_mount {
|
|
||||||
name = "server-data"
|
|
||||||
mount_path = var.twentycrm_server_data_mount_path
|
|
||||||
}
|
|
||||||
|
|
||||||
volume_mount {
|
|
||||||
name = "docker-data"
|
|
||||||
mount_path = var.twentycrm_docker_data_mount_path
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
volume {
|
|
||||||
name = "server-data"
|
|
||||||
|
|
||||||
persistent_volume_claim {
|
|
||||||
claim_name = kubernetes_persistent_volume_claim.server.metadata.0.name
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
volume {
|
|
||||||
name = "docker-data"
|
|
||||||
|
|
||||||
persistent_volume_claim {
|
|
||||||
claim_name = kubernetes_persistent_volume_claim.docker_data.metadata.0.name
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
dns_policy = "ClusterFirst"
|
|
||||||
restart_policy = "Always"
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
depends_on = [
|
|
||||||
kubernetes_deployment.twentycrm_db,
|
|
||||||
kubernetes_deployment.twentycrm_redis,
|
|
||||||
kubernetes_secret.twentycrm_tokens
|
|
||||||
]
|
|
||||||
}
|
|
||||||
@@ -1,99 +0,0 @@
|
|||||||
resource "kubernetes_deployment" "twentycrm_worker" {
|
|
||||||
metadata {
|
|
||||||
name = "${var.twentycrm_app_name}-worker"
|
|
||||||
namespace = kubernetes_namespace.twentycrm.metadata.0.name
|
|
||||||
labels = {
|
|
||||||
app = "${var.twentycrm_app_name}-worker"
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
spec {
|
|
||||||
replicas = var.twentycrm_worker_replicas
|
|
||||||
selector {
|
|
||||||
match_labels = {
|
|
||||||
app = "${var.twentycrm_app_name}-worker"
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
strategy {
|
|
||||||
type = "RollingUpdate"
|
|
||||||
rolling_update {
|
|
||||||
max_surge = "1"
|
|
||||||
max_unavailable = "1"
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
template {
|
|
||||||
metadata {
|
|
||||||
labels = {
|
|
||||||
app = "${var.twentycrm_app_name}-worker"
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
spec {
|
|
||||||
container {
|
|
||||||
image = var.twentycrm_server_image
|
|
||||||
name = var.twentycrm_app_name
|
|
||||||
stdin = true
|
|
||||||
tty = true
|
|
||||||
command = ["yarn", "worker:prod"]
|
|
||||||
|
|
||||||
env {
|
|
||||||
name = "SERVER_URL"
|
|
||||||
value = var.twentycrm_app_hostname
|
|
||||||
}
|
|
||||||
|
|
||||||
env {
|
|
||||||
name = "PG_DATABASE_URL"
|
|
||||||
value = "postgres://twenty:${var.twentycrm_pgdb_admin_password}@${kubernetes_service.twentycrm_db.metadata.0.name}.${kubernetes_namespace.twentycrm.metadata.0.name}.svc.cluster.local/default"
|
|
||||||
}
|
|
||||||
|
|
||||||
env {
|
|
||||||
name = "REDIS_URL"
|
|
||||||
value = "redis://${kubernetes_service.twentycrm_redis.metadata.0.name}.${kubernetes_namespace.twentycrm.metadata.0.name}.svc.cluster.local:6379"
|
|
||||||
}
|
|
||||||
|
|
||||||
env {
|
|
||||||
name = "DISABLE_DB_MIGRATIONS"
|
|
||||||
value = "true" #it already runs on the server
|
|
||||||
}
|
|
||||||
|
|
||||||
env {
|
|
||||||
name = "STORAGE_TYPE"
|
|
||||||
value = "local"
|
|
||||||
}
|
|
||||||
|
|
||||||
env {
|
|
||||||
name = "APP_SECRET"
|
|
||||||
value_from {
|
|
||||||
secret_key_ref {
|
|
||||||
name = "tokens"
|
|
||||||
key = "accessToken"
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
resources {
|
|
||||||
requests = {
|
|
||||||
cpu = "250m"
|
|
||||||
memory = "1024Mi"
|
|
||||||
}
|
|
||||||
limits = {
|
|
||||||
cpu = "1000m"
|
|
||||||
memory = "2048Mi"
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
dns_policy = "ClusterFirst"
|
|
||||||
restart_policy = "Always"
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
depends_on = [
|
|
||||||
kubernetes_deployment.twentycrm_db,
|
|
||||||
kubernetes_deployment.twentycrm_redis,
|
|
||||||
kubernetes_deployment.twentycrm_server,
|
|
||||||
kubernetes_secret.twentycrm_tokens,
|
|
||||||
]
|
|
||||||
}
|
|
||||||
@@ -1,30 +0,0 @@
|
|||||||
resource "kubernetes_ingress" "twentycrm" {
|
|
||||||
wait_for_load_balancer = true
|
|
||||||
metadata {
|
|
||||||
name = "${var.twentycrm_app_name}-ingress"
|
|
||||||
namespace = kubernetes_namespace.twentycrm.metadata.0.name
|
|
||||||
annotations = {
|
|
||||||
"kubernetes.io/ingress.class" = "nginx"
|
|
||||||
"nginx.ingress.kubernetes.io/configuration-snippet" = <<EOF
|
|
||||||
more_set_headers "X-Forwarded-For $http_x_forwarded_for";
|
|
||||||
EOF
|
|
||||||
"nginx.ingress.kubernetes.io/force-ssl-redirect" = "false"
|
|
||||||
"nginx.ingress.kubernetes.io/backend-protocol" = "HTTP"
|
|
||||||
}
|
|
||||||
}
|
|
||||||
spec {
|
|
||||||
ingress_class_name = "nginx"
|
|
||||||
rule {
|
|
||||||
host = var.twentycrm_app_hostname
|
|
||||||
http {
|
|
||||||
path {
|
|
||||||
path = "/*"
|
|
||||||
backend {
|
|
||||||
service_name = kubernetes_service.twentycrm_server.metadata.0.name
|
|
||||||
service_port = kubernetes_service.twentycrm_server.spec.0.port.0.port
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
@@ -1,23 +0,0 @@
|
|||||||
#############
|
|
||||||
# Providers #
|
|
||||||
#############
|
|
||||||
provider "kubernetes" {
|
|
||||||
config_path = "~/.kube/config"
|
|
||||||
}
|
|
||||||
|
|
||||||
####################
|
|
||||||
# Terraform Config #
|
|
||||||
####################
|
|
||||||
terraform {
|
|
||||||
required_version = ">= 1.9.2"
|
|
||||||
required_providers {
|
|
||||||
kubernetes = {
|
|
||||||
source = "hashicorp/kubernetes"
|
|
||||||
version = ">= 2.32.0"
|
|
||||||
}
|
|
||||||
random = {
|
|
||||||
source = "hashicorp/random"
|
|
||||||
version = ">= 3.6.3"
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
@@ -1,9 +0,0 @@
|
|||||||
resource "kubernetes_namespace" "twentycrm" {
|
|
||||||
metadata {
|
|
||||||
annotations = {
|
|
||||||
name = var.twentycrm_namespace
|
|
||||||
}
|
|
||||||
|
|
||||||
name = var.twentycrm_namespace
|
|
||||||
}
|
|
||||||
}
|
|
||||||
@@ -1,19 +0,0 @@
|
|||||||
resource "kubernetes_persistent_volume" "db" {
|
|
||||||
metadata {
|
|
||||||
name = "${var.twentycrm_app_name}-db-pv"
|
|
||||||
}
|
|
||||||
spec {
|
|
||||||
storage_class_name = "default"
|
|
||||||
capacity = {
|
|
||||||
storage = var.twentycrm_db_pv_capacity
|
|
||||||
}
|
|
||||||
access_modes = ["ReadWriteOnce"]
|
|
||||||
# refer to Terraform Docs for your specific implementation requirements
|
|
||||||
# https://registry.terraform.io/providers/hashicorp/kubernetes/latest/docs/resources/persistent_volume
|
|
||||||
persistent_volume_source {
|
|
||||||
local {
|
|
||||||
path = var.twentycrm_db_pv_path
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
@@ -1,19 +0,0 @@
|
|||||||
resource "kubernetes_persistent_volume" "docker_data" {
|
|
||||||
metadata {
|
|
||||||
name = "${var.twentycrm_app_name}-docker-data-pv"
|
|
||||||
}
|
|
||||||
spec {
|
|
||||||
storage_class_name = "default"
|
|
||||||
capacity = {
|
|
||||||
storage = var.twentycrm_docker_data_pv_capacity
|
|
||||||
}
|
|
||||||
access_modes = ["ReadWriteOnce"]
|
|
||||||
# refer to Terraform Docs for your specific implementation requirements
|
|
||||||
# https://registry.terraform.io/providers/hashicorp/kubernetes/latest/docs/resources/persistent_volume
|
|
||||||
persistent_volume_source {
|
|
||||||
local {
|
|
||||||
path = var.twentycrm_docker_data_pv_path
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
@@ -1,19 +0,0 @@
|
|||||||
resource "kubernetes_persistent_volume" "server" {
|
|
||||||
metadata {
|
|
||||||
name = "${var.twentycrm_app_name}-server-pv"
|
|
||||||
}
|
|
||||||
spec {
|
|
||||||
storage_class_name = "default"
|
|
||||||
capacity = {
|
|
||||||
storage = var.twentycrm_server_pv_capacity
|
|
||||||
}
|
|
||||||
access_modes = ["ReadWriteOnce"]
|
|
||||||
# refer to Terraform Docs for your specific implementation requirements
|
|
||||||
# https://registry.terraform.io/providers/hashicorp/kubernetes/latest/docs/resources/persistent_volume
|
|
||||||
persistent_volume_source {
|
|
||||||
local {
|
|
||||||
path = var.twentycrm_server_pv_path
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
@@ -1,15 +0,0 @@
|
|||||||
resource "kubernetes_persistent_volume_claim" "db" {
|
|
||||||
metadata {
|
|
||||||
name = "${var.twentycrm_app_name}-db-pvc"
|
|
||||||
namespace = kubernetes_namespace.twentycrm.metadata.0.name
|
|
||||||
}
|
|
||||||
spec {
|
|
||||||
access_modes = ["ReadWriteOnce"]
|
|
||||||
resources {
|
|
||||||
requests = {
|
|
||||||
storage = var.twentycrm_db_pvc_requests
|
|
||||||
}
|
|
||||||
}
|
|
||||||
volume_name = kubernetes_persistent_volume.db.metadata.0.name
|
|
||||||
}
|
|
||||||
}
|
|
||||||
@@ -1,15 +0,0 @@
|
|||||||
resource "kubernetes_persistent_volume_claim" "docker_data" {
|
|
||||||
metadata {
|
|
||||||
name = "${var.twentycrm_app_name}-docker-data-pvc"
|
|
||||||
namespace = kubernetes_namespace.twentycrm.metadata.0.name
|
|
||||||
}
|
|
||||||
spec {
|
|
||||||
access_modes = ["ReadWriteOnce"]
|
|
||||||
resources {
|
|
||||||
requests = {
|
|
||||||
storage = var.twentycrm_docker_data_pvc_requests
|
|
||||||
}
|
|
||||||
}
|
|
||||||
volume_name = kubernetes_persistent_volume.docker_data.metadata.0.name
|
|
||||||
}
|
|
||||||
}
|
|
||||||
@@ -1,15 +0,0 @@
|
|||||||
resource "kubernetes_persistent_volume_claim" "server" {
|
|
||||||
metadata {
|
|
||||||
name = "${var.twentycrm_app_name}-server-pvc"
|
|
||||||
namespace = kubernetes_namespace.twentycrm.metadata.0.name
|
|
||||||
}
|
|
||||||
spec {
|
|
||||||
access_modes = ["ReadWriteOnce"]
|
|
||||||
resources {
|
|
||||||
requests = {
|
|
||||||
storage = var.twentycrm_server_pvc_requests
|
|
||||||
}
|
|
||||||
}
|
|
||||||
volume_name = kubernetes_persistent_volume.server.metadata.0.name
|
|
||||||
}
|
|
||||||
}
|
|
||||||
@@ -1,28 +0,0 @@
|
|||||||
locals {
|
|
||||||
tokens = [
|
|
||||||
"accessToken",
|
|
||||||
"loginToken",
|
|
||||||
"refreshToken",
|
|
||||||
"fileToken"
|
|
||||||
]
|
|
||||||
}
|
|
||||||
|
|
||||||
resource "random_bytes" "this" {
|
|
||||||
for_each = toset(local.tokens)
|
|
||||||
|
|
||||||
length = 32
|
|
||||||
}
|
|
||||||
|
|
||||||
resource "kubernetes_secret" "twentycrm_tokens" {
|
|
||||||
metadata {
|
|
||||||
name = "tokens"
|
|
||||||
namespace = kubernetes_namespace.twentycrm.metadata.0.name
|
|
||||||
}
|
|
||||||
|
|
||||||
data = {
|
|
||||||
accessToken = random_bytes.this["accessToken"].base64
|
|
||||||
loginToken = random_bytes.this["loginToken"].base64
|
|
||||||
refreshToken = random_bytes.this["refreshToken"].base64
|
|
||||||
fileToken = random_bytes.this["fileToken"].base64
|
|
||||||
}
|
|
||||||
}
|
|
||||||
@@ -1,18 +0,0 @@
|
|||||||
resource "kubernetes_service" "twentycrm_db" {
|
|
||||||
metadata {
|
|
||||||
name = "${var.twentycrm_app_name}-db"
|
|
||||||
namespace = kubernetes_namespace.twentycrm.metadata.0.name
|
|
||||||
}
|
|
||||||
spec {
|
|
||||||
selector = {
|
|
||||||
app = "${var.twentycrm_app_name}-db"
|
|
||||||
}
|
|
||||||
session_affinity = "ClientIP"
|
|
||||||
port {
|
|
||||||
port = 5432
|
|
||||||
target_port = 5432
|
|
||||||
}
|
|
||||||
|
|
||||||
type = "ClusterIP"
|
|
||||||
}
|
|
||||||
}
|
|
||||||
@@ -1,18 +0,0 @@
|
|||||||
resource "kubernetes_service" "twentycrm_redis" {
|
|
||||||
metadata {
|
|
||||||
name = "${var.twentycrm_app_name}-redis"
|
|
||||||
namespace = kubernetes_namespace.twentycrm.metadata.0.name
|
|
||||||
}
|
|
||||||
spec {
|
|
||||||
selector = {
|
|
||||||
app = "${var.twentycrm_app_name}-redis"
|
|
||||||
}
|
|
||||||
session_affinity = "ClientIP"
|
|
||||||
port {
|
|
||||||
port = 6379
|
|
||||||
target_port = 6379
|
|
||||||
}
|
|
||||||
|
|
||||||
type = "ClusterIP"
|
|
||||||
}
|
|
||||||
}
|
|
||||||
@@ -1,19 +0,0 @@
|
|||||||
resource "kubernetes_service" "twentycrm_server" {
|
|
||||||
metadata {
|
|
||||||
name = "${var.twentycrm_app_name}-server"
|
|
||||||
namespace = kubernetes_namespace.twentycrm.metadata.0.name
|
|
||||||
}
|
|
||||||
spec {
|
|
||||||
selector = {
|
|
||||||
app = "${var.twentycrm_app_name}-server"
|
|
||||||
}
|
|
||||||
session_affinity = "ClientIP"
|
|
||||||
port {
|
|
||||||
name = "http-tcp"
|
|
||||||
port = 3000
|
|
||||||
target_port = 3000
|
|
||||||
}
|
|
||||||
|
|
||||||
type = "ClusterIP"
|
|
||||||
}
|
|
||||||
}
|
|
||||||
@@ -1,136 +0,0 @@
|
|||||||
######################
|
|
||||||
# Required Variables #
|
|
||||||
######################
|
|
||||||
variable "twentycrm_pgdb_admin_password" {
|
|
||||||
type = string
|
|
||||||
description = "TwentyCRM password for postgres database."
|
|
||||||
sensitive = true
|
|
||||||
}
|
|
||||||
|
|
||||||
variable "twentycrm_app_hostname" {
|
|
||||||
type = string
|
|
||||||
description = "The protocol, DNS fully qualified hostname, and port used to access TwentyCRM in your environment. Ex: https://crm.example.com:443"
|
|
||||||
}
|
|
||||||
|
|
||||||
######################
|
|
||||||
# Optional Variables #
|
|
||||||
######################
|
|
||||||
variable "twentycrm_app_name" {
|
|
||||||
type = string
|
|
||||||
default = "twentycrm"
|
|
||||||
description = "A friendly name prefix to use for every component deployed."
|
|
||||||
}
|
|
||||||
|
|
||||||
variable "twentycrm_server_image" {
|
|
||||||
type = string
|
|
||||||
default = "twentycrm/twenty:latest"
|
|
||||||
description = "TwentyCRM server image for the server deployment. This defaults to latest. This value is also used for the workers image."
|
|
||||||
}
|
|
||||||
|
|
||||||
variable "twentycrm_db_image" {
|
|
||||||
type = string
|
|
||||||
default = "twentycrm/twenty-postgres-spilo:latest"
|
|
||||||
description = "TwentyCRM image for database deployment. This defaults to latest."
|
|
||||||
}
|
|
||||||
|
|
||||||
variable "twentycrm_server_replicas" {
|
|
||||||
type = number
|
|
||||||
default = 1
|
|
||||||
description = "Number of replicas for the TwentyCRM server deployment. This defaults to 1."
|
|
||||||
}
|
|
||||||
|
|
||||||
variable "twentycrm_worker_replicas" {
|
|
||||||
type = number
|
|
||||||
default = 1
|
|
||||||
description = "Number of replicas for the TwentyCRM worker deployment. This defaults to 1."
|
|
||||||
}
|
|
||||||
|
|
||||||
variable "twentycrm_db_replicas" {
|
|
||||||
type = number
|
|
||||||
default = 1
|
|
||||||
description = "Number of replicas for the TwentyCRM database deployment. This defaults to 1."
|
|
||||||
}
|
|
||||||
|
|
||||||
variable "twentycrm_server_data_mount_path" {
|
|
||||||
type = string
|
|
||||||
default = "/app/packages/twenty-server/.local-storage"
|
|
||||||
description = "TwentyCRM mount path for servers application data. Defaults to '/app/packages/twenty-server/.local-storage'."
|
|
||||||
}
|
|
||||||
|
|
||||||
variable "twentycrm_db_pv_path" {
|
|
||||||
type = string
|
|
||||||
default = ""
|
|
||||||
description = "Local path to use to store the physical volume if using local storage on nodes."
|
|
||||||
}
|
|
||||||
|
|
||||||
variable "twentycrm_server_pv_path" {
|
|
||||||
type = string
|
|
||||||
default = ""
|
|
||||||
description = "Local path to use to store the physical volume if using local storage on nodes."
|
|
||||||
}
|
|
||||||
|
|
||||||
variable "twentycrm_db_pv_capacity" {
|
|
||||||
type = string
|
|
||||||
default = "10Gi"
|
|
||||||
description = "Storage capacity provisioned for database persistent volume."
|
|
||||||
}
|
|
||||||
|
|
||||||
variable "twentycrm_db_pvc_requests" {
|
|
||||||
type = string
|
|
||||||
default = "10Gi"
|
|
||||||
description = "Storage capacity reservation for database persistent volume claim."
|
|
||||||
}
|
|
||||||
|
|
||||||
variable "twentycrm_server_pv_capacity" {
|
|
||||||
type = string
|
|
||||||
default = "10Gi"
|
|
||||||
description = "Storage capacity provisioned for server persistent volume."
|
|
||||||
}
|
|
||||||
|
|
||||||
variable "twentycrm_server_pvc_requests" {
|
|
||||||
type = string
|
|
||||||
default = "10Gi"
|
|
||||||
description = "Storage capacity reservation for server persistent volume claim."
|
|
||||||
}
|
|
||||||
|
|
||||||
variable "twentycrm_namespace" {
|
|
||||||
type = string
|
|
||||||
default = "twentycrm"
|
|
||||||
description = "Namespace for all TwentyCRM resources"
|
|
||||||
}
|
|
||||||
|
|
||||||
variable "twentycrm_redis_replicas" {
|
|
||||||
type = number
|
|
||||||
default = 1
|
|
||||||
description = "Number of replicas for the TwentyCRM Redis deployment. This defaults to 1."
|
|
||||||
}
|
|
||||||
|
|
||||||
variable "twentycrm_redis_image" {
|
|
||||||
type = string
|
|
||||||
default = "redis/redis-stack-server:latest"
|
|
||||||
description = "TwentyCRM image for Redis deployment. This defaults to latest."
|
|
||||||
}
|
|
||||||
|
|
||||||
variable "twentycrm_docker_data_mount_path" {
|
|
||||||
type = string
|
|
||||||
default = "/app/docker-data"
|
|
||||||
description = "TwentyCRM mount path for servers application data. Defaults to '/app/docker-data'."
|
|
||||||
}
|
|
||||||
|
|
||||||
variable "twentycrm_docker_data_pv_path" {
|
|
||||||
type = string
|
|
||||||
default = ""
|
|
||||||
description = "Local path to use to store the physical volume if using local storage on nodes."
|
|
||||||
}
|
|
||||||
|
|
||||||
variable "twentycrm_docker_data_pv_capacity" {
|
|
||||||
type = string
|
|
||||||
default = "100Mi"
|
|
||||||
description = "Storage capacity provisioned for server persistent volume."
|
|
||||||
}
|
|
||||||
|
|
||||||
variable "twentycrm_docker_data_pvc_requests" {
|
|
||||||
type = string
|
|
||||||
default = "100Mi"
|
|
||||||
description = "Storage capacity reservation for server persistent volume claim."
|
|
||||||
}
|
|
||||||
@@ -1,24 +0,0 @@
|
|||||||
receivers:
|
|
||||||
otlp:
|
|
||||||
protocols:
|
|
||||||
http:
|
|
||||||
endpoint: "0.0.0.0:4318"
|
|
||||||
|
|
||||||
exporters:
|
|
||||||
clickhouse:
|
|
||||||
endpoint: tcp://twenty_clickhouse:9000
|
|
||||||
database: twenty_dev
|
|
||||||
username: default
|
|
||||||
password: devPassword
|
|
||||||
debug:
|
|
||||||
verbosity: detailed
|
|
||||||
|
|
||||||
processors:
|
|
||||||
batch:
|
|
||||||
|
|
||||||
service:
|
|
||||||
pipelines:
|
|
||||||
metrics:
|
|
||||||
receivers: [otlp]
|
|
||||||
processors: [batch]
|
|
||||||
exporters: [clickhouse, debug]
|
|
||||||
@@ -1,48 +0,0 @@
|
|||||||
# How to deploy twenty on podman
|
|
||||||
|
|
||||||
DISCLAIMER: The k8s and podman deployments are not maintained by the core team.
|
|
||||||
These files are provided and maintained by the community. Twenty core team
|
|
||||||
maintains support for docker deployment.
|
|
||||||
|
|
||||||
|
|
||||||
## How to use
|
|
||||||
|
|
||||||
1. Edit `.env` file. At the minimum set `POSTGRES_PASSWORD`, `SERVER_URL`, and `APP_SECRET`.
|
|
||||||
2. Start twenty by running `podman-compose up -d`.
|
|
||||||
|
|
||||||
If you need to stop twenty, you can do so by running `podman-compose down`.
|
|
||||||
|
|
||||||
|
|
||||||
### Install systemd service (optional)
|
|
||||||
|
|
||||||
If you want to install a systemd service to run twenty, you can use the provided systemd service.
|
|
||||||
|
|
||||||
Edit `twentycrm.service` and change these two variables:
|
|
||||||
|
|
||||||
|
|
||||||
WorkingDirectory=/opt/apps/twenty
|
|
||||||
EnvironmentFile=/opt/apps/twenty/.env
|
|
||||||
|
|
||||||
`WorkingDirectory` should be changed to the path in which `podman-compose.yml` is located.
|
|
||||||
|
|
||||||
`EnvironmentFile` should be changed to the path in which your `.env`file is located.
|
|
||||||
|
|
||||||
You can run the script `install-systemd-user-service` to install the systemd service under the current user.
|
|
||||||
|
|
||||||
|
|
||||||
./install-systemd-user-service
|
|
||||||
|
|
||||||
Note: this script will enable the service and also start it. So it will assume that twenty is not currently running.
|
|
||||||
If you started it previously, bring it down using:
|
|
||||||
|
|
||||||
podman-compose down
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
## Compatibility
|
|
||||||
|
|
||||||
These files should be compatible with podman 4.3+.
|
|
||||||
|
|
||||||
I have tested this on Debian GNU/Linux 12 (bookworm) and with the podman that is distributed with the official Debian stable mirrors (podman v4.3.1+ds1-8+deb12u1, podman-compose v1.0.3-3).
|
|
||||||
|
|
||||||
|
|
||||||
@@ -1,11 +0,0 @@
|
|||||||
#!/bin/bash
|
|
||||||
set -e
|
|
||||||
|
|
||||||
mkdir -p ~/.config/systemd/user
|
|
||||||
[ -f twentycrm.service ] || { echo "Error: twentycrm.service not found"; exit 1; }
|
|
||||||
cp twentycrm.service ~/.config/systemd/user
|
|
||||||
|
|
||||||
|
|
||||||
systemctl --user daemon-reload
|
|
||||||
systemctl --user enable twentycrm.service
|
|
||||||
systemctl --user start twentycrm.service
|
|
||||||
@@ -1,71 +0,0 @@
|
|||||||
#!/bin/bash
|
|
||||||
set -e
|
|
||||||
if [ ! -f "$(dirname "$0")/.env" ]; then
|
|
||||||
echo "Error: .env file not found"
|
|
||||||
exit 1
|
|
||||||
fi
|
|
||||||
source "$(dirname "$0")/.env"
|
|
||||||
|
|
||||||
## steps to cleanup and start over from scratch - useful when testing
|
|
||||||
#podman pod stop twenty-pod
|
|
||||||
#podman pod rm twenty-pod
|
|
||||||
#podman volume rm twenty-db-data twenty-server-data twenty-redis-data
|
|
||||||
# end of cleanup
|
|
||||||
|
|
||||||
podman volume create twenty-db-data
|
|
||||||
podman volume create twenty-server-data
|
|
||||||
podman volume create twenty-redis-data
|
|
||||||
|
|
||||||
podman pod create --name twenty-pod -p 127.0.0.1:8080:3000
|
|
||||||
|
|
||||||
podman run -d --pod twenty-pod --name twenty-db \
|
|
||||||
-e POSTGRES_DB=twenty \
|
|
||||||
-e POSTGRES_USER=twenty \
|
|
||||||
-e POSTGRES_PASSWORD="$POSTGRES_PASSWORD" \
|
|
||||||
-v twenty-db-data:/var/lib/postgresql/data:Z \
|
|
||||||
docker.io/library/postgres:16
|
|
||||||
|
|
||||||
podman run -d --pod twenty-pod --name twenty-redis \
|
|
||||||
-v twenty-redis-data:/data:Z \
|
|
||||||
docker.io/library/redis:latest
|
|
||||||
|
|
||||||
podman run -d --pod twenty-pod --name twenty-server \
|
|
||||||
-e NODE_PORT=3000 \
|
|
||||||
-e SERVER_URL="$SERVER_URL" \
|
|
||||||
-e PG_DATABASE_URL="postgresql://twenty:$POSTGRES_PASSWORD@twenty-db:5432/twenty" \
|
|
||||||
-e REDIS_URL="redis://twenty-redis:6379" \
|
|
||||||
-e APP_SECRET="$APP_SECRET" \
|
|
||||||
-e NODE_ENV=production \
|
|
||||||
-e LOG_LEVEL=info \
|
|
||||||
-v twenty-server-data:/app/docker-data:Z \
|
|
||||||
docker.io/twentycrm/twenty:latest
|
|
||||||
|
|
||||||
podman run -d --pod twenty-pod --name twenty-worker \
|
|
||||||
--init \
|
|
||||||
-e SERVER_URL="$SERVER_URL" \
|
|
||||||
-e PG_DATABASE_URL="postgresql://twenty:$POSTGRES_PASSWORD@twenty-db:5432/twenty" \
|
|
||||||
-e REDIS_URL="redis://twenty-redis:6379" \
|
|
||||||
-e APP_SECRET="$APP_SECRET" \
|
|
||||||
-e DISABLE_DB_MIGRATIONS=true \
|
|
||||||
-e NODE_ENV=production \
|
|
||||||
-e LOG_LEVEL=info \
|
|
||||||
-v twenty-server-data:/app/docker-data:Z \
|
|
||||||
docker.io/twentycrm/twenty:latest \
|
|
||||||
yarn worker:prod
|
|
||||||
|
|
||||||
# wait some time, check status
|
|
||||||
sleep 30
|
|
||||||
podman ps --pod -f name=twenty-pod
|
|
||||||
|
|
||||||
|
|
||||||
mkdir -p ~/.config/systemd/user
|
|
||||||
if [ ! -f "twentycrm.service" ]; then
|
|
||||||
echo "Error: twentycrm.service file not found"
|
|
||||||
exit 1
|
|
||||||
fi
|
|
||||||
cp twentycrm.service ~/.config/systemd/user
|
|
||||||
|
|
||||||
systemctl --user daemon-reload
|
|
||||||
systemctl --user enable twentycrm.service
|
|
||||||
systemctl --user start twentycrm.service
|
|
||||||
|
|
||||||
@@ -1,56 +0,0 @@
|
|||||||
version: "3.8"
|
|
||||||
|
|
||||||
services:
|
|
||||||
db:
|
|
||||||
container_name: twenty-db
|
|
||||||
image: postgres:16
|
|
||||||
environment:
|
|
||||||
POSTGRES_DB: twenty
|
|
||||||
POSTGRES_USER: twenty
|
|
||||||
POSTGRES_PASSWORD: ${PG_DATABASE_PASSWORD}
|
|
||||||
volumes:
|
|
||||||
- twenty-db-data:/var/lib/postgresql/data:Z
|
|
||||||
|
|
||||||
redis:
|
|
||||||
container_name: twenty-redis
|
|
||||||
image: redis:latest
|
|
||||||
command: ["--maxmemory-policy", "noeviction"]
|
|
||||||
volumes:
|
|
||||||
- twenty-redis-data:/data:Z
|
|
||||||
|
|
||||||
server:
|
|
||||||
container_name: twenty-server
|
|
||||||
image: twentycrm/twenty:latest
|
|
||||||
environment:
|
|
||||||
NODE_PORT: "3000"
|
|
||||||
SERVER_URL: ${SERVER_URL}
|
|
||||||
PG_DATABASE_URL: "postgresql://twenty:${PG_DATABASE_PASSWORD}@twenty-db:5432/twenty"
|
|
||||||
REDIS_URL: "redis://twenty-redis:6379"
|
|
||||||
APP_SECRET: ${APP_SECRET}
|
|
||||||
NODE_ENV: production
|
|
||||||
LOG_LEVEL: info
|
|
||||||
volumes:
|
|
||||||
- twenty-server-data:/app/docker-data:Z
|
|
||||||
ports:
|
|
||||||
- 127.0.0.1:8080:3000
|
|
||||||
|
|
||||||
worker:
|
|
||||||
container_name: twenty-worker
|
|
||||||
image: twentycrm/twenty:latest
|
|
||||||
command: yarn worker:prod
|
|
||||||
environment:
|
|
||||||
SERVER_URL: ${SERVER_URL}
|
|
||||||
PG_DATABASE_URL: "postgresql://twenty:${PG_DATABASE_PASSWORD}@twenty-db:5432/twenty"
|
|
||||||
REDIS_URL: "redis://twenty-redis:6379"
|
|
||||||
APP_SECRET: ${APP_SECRET}
|
|
||||||
DISABLE_DB_MIGRATIONS: "true"
|
|
||||||
NODE_ENV: production
|
|
||||||
LOG_LEVEL: info
|
|
||||||
volumes:
|
|
||||||
- twenty-server-data:/app/docker-data:Z
|
|
||||||
init: true
|
|
||||||
|
|
||||||
volumes:
|
|
||||||
twenty-db-data:
|
|
||||||
twenty-server-data:
|
|
||||||
twenty-redis-data:
|
|
||||||
@@ -1,15 +0,0 @@
|
|||||||
[Unit]
|
|
||||||
Description=TwentyCRM Container Stack via Podman-Compose
|
|
||||||
After=network.target
|
|
||||||
|
|
||||||
[Service]
|
|
||||||
Type=simple
|
|
||||||
WorkingDirectory=/opt/apps/twenty
|
|
||||||
EnvironmentFile=/opt/apps/twenty/.env
|
|
||||||
ExecStart=/usr/bin/podman-compose -f podman-compose.yml up -d
|
|
||||||
ExecStop=/usr/bin/podman-compose -f podman-compose.yml down
|
|
||||||
RemainAfterExit=yes
|
|
||||||
|
|
||||||
[Install]
|
|
||||||
WantedBy=default.target
|
|
||||||
|
|
||||||
@@ -1,22 +0,0 @@
|
|||||||
pull_version=${VERSION:-$(curl -s https://api.github.com/repos/twentyhq/twenty/tags | grep '"name":' | head -n 1 | cut -d '"' -f 4)}
|
|
||||||
|
|
||||||
if [[ -z "$pull_version" ]]; then
|
|
||||||
echo "Error: Unable to fetch the latest version tag. Please check your network connection or the GitHub API response."
|
|
||||||
exit 1
|
|
||||||
fi
|
|
||||||
pull_branch=${BRANCH:-$pull_version}
|
|
||||||
|
|
||||||
version_num=${pull_version#v}
|
|
||||||
target_version="0.32.4"
|
|
||||||
|
|
||||||
# We moved the install script to a different location in v0.32.4
|
|
||||||
if [[ -n "$BRANCH" ]] || [[ "$(printf '%s\n' "$target_version" "$version_num" | sort -V | head -n1)" != "$version_num" ]]; then
|
|
||||||
curl -sL "https://raw.githubusercontent.com/twentyhq/twenty/$pull_branch/packages/twenty-docker/scripts/install.sh" -o twenty_install.sh
|
|
||||||
else
|
|
||||||
curl -sL "https://raw.githubusercontent.com/twentyhq/twenty/$pull_branch/install.sh" -o twenty_install.sh
|
|
||||||
fi
|
|
||||||
|
|
||||||
chmod +x twenty_install.sh
|
|
||||||
VERSION="$VERSION" BRANCH="$BRANCH" ./twenty_install.sh
|
|
||||||
|
|
||||||
rm twenty_install.sh
|
|
||||||
@@ -1,167 +0,0 @@
|
|||||||
#!/bin/bash
|
|
||||||
|
|
||||||
echo "🔧 Checking dependencies..."
|
|
||||||
if ! command -v docker &>/dev/null; then
|
|
||||||
echo -e "\t❌ Docker is not installed or not in PATH. Please install Docker first.\n\t\tSee https://docs.docker.com/get-docker/"
|
|
||||||
exit 1
|
|
||||||
fi
|
|
||||||
# Check if docker compose plugin is installed
|
|
||||||
if ! docker compose version &>/dev/null; then
|
|
||||||
echo -e "\t❌ Docker Compose is not installed or not in PATH (n.b. docker-compose is deprecated)\n\t\tUpdate docker or install docker-compose-plugin\n\t\tOn Linux: sudo apt-get install docker-compose-plugin\n\t\tSee https://docs.docker.com/compose/install/"
|
|
||||||
exit 1
|
|
||||||
fi
|
|
||||||
# Check if docker is started
|
|
||||||
if ! docker info &>/dev/null; then
|
|
||||||
echo -e "\t❌ Docker is not running.\n\t\tPlease start Docker Desktop, Docker or check documentation at https://docs.docker.com/config/daemon/start/"
|
|
||||||
exit 1
|
|
||||||
fi
|
|
||||||
if ! command -v curl &>/dev/null; then
|
|
||||||
echo -e "\t❌ Curl is not installed or not in PATH.\n\t\tOn macOS: brew install curl\n\t\tOn Linux: sudo apt install curl"
|
|
||||||
exit 1
|
|
||||||
fi
|
|
||||||
|
|
||||||
# Check if docker compose version is >= 2
|
|
||||||
if [ "$(docker compose version --short | cut -d' ' -f3 | cut -d'.' -f1)" -lt 2 ]; then
|
|
||||||
echo -e "\t❌ Docker Compose is outdated. Please update Docker Compose to version 2 or higher.\n\t\tSee https://docs.docker.com/compose/install/linux/"
|
|
||||||
exit 1
|
|
||||||
fi
|
|
||||||
# Check if docker-compose is installed, if so issue a warning if version is < 2
|
|
||||||
if command -v docker-compose &>/dev/null; then
|
|
||||||
if [ "$(docker-compose version --short | cut -d' ' -f3 | cut -d'.' -f1)" -lt 2 ]; then
|
|
||||||
echo -e "\n\t⚠️ 'docker-compose' is installed but outdated. Make sure to use 'docker compose' or to upgrade 'docker-compose' to version 2.\n\t\tSee https://docs.docker.com/compose/install/standalone/\n"
|
|
||||||
fi
|
|
||||||
fi
|
|
||||||
|
|
||||||
# Catch errors
|
|
||||||
set -e
|
|
||||||
function on_exit {
|
|
||||||
# $? is the exit status of the last command executed
|
|
||||||
local exit_status=$?
|
|
||||||
if [ $exit_status -ne 0 ]; then
|
|
||||||
echo "❌ Something went wrong, exiting: $exit_status"
|
|
||||||
fi
|
|
||||||
}
|
|
||||||
trap on_exit EXIT
|
|
||||||
|
|
||||||
# Use environment variables VERSION and BRANCH, with defaults if not set
|
|
||||||
version=${VERSION:-$(curl -s "https://hub.docker.com/v2/repositories/twentycrm/twenty/tags" | grep -o '"name":"[^"]*"' | grep -v 'latest' | cut -d'"' -f4 | sort -V | tail -n1)}
|
|
||||||
branch=${BRANCH:-$(curl -s https://api.github.com/repos/twentyhq/twenty/tags | grep '"name":' | head -n 1 | cut -d '"' -f 4)}
|
|
||||||
|
|
||||||
echo "🚀 Using docker version $version and Github branch $branch"
|
|
||||||
|
|
||||||
dir_name="twenty"
|
|
||||||
function ask_directory {
|
|
||||||
read -p "📁 Enter the directory name to setup the project (default: $dir_name): " answer
|
|
||||||
if [ -n "$answer" ]; then
|
|
||||||
dir_name=$answer
|
|
||||||
fi
|
|
||||||
}
|
|
||||||
|
|
||||||
ask_directory
|
|
||||||
|
|
||||||
while [ -d "$dir_name" ]; do
|
|
||||||
read -p "🚫 Directory '$dir_name' already exists. Do you want to overwrite it? (y/N) " answer
|
|
||||||
if [ "$answer" = "y" ]; then
|
|
||||||
break
|
|
||||||
else
|
|
||||||
ask_directory
|
|
||||||
fi
|
|
||||||
done
|
|
||||||
|
|
||||||
# Create a directory named twenty
|
|
||||||
echo "📁 Creating directory '$dir_name'"
|
|
||||||
mkdir -p "$dir_name" && cd "$dir_name" || { echo "❌ Failed to create/access directory '$dir_name'"; exit 1; }
|
|
||||||
|
|
||||||
# Copy twenty/packages/twenty-docker/docker-compose.yml in it
|
|
||||||
echo -e "\t• Copying docker-compose.yml"
|
|
||||||
curl -sLo docker-compose.yml https://raw.githubusercontent.com/twentyhq/twenty/$branch/packages/twenty-docker/docker-compose.yml
|
|
||||||
|
|
||||||
# Copy twenty/packages/twenty-docker/.env.example to .env
|
|
||||||
echo -e "\t• Setting up .env file"
|
|
||||||
curl -sLo .env https://raw.githubusercontent.com/twentyhq/twenty/$branch/packages/twenty-docker/.env.example
|
|
||||||
|
|
||||||
# Replace TAG=latest by TAG=<latest_release or version input>
|
|
||||||
if [[ $(uname) == "Darwin" ]]; then
|
|
||||||
# Running on macOS
|
|
||||||
sed -i '' "s/TAG=latest/TAG=$version/g" .env
|
|
||||||
else
|
|
||||||
# Assuming Linux
|
|
||||||
sed -i'' "s/TAG=latest/TAG=$version/g" .env
|
|
||||||
fi
|
|
||||||
|
|
||||||
# Generate random strings for secrets
|
|
||||||
echo "# === Randomly generated secret ===" >> .env
|
|
||||||
echo "APP_SECRET=$(openssl rand -base64 32)" >> .env
|
|
||||||
|
|
||||||
echo "" >> .env
|
|
||||||
echo "PG_DATABASE_PASSWORD=$(openssl rand -hex 32)" >> .env
|
|
||||||
|
|
||||||
echo -e "\t• .env configuration completed"
|
|
||||||
|
|
||||||
port=3000
|
|
||||||
# Check if command nc is available
|
|
||||||
if command -v nc &> /dev/null; then
|
|
||||||
# Check if port 3000 is already in use, propose to change it
|
|
||||||
while nc -zv localhost $port &>/dev/null; do
|
|
||||||
read -p "🚫 Port $port is already in use. Do you want to use another port? (Y/n) " answer
|
|
||||||
if [ "$answer" = "n" ]; then
|
|
||||||
continue
|
|
||||||
fi
|
|
||||||
read -p "Enter a new port number: " new_port
|
|
||||||
if [[ $(uname) == "Darwin" ]]; then
|
|
||||||
sed -i '' "s/$port:$port/$new_port:$port/g" docker-compose.yml
|
|
||||||
sed -E -i '' "s|^SERVER_URL=http://localhost:[0-9]+|SERVER_URL=http://localhost:$new_port|g" .env
|
|
||||||
else
|
|
||||||
sed -i'' "s/$port:$port/$new_port:$port/g" docker-compose.yml
|
|
||||||
sed -E -i'' "s|^SERVER_URL=http://localhost:[0-9]+|SERVER_URL=http://localhost:$new_port|g" .env
|
|
||||||
fi
|
|
||||||
port=$new_port
|
|
||||||
done
|
|
||||||
fi
|
|
||||||
|
|
||||||
# Ask user if they want to start the project
|
|
||||||
read -p "🚀 Do you want to start the project now? (Y/n) " answer
|
|
||||||
if [ "$answer" = "n" ]; then
|
|
||||||
echo "✅ Project setup completed. Run 'docker compose up -d' to start."
|
|
||||||
exit 0
|
|
||||||
else
|
|
||||||
echo "🐳 Starting Docker containers..."
|
|
||||||
docker compose up -d
|
|
||||||
# Check if port is listening
|
|
||||||
echo "Waiting for server to be healthy, it might take a few minutes while we initialize the database..."
|
|
||||||
# Tail logs of the server until it's ready
|
|
||||||
docker compose logs -f server &
|
|
||||||
pid=$!
|
|
||||||
while [ ! $(docker inspect --format='{{.State.Health.Status}}' twenty-server-1) = "healthy" ]; do
|
|
||||||
sleep 1
|
|
||||||
done
|
|
||||||
kill $pid
|
|
||||||
echo ""
|
|
||||||
echo "✅ Server is up and running"
|
|
||||||
fi
|
|
||||||
|
|
||||||
function ask_open_browser {
|
|
||||||
read -p "🌐 Do you want to open the project in your browser? (Y/n) " answer
|
|
||||||
if [ "$answer" = "n" ]; then
|
|
||||||
echo "✅ Setup completed. Access your project at http://localhost:$port"
|
|
||||||
exit 0
|
|
||||||
fi
|
|
||||||
}
|
|
||||||
|
|
||||||
# Ask user if they want to open the project
|
|
||||||
# Running on macOS
|
|
||||||
if [[ $(uname) == "Darwin" ]]; then
|
|
||||||
ask_open_browser
|
|
||||||
|
|
||||||
open "http://localhost:$port"
|
|
||||||
# Assuming Linux
|
|
||||||
else
|
|
||||||
# xdg-open is not installed, we could be running in a non gui environment
|
|
||||||
if command -v xdg-open >/dev/null 2>&1; then
|
|
||||||
ask_open_browser
|
|
||||||
|
|
||||||
xdg-open "http://localhost:$port"
|
|
||||||
else
|
|
||||||
echo "✅ Setup completed. Your project is available at http://localhost:$port"
|
|
||||||
fi
|
|
||||||
fi
|
|
||||||
@@ -1,68 +0,0 @@
|
|||||||
ARG POSTGRES_VERSION=15
|
|
||||||
ARG SPILO_VERSION=3.2-p1
|
|
||||||
ARG WRAPPERS_VERSION=0.2.0
|
|
||||||
|
|
||||||
# Build the mysql_fdw extension
|
|
||||||
FROM debian:bookworm AS build-mysql_fdw
|
|
||||||
ARG POSTGRES_VERSION
|
|
||||||
|
|
||||||
ENV DEBIAN_FRONTEND=noninteractive
|
|
||||||
RUN apt update && \
|
|
||||||
apt install -y \
|
|
||||||
build-essential \
|
|
||||||
git \
|
|
||||||
postgresql-server-dev-${POSTGRES_VERSION} \
|
|
||||||
default-libmysqlclient-dev && \
|
|
||||||
rm -rf /var/lib/apt/lists/*
|
|
||||||
|
|
||||||
# Install mysql_fdw
|
|
||||||
RUN git clone https://github.com/EnterpriseDB/mysql_fdw.git
|
|
||||||
WORKDIR /mysql_fdw
|
|
||||||
RUN make USE_PGXS=1
|
|
||||||
|
|
||||||
|
|
||||||
# Build libssl for wrappers
|
|
||||||
FROM ubuntu:22.04 AS build-libssl
|
|
||||||
|
|
||||||
ENV DEBIAN_FRONTEND=noninteractive
|
|
||||||
RUN apt update && \
|
|
||||||
apt install -y \
|
|
||||||
build-essential \
|
|
||||||
git && \
|
|
||||||
rm -rf /var/lib/apt/lists/*
|
|
||||||
|
|
||||||
WORKDIR /build
|
|
||||||
RUN git clone --branch OpenSSL_1_1_1-stable https://github.com/openssl/openssl.git
|
|
||||||
WORKDIR /build/openssl
|
|
||||||
RUN ./config && make && make install
|
|
||||||
|
|
||||||
|
|
||||||
# Extend the Spilo image with the mysql_fdw extensions
|
|
||||||
FROM ghcr.io/zalando/spilo-${POSTGRES_VERSION}:${SPILO_VERSION}
|
|
||||||
ARG POSTGRES_VERSION
|
|
||||||
ARG WRAPPERS_VERSION
|
|
||||||
ARG TARGETARCH
|
|
||||||
|
|
||||||
# Install precompiled supabase wrappers extensions
|
|
||||||
RUN set -eux; \
|
|
||||||
ARCH="$(dpkg --print-architecture)"; \
|
|
||||||
case "${ARCH}" in \
|
|
||||||
aarch64|arm64) TARGETARCH='arm64';; \
|
|
||||||
amd64|x86_64) TARGETARCH='amd64';; \
|
|
||||||
*) echo "Unsupported arch: ${ARCH}"; exit 1;; \
|
|
||||||
esac;
|
|
||||||
|
|
||||||
RUN apt update && apt install default-libmysqlclient-dev -y && rm -rf /var/lib/apt/lists/*
|
|
||||||
|
|
||||||
RUN curl -L "https://github.com/supabase/wrappers/releases/download/v${WRAPPERS_VERSION}/wrappers-v${WRAPPERS_VERSION}-pg${POSTGRES_VERSION}-${TARGETARCH}-linux-gnu.deb" -o wrappers.deb && \
|
|
||||||
dpkg --install wrappers.deb && \
|
|
||||||
rm wrappers.deb
|
|
||||||
|
|
||||||
COPY --from=build-libssl /usr/local/lib/libssl* /usr/local/lib/libcrypto* /usr/lib/
|
|
||||||
COPY --from=build-libssl /usr/local/lib/engines-1.1 /usr/lib/engines-1.1
|
|
||||||
|
|
||||||
# Copy mysql_fdw
|
|
||||||
COPY --from=build-mysql_fdw /mysql_fdw/mysql_fdw.so \
|
|
||||||
/usr/lib/postgresql/${POSTGRES_VERSION}/lib/mysql_fdw.so
|
|
||||||
COPY --from=build-mysql_fdw /mysql_fdw/mysql_fdw*.sql /mysql_fdw/mysql_fdw.control /mysql_fdw/mysql_fdw_pushdown.config \
|
|
||||||
/usr/share/postgresql/${POSTGRES_VERSION}/extension/
|
|
||||||
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user