641 lines
26 KiB
YAML
641 lines
26 KiB
YAML
# ignore: true
|
|
# documentation: https://docs.dify.ai
|
|
# slogan: Dify is an open-source LLM app development platform. Dify's intuitive interface combines AI workflow, RAG pipeline, agent capabilities, model management, observability features and more, letting you quickly go from prototype to production.
|
|
# tags: ai, weaviate, openai, gpt, llm, lmops, dify, redis, postgres, qdrant, RAG, agent
|
|
# logo: svgs/dify.png
|
|
# port: 3000
|
|
|
|
x-shared-env: &shared-api-worker-env
|
|
LOG_LEVEL: ${LOG_LEVEL:-INFO}
|
|
DEBUG: ${DEBUG:-false}
|
|
FLASK_DEBUG: ${FLASK_DEBUG:-false}
|
|
CONSOLE_WEB_URL: ${CONSOLE_WEB_URL:-}
|
|
CONSOLE_API_URL: ${CONSOLE_API_URL:-}
|
|
SERVICE_API_URL:
|
|
APP_WEB_URL: ${APP_WEB_URL:-}
|
|
CHECK_UPDATE_URL: ${CHECK_UPDATE_URL:-https://updates.dify.ai}
|
|
OPENAI_API_BASE: ${OPENAI_API_BASE:-https://api.openai.com/v1}
|
|
FILES_URL: ${FILES_URL:-}
|
|
FILES_ACCESS_TIMEOUT: ${FILES_ACCESS_TIMEOUT:-300}
|
|
APP_MAX_ACTIVE_REQUESTS: ${APP_MAX_ACTIVE_REQUESTS:-0}
|
|
MIGRATION_ENABLED: ${MIGRATION_ENABLED:-true}
|
|
DEPLOY_ENV: ${DEPLOY_ENV:-PRODUCTION}
|
|
DIFY_BIND_ADDRESS: ${DIFY_BIND_ADDRESS:-0.0.0.0}
|
|
DIFY_PORT: ${DIFY_PORT:-5001}
|
|
SERVER_WORKER_AMOUNT: ${SERVER_WORKER_AMOUNT:-}
|
|
SERVER_WORKER_CLASS: ${SERVER_WORKER_CLASS:-}
|
|
CELERY_WORKER_CLASS: ${CELERY_WORKER_CLASS:-}
|
|
GUNICORN_TIMEOUT: ${GUNICORN_TIMEOUT:-360}
|
|
CELERY_WORKER_AMOUNT: ${CELERY_WORKER_AMOUNT:-}
|
|
CELERY_AUTO_SCALE: ${CELERY_AUTO_SCALE:-false}
|
|
CELERY_MAX_WORKERS: ${CELERY_MAX_WORKERS:-}
|
|
CELERY_MIN_WORKERS: ${CELERY_MIN_WORKERS:-}
|
|
API_TOOL_DEFAULT_CONNECT_TIMEOUT: ${API_TOOL_DEFAULT_CONNECT_TIMEOUT:-10}
|
|
API_TOOL_DEFAULT_READ_TIMEOUT: ${API_TOOL_DEFAULT_READ_TIMEOUT:-60}
|
|
DB_USERNAME: $SERVICE_USER_POSTGRES
|
|
DB_PASSWORD: $SERVICE_PASSWORD_POSTGRES
|
|
DB_HOST: ${DB_HOST:-db}
|
|
DB_PORT: ${DB_PORT:-5432}
|
|
DB_DATABASE: dify
|
|
SQLALCHEMY_POOL_SIZE: ${SQLALCHEMY_POOL_SIZE:-30}
|
|
SQLALCHEMY_POOL_RECYCLE: ${SQLALCHEMY_POOL_RECYCLE:-3600}
|
|
SQLALCHEMY_ECHO: ${SQLALCHEMY_ECHO:-false}
|
|
POSTGRES_MAX_CONNECTIONS: ${POSTGRES_MAX_CONNECTIONS:-100}
|
|
POSTGRES_SHARED_BUFFERS: ${POSTGRES_SHARED_BUFFERS:-128MB}
|
|
POSTGRES_WORK_MEM: ${POSTGRES_WORK_MEM:-4MB}
|
|
POSTGRES_MAINTENANCE_WORK_MEM: ${POSTGRES_MAINTENANCE_WORK_MEM:-64MB}
|
|
POSTGRES_EFFECTIVE_CACHE_SIZE: ${POSTGRES_EFFECTIVE_CACHE_SIZE:-4096MB}
|
|
REDIS_HOST: ${REDIS_HOST:-redis}
|
|
REDIS_PORT: ${REDIS_PORT:-6379}
|
|
REDIS_USERNAME: ${REDIS_USERNAME:-}
|
|
REDIS_PASSWORD: $SERVICE_PASSWORD_REDIS
|
|
REDIS_USE_SSL: ${REDIS_USE_SSL:-false}
|
|
REDIS_DB: 0
|
|
CELERY_BROKER_URL: redis://:$SERVICE_PASSWORD_REDIS@redis:6379/1
|
|
BROKER_USE_SSL: ${BROKER_USE_SSL:-false}
|
|
WEB_API_CORS_ALLOW_ORIGINS: ${WEB_API_CORS_ALLOW_ORIGINS:-*}
|
|
CONSOLE_CORS_ALLOW_ORIGINS: ${CONSOLE_CORS_ALLOW_ORIGINS:-*}
|
|
STORAGE_TYPE: ${STORAGE_TYPE:-local}
|
|
STORAGE_LOCAL_PATH: storage
|
|
S3_USE_AWS_MANAGED_IAM: ${S3_USE_AWS_MANAGED_IAM:-false}
|
|
S3_ENDPOINT: ${S3_ENDPOINT:-}
|
|
S3_BUCKET_NAME: ${S3_BUCKET_NAME:-}
|
|
S3_ACCESS_KEY: ${S3_ACCESS_KEY:-}
|
|
S3_SECRET_KEY: ${S3_SECRET_KEY:-}
|
|
S3_REGION: ${S3_REGION:-us-east-1}
|
|
AZURE_BLOB_ACCOUNT_NAME: ${AZURE_BLOB_ACCOUNT_NAME:-}
|
|
AZURE_BLOB_ACCOUNT_KEY: ${AZURE_BLOB_ACCOUNT_KEY:-}
|
|
AZURE_BLOB_CONTAINER_NAME: ${AZURE_BLOB_CONTAINER_NAME:-}
|
|
AZURE_BLOB_ACCOUNT_URL: ${AZURE_BLOB_ACCOUNT_URL:-}
|
|
GOOGLE_STORAGE_BUCKET_NAME: ${GOOGLE_STORAGE_BUCKET_NAME:-}
|
|
GOOGLE_STORAGE_SERVICE_ACCOUNT_JSON_BASE64: ${GOOGLE_STORAGE_SERVICE_ACCOUNT_JSON_BASE64:-}
|
|
ALIYUN_OSS_BUCKET_NAME: ${ALIYUN_OSS_BUCKET_NAME:-}
|
|
ALIYUN_OSS_ACCESS_KEY: ${ALIYUN_OSS_ACCESS_KEY:-}
|
|
ALIYUN_OSS_SECRET_KEY: ${ALIYUN_OSS_SECRET_KEY:-}
|
|
ALIYUN_OSS_ENDPOINT: ${ALIYUN_OSS_ENDPOINT:-}
|
|
ALIYUN_OSS_REGION: ${ALIYUN_OSS_REGION:-}
|
|
ALIYUN_OSS_AUTH_VERSION: ${ALIYUN_OSS_AUTH_VERSION:-v4}
|
|
TENCENT_COS_BUCKET_NAME: ${TENCENT_COS_BUCKET_NAME:-}
|
|
TENCENT_COS_SECRET_KEY: ${TENCENT_COS_SECRET_KEY:-}
|
|
TENCENT_COS_SECRET_ID: ${TENCENT_COS_SECRET_ID:-}
|
|
TENCENT_COS_REGION: ${TENCENT_COS_REGION:-}
|
|
TENCENT_COS_SCHEME: ${TENCENT_COS_SCHEME:-}
|
|
OCI_ENDPOINT: ${OCI_ENDPOINT:-}
|
|
OCI_BUCKET_NAME: ${OCI_BUCKET_NAME:-}
|
|
OCI_ACCESS_KEY: ${OCI_ACCESS_KEY:-}
|
|
OCI_SECRET_KEY: ${OCI_SECRET_KEY:-}
|
|
OCI_REGION: ${OCI_REGION:-}
|
|
VECTOR_STORE: ${VECTOR_STORE:-weaviate}
|
|
WEAVIATE_ENDPOINT: ${WEAVIATE_ENDPOINT:-http://weaviate:8080}
|
|
WEAVIATE_API_KEY: $SERVICE_PASSWORD_WEAVIATE
|
|
RELYT_HOST: ${RELYT_HOST:-db}
|
|
RELYT_PORT: ${RELYT_PORT:-5432}
|
|
RELYT_USER: $SERVICE_USER_RELYT
|
|
RELYT_PASSWORD: $SERVICE_PASSWORD_RELYT
|
|
RELYT_DATABASE: ${RELYT_DATABASE:-postgres}
|
|
TIDB_VECTOR_HOST: ${TIDB_VECTOR_HOST:-tidb}
|
|
TIDB_VECTOR_PORT: ${TIDB_VECTOR_PORT:-4000}
|
|
TIDB_VECTOR_USER: $SERVICE_USER_TIDB
|
|
TIDB_VECTOR_PASSWORD: $SERVICE_PASSWORD_TIDB
|
|
TIDB_VECTOR_DATABASE: ${TIDB_VECTOR_DATABASE:-dify}
|
|
# AnalyticDB configuration
|
|
ANALYTICDB_KEY_ID: ${ANALYTICDB_KEY_ID:-}
|
|
ANALYTICDB_KEY_SECRET: ${ANALYTICDB_KEY_SECRET:-}
|
|
ANALYTICDB_REGION_ID: ${ANALYTICDB_REGION_ID:-}
|
|
ANALYTICDB_INSTANCE_ID: ${ANALYTICDB_INSTANCE_ID:-}
|
|
ANALYTICDB_ACCOUNT: ${ANALYTICDB_ACCOUNT:-}
|
|
ANALYTICDB_PASSWORD: ${ANALYTICDB_PASSWORD:-}
|
|
ANALYTICDB_NAMESPACE: ${ANALYTICDB_NAMESPACE:-dify}
|
|
ANALYTICDB_NAMESPACE_PASSWORD: ${ANALYTICDB_NAMESPACE_PASSWORD:-}
|
|
TENCENT_VECTOR_DB_URL: ${TENCENT_VECTOR_DB_URL:-http://127.0.0.1}
|
|
TENCENT_VECTOR_DB_API_KEY: ${TENCENT_VECTOR_DB_API_KEY:-dify}
|
|
TENCENT_VECTOR_DB_TIMEOUT: ${TENCENT_VECTOR_DB_TIMEOUT:-30}
|
|
TENCENT_VECTOR_DB_USERNAME: ${TENCENT_VECTOR_DB_USERNAME:-dify}
|
|
TENCENT_VECTOR_DB_DATABASE: ${TENCENT_VECTOR_DB_DATABASE:-dify}
|
|
TENCENT_VECTOR_DB_SHARD: ${TENCENT_VECTOR_DB_SHARD:-1}
|
|
TENCENT_VECTOR_DB_REPLICAS: ${TENCENT_VECTOR_DB_REPLICAS:-2}
|
|
UPLOAD_FILE_SIZE_LIMIT: ${UPLOAD_FILE_SIZE_LIMIT:-15}
|
|
UPLOAD_FILE_BATCH_LIMIT: ${UPLOAD_FILE_BATCH_LIMIT:-5}
|
|
ETL_TYPE: ${ETL_TYPE:-dify}
|
|
MULTIMODAL_SEND_IMAGE_FORMAT: ${MULTIMODAL_SEND_IMAGE_FORMAT:-base64}
|
|
UPLOAD_IMAGE_FILE_SIZE_LIMIT: ${UPLOAD_IMAGE_FILE_SIZE_LIMIT:-10}
|
|
SENTRY_DSN: ${API_SENTRY_DSN:-}
|
|
SENTRY_TRACES_SAMPLE_RATE: ${API_SENTRY_TRACES_SAMPLE_RATE:-1.0}
|
|
SENTRY_PROFILES_SAMPLE_RATE: ${API_SENTRY_PROFILES_SAMPLE_RATE:-1.0}
|
|
NOTION_INTEGRATION_TYPE: ${NOTION_INTEGRATION_TYPE:-public}
|
|
NOTION_CLIENT_SECRET: ${NOTION_CLIENT_SECRET:-}
|
|
NOTION_CLIENT_ID: ${NOTION_CLIENT_ID:-}
|
|
NOTION_INTERNAL_SECRET: ${NOTION_INTERNAL_SECRET:-}
|
|
MAIL_TYPE: ${MAIL_TYPE:-resend}
|
|
MAIL_DEFAULT_SEND_FROM: ${MAIL_DEFAULT_SEND_FROM:-}
|
|
SMTP_SERVER: ${SMTP_SERVER:-}
|
|
SMTP_PORT: ${SMTP_PORT:-465}
|
|
SMTP_USERNAME: ${SMTP_USERNAME:-}
|
|
SMTP_PASSWORD: ${SMTP_PASSWORD:-}
|
|
SMTP_USE_TLS: ${SMTP_USE_TLS:-true}
|
|
SMTP_OPPORTUNISTIC_TLS: ${SMTP_OPPORTUNISTIC_TLS:-false}
|
|
RESEND_API_KEY: ${RESEND_API_KEY:-your-resend-api-key}
|
|
RESEND_API_URL: https://api.resend.com
|
|
INDEXING_MAX_SEGMENTATION_TOKENS_LENGTH: ${INDEXING_MAX_SEGMENTATION_TOKENS_LENGTH:-1000}
|
|
INVITE_EXPIRY_HOURS: ${INVITE_EXPIRY_HOURS:-72}
|
|
RESET_PASSWORD_TOKEN_EXPIRY_HOURS: ${RESET_PASSWORD_TOKEN_EXPIRY_HOURS:-24}
|
|
CODE_EXECUTION_ENDPOINT: ${CODE_EXECUTION_ENDPOINT:-http://sandbox:8194}
|
|
CODE_EXECUTION_API_KEY: ${SANDBOX_API_KEY:-dify-sandbox}
|
|
CODE_MAX_NUMBER: ${CODE_MAX_NUMBER:-9223372036854775807}
|
|
CODE_MIN_NUMBER: ${CODE_MIN_NUMBER:--9223372036854775808}
|
|
CODE_MAX_STRING_LENGTH: ${CODE_MAX_STRING_LENGTH:-80000}
|
|
TEMPLATE_TRANSFORM_MAX_LENGTH: ${TEMPLATE_TRANSFORM_MAX_LENGTH:-80000}
|
|
CODE_MAX_STRING_ARRAY_LENGTH: ${CODE_MAX_STRING_ARRAY_LENGTH:-30}
|
|
CODE_MAX_OBJECT_ARRAY_LENGTH: ${CODE_MAX_OBJECT_ARRAY_LENGTH:-30}
|
|
CODE_MAX_NUMBER_ARRAY_LENGTH: ${CODE_MAX_NUMBER_ARRAY_LENGTH:-1000}
|
|
SSRF_PROXY_HTTP_URL: ${SSRF_PROXY_HTTP_URL:-http://ssrf_proxy:3128}
|
|
SSRF_PROXY_HTTPS_URL: ${SSRF_PROXY_HTTPS_URL:-http://ssrf_proxy:3128}
|
|
|
|
services:
|
|
api:
|
|
image: langgenius/dify-api:latest
|
|
environment:
|
|
SECRET_KEY: $SERVICE_PASSWORD_64_SECRETKEY
|
|
INIT_PASSWORD: $SERVICE_USER_INITPASSWORD
|
|
# Use the shared environment variables.
|
|
<<: *shared-api-worker-env
|
|
# Startup mode, 'api' starts the API server.
|
|
MODE: api
|
|
depends_on:
|
|
db:
|
|
condition: service_healthy
|
|
redis:
|
|
condition: service_healthy
|
|
volumes:
|
|
# Mount the storage directory to the container, for storing user files.
|
|
- dify-storage:/app/api/storage
|
|
networks:
|
|
- ssrf_proxy_network
|
|
- default
|
|
healthcheck:
|
|
test: ["CMD", "curl", "-f", "http://localhost:5001/health"]
|
|
interval: 30s
|
|
timeout: 10s
|
|
retries: 3
|
|
start_period: 40s
|
|
|
|
# worker service
|
|
# The Celery worker for processing the queue.
|
|
worker:
|
|
image: langgenius/dify-api:latest
|
|
environment:
|
|
# Use the shared environment variables.
|
|
<<: *shared-api-worker-env
|
|
# Startup mode, 'worker' starts the Celery worker for processing the queue.
|
|
MODE: worker
|
|
depends_on:
|
|
db:
|
|
condition: service_healthy
|
|
redis:
|
|
condition: service_healthy
|
|
volumes:
|
|
# Mount the storage directory to the container, for storing user files.
|
|
- dify-storage:/app/api/storage
|
|
networks:
|
|
- ssrf_proxy_network
|
|
- default
|
|
healthcheck:
|
|
test: ["CMD-SHELL", "celery inspect ping"]
|
|
interval: 30s
|
|
timeout: 10s
|
|
retries: 3
|
|
start_period: 40s
|
|
|
|
# Frontend web application.
|
|
web:
|
|
image: langgenius/dify-web:latest
|
|
environment:
|
|
- SERVICE_FQDN_WEB_3000
|
|
- CONSOLE_API_URL=${SERVICE_FQDN_WEB}
|
|
- APP_API_URL=${SERVICE_FQDN_API}
|
|
- SENTRY_DSN=${WEB_SENTRY_DSN:-}
|
|
- NEXT_TELEMETRY_DISABLED=${NEXT_TELEMETRY_DISABLED:-0}
|
|
healthcheck:
|
|
test: ["CMD", "wget", "--spider", "-q", "http://web:3000"]
|
|
interval: 30s
|
|
timeout: 10s
|
|
retries: 3
|
|
start_period: 40s
|
|
|
|
# The postgres database.
|
|
db:
|
|
image: postgres:15-alpine
|
|
environment:
|
|
POSTGRES_USER: $SERVICE_USER_POSTGRES
|
|
POSTGRES_PASSWORD: $SERVICE_PASSWORD_POSTGRES
|
|
POSTGRES_DB: dify
|
|
PGDATA: /var/lib/postgresql/data/pgdata
|
|
command: >
|
|
postgres -c 'max_connections=${POSTGRES_MAX_CONNECTIONS:-100}'
|
|
-c 'shared_buffers=${POSTGRES_SHARED_BUFFERS:-128MB}'
|
|
-c 'work_mem=${POSTGRES_WORK_MEM:-4MB}'
|
|
-c 'maintenance_work_mem=${POSTGRES_MAINTENANCE_WORK_MEM:-64MB}'
|
|
-c 'effective_cache_size=${POSTGRES_EFFECTIVE_CACHE_SIZE:-4096MB}'
|
|
volumes:
|
|
- dify-db-data:/var/lib/postgresql/data
|
|
healthcheck:
|
|
test: ["CMD", "pg_isready", "-U", "$SERVICE_USER_POSTGRES", "-d", "dify"]
|
|
interval: 10s
|
|
timeout: 5s
|
|
retries: 5
|
|
|
|
# The redis cache.
|
|
redis:
|
|
image: redis:6-alpine
|
|
environment:
|
|
REDIS_PASSWORD: $SERVICE_PASSWORD_REDIS
|
|
volumes:
|
|
- dify-redis-data:/data
|
|
# Set the redis password when startup redis server.
|
|
command: redis-server --requirepass "$SERVICE_PASSWORD_REDIS"
|
|
healthcheck:
|
|
test: [ "CMD", "redis-cli", "-a", "$SERVICE_PASSWORD_REDIS", "ping" ]
|
|
|
|
# The DifySandbox
|
|
sandbox:
|
|
image: langgenius/dify-sandbox:latest
|
|
restart: always
|
|
environment:
|
|
# The DifySandbox configurations
|
|
# Make sure you are changing this key for your deployment with a strong key.
|
|
# You can generate a strong key using `openssl rand -base64 42`.
|
|
API_KEY: ${SANDBOX_API_KEY:-dify-sandbox}
|
|
GIN_MODE: ${SANDBOX_GIN_MODE:-release}
|
|
WORKER_TIMEOUT: ${SANDBOX_WORKER_TIMEOUT:-15}
|
|
ENABLE_NETWORK: ${SANDBOX_ENABLE_NETWORK:-true}
|
|
HTTP_PROXY: ${SANDBOX_HTTP_PROXY:-http://ssrf_proxy:3128}
|
|
HTTPS_PROXY: ${SANDBOX_HTTPS_PROXY:-http://ssrf_proxy:3128}
|
|
SANDBOX_PORT: ${SANDBOX_PORT:-8194}
|
|
volumes:
|
|
- './volumes/sandbox/dependencies:/dependencies'
|
|
networks:
|
|
- ssrf_proxy_network
|
|
- default
|
|
healthcheck:
|
|
test: ["CMD-SHELL", "bash -c ':> /dev/tcp/127.0.0.1/8194' || exit 1"]
|
|
interval: 5s
|
|
timeout: 20s
|
|
retries: 3
|
|
|
|
# ssrf_proxy server
|
|
# for more information, please refer to
|
|
# https://docs.dify.ai/learn-more/faq/self-host-faq#id-18.-why-is-ssrf_proxy-needed
|
|
ssrf_proxy:
|
|
image: ubuntu/squid:latest
|
|
volumes:
|
|
- type: bind
|
|
source: ./ssrf_proxy/squid.conf.template
|
|
target: /etc/squid/squid.conf.template
|
|
read_only: true
|
|
content: |
|
|
acl localnet src 0.0.0.1-0.255.255.255 # RFC 1122 "this" network (LAN)
|
|
acl localnet src 10.0.0.0/8 # RFC 1918 local private network (LAN)
|
|
acl localnet src 100.64.0.0/10 # RFC 6598 shared address space (CGN)
|
|
acl localnet src 169.254.0.0/16 # RFC 3927 link-local (directly plugged) machines
|
|
acl localnet src 172.16.0.0/12 # RFC 1918 local private network (LAN)
|
|
acl localnet src 192.168.0.0/16 # RFC 1918 local private network (LAN)
|
|
acl localnet src fc00::/7 # RFC 4193 local private network range
|
|
acl localnet src fe80::/10 # RFC 4291 link-local (directly plugged) machines
|
|
acl SSL_ports port 443
|
|
acl Safe_ports port 80 # http
|
|
acl Safe_ports port 21 # ftp
|
|
acl Safe_ports port 443 # https
|
|
acl Safe_ports port 70 # gopher
|
|
acl Safe_ports port 210 # wais
|
|
acl Safe_ports port 1025-65535 # unregistered ports
|
|
acl Safe_ports port 280 # http-mgmt
|
|
acl Safe_ports port 488 # gss-http
|
|
acl Safe_ports port 591 # filemaker
|
|
acl Safe_ports port 777 # multiling http
|
|
acl CONNECT method CONNECT
|
|
http_access deny !Safe_ports
|
|
http_access deny CONNECT !SSL_ports
|
|
http_access allow localhost manager
|
|
http_access deny manager
|
|
http_access allow localhost
|
|
include /etc/squid/conf.d/*.conf
|
|
http_access deny all
|
|
|
|
################################## Proxy Server ################################
|
|
http_port 3128
|
|
coredump_dir ${COREDUMP_DIR}
|
|
refresh_pattern ^ftp: 1440 20% 10080
|
|
refresh_pattern ^gopher: 1440 0% 1440
|
|
refresh_pattern -i (/cgi-bin/|\?) 0 0% 0
|
|
refresh_pattern \/(Packages|Sources)(|\.bz2|\.gz|\.xz)$ 0 0% 0 refresh-ims
|
|
refresh_pattern \/Release(|\.gpg)$ 0 0% 0 refresh-ims
|
|
refresh_pattern \/InRelease$ 0 0% 0 refresh-ims
|
|
refresh_pattern \/(Translation-.*)(|\.bz2|\.gz|\.xz)$ 0 0% 0 refresh-ims
|
|
refresh_pattern . 0 20% 4320
|
|
|
|
|
|
# cache_dir ufs /var/spool/squid 100 16 256
|
|
# upstream proxy, set to your own upstream proxy IP to avoid SSRF attacks
|
|
# cache_peer 172.1.1.1 parent 3128 0 no-query no-digest no-netdb-exchange default
|
|
|
|
################################## Reverse Proxy To Sandbox ################################
|
|
http_port 3129 accel vhost
|
|
cache_peer ${SANDBOX_HOST} parent ${SANDBOX_PORT} 0 no-query originserver
|
|
acl src_all src all
|
|
http_access allow src_all
|
|
- type: bind
|
|
source: ./ssrf_proxy/docker-entrypoint.sh
|
|
target: /docker-entrypoint.sh
|
|
read_only: true
|
|
content: |
|
|
#!/bin/bash
|
|
|
|
# Modified based on Squid OCI image entrypoint
|
|
|
|
# This entrypoint aims to forward the squid logs to stdout to assist users of
|
|
# common container related tooling (e.g., kubernetes, docker-compose, etc) to
|
|
# access the service logs.
|
|
|
|
# Moreover, it invokes the squid binary, leaving all the desired parameters to
|
|
# be provided by the "command" passed to the spawned container. If no command
|
|
# is provided by the user, the default behavior (as per the CMD statement in
|
|
# the Dockerfile) will be to use Ubuntu's default configuration [1] and run
|
|
# squid with the "-NYC" options to mimic the behavior of the Ubuntu provided
|
|
# systemd unit.
|
|
|
|
# [1] The default configuration is changed in the Dockerfile to allow local
|
|
# network connections. See the Dockerfile for further information.
|
|
|
|
echo "[ENTRYPOINT] re-create snakeoil self-signed certificate removed in the build process"
|
|
if [ ! -f /etc/ssl/private/ssl-cert-snakeoil.key ]; then
|
|
/usr/sbin/make-ssl-cert generate-default-snakeoil --force-overwrite > /dev/null 2>&1
|
|
fi
|
|
|
|
tail -F /var/log/squid/access.log 2>/dev/null &
|
|
tail -F /var/log/squid/error.log 2>/dev/null &
|
|
tail -F /var/log/squid/store.log 2>/dev/null &
|
|
tail -F /var/log/squid/cache.log 2>/dev/null &
|
|
|
|
# Replace environment variables in the template and output to the squid.conf
|
|
echo "[ENTRYPOINT] replacing environment variables in the template"
|
|
awk '{
|
|
while(match($0, /\${[A-Za-z_][A-Za-z_0-9]*}/)) {
|
|
var = substr($0, RSTART+2, RLENGTH-3)
|
|
val = ENVIRON[var]
|
|
$0 = substr($0, 1, RSTART-1) val substr($0, RSTART+RLENGTH)
|
|
}
|
|
print
|
|
}' /etc/squid/squid.conf.template > /etc/squid/squid.conf
|
|
|
|
/usr/sbin/squid -Nz
|
|
echo "[ENTRYPOINT] starting squid"
|
|
/usr/sbin/squid -f /etc/squid/squid.conf -NYC 1
|
|
- ssrf_proxy_var_log_squid:/var/log/squid
|
|
- ssrf_proxy_var_spool_squid:/var/spool/squid
|
|
entrypoint: ["/bin/sh", "/docker-entrypoint.sh"]
|
|
environment:
|
|
# pls clearly modify the squid env vars to fit your network environment.
|
|
HTTP_PORT: ${SSRF_HTTP_PORT:-3128}
|
|
COREDUMP_DIR: ${SSRF_COREDUMP_DIR:-/var/spool/squid}
|
|
REVERSE_PROXY_PORT: ${SSRF_REVERSE_PROXY_PORT:-8194}
|
|
SANDBOX_HOST: ${SSRF_SANDBOX_HOST:-sandbox}
|
|
SANDBOX_PORT: ${SANDBOX_PORT:-8194}
|
|
networks:
|
|
- ssrf_proxy_network
|
|
- default
|
|
healthcheck:
|
|
test: ["CMD", "squid", "-k", "check"]
|
|
interval: 30s
|
|
timeout: 10s
|
|
retries: 3
|
|
start_period: 40s
|
|
|
|
# The nginx reverse proxy.
|
|
# used for reverse proxying the API service and Web service.
|
|
nginx:
|
|
image: nginx:latest
|
|
volumes:
|
|
- type: bind
|
|
source: ./nginx/nginx.conf.template
|
|
target: /etc/nginx/nginx.conf.template
|
|
read_only: true
|
|
content: |
|
|
# Please do not directly edit this file. Instead, modify the .env variables related to NGINX configuration.
|
|
|
|
user nginx;
|
|
worker_processes ${NGINX_WORKER_PROCESSES};
|
|
|
|
error_log /var/log/nginx/error.log notice;
|
|
pid /var/run/nginx.pid;
|
|
|
|
|
|
events {
|
|
worker_connections 1024;
|
|
}
|
|
|
|
|
|
http {
|
|
include /etc/nginx/mime.types;
|
|
default_type application/octet-stream;
|
|
|
|
log_format main '$remote_addr - $remote_user [$time_local] "$request" '
|
|
'$status $body_bytes_sent "$http_referer" '
|
|
'"$http_user_agent" "$http_x_forwarded_for"';
|
|
|
|
access_log /var/log/nginx/access.log main;
|
|
|
|
sendfile on;
|
|
#tcp_nopush on;
|
|
|
|
keepalive_timeout ${NGINX_KEEPALIVE_TIMEOUT};
|
|
|
|
#gzip on;
|
|
client_max_body_size ${NGINX_CLIENT_MAX_BODY_SIZE};
|
|
|
|
include /etc/nginx/conf.d/*.conf;
|
|
}
|
|
- type: bind
|
|
source: ./nginx/proxy.conf.template
|
|
target: /etc/nginx/proxy.conf.template
|
|
read_only: true
|
|
content: |
|
|
# Please do not directly edit this file. Instead, modify the .env variables related to NGINX configuration.
|
|
proxy_set_header Host $host;
|
|
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
|
|
proxy_set_header X-Forwarded-Proto $scheme;
|
|
proxy_http_version 1.1;
|
|
proxy_set_header Connection "";
|
|
proxy_buffering off;
|
|
proxy_read_timeout ${NGINX_PROXY_READ_TIMEOUT};
|
|
proxy_send_timeout ${NGINX_PROXY_SEND_TIMEOUT};
|
|
- type: bind
|
|
source: ./nginx/https.conf.template
|
|
target: /etc/nginx/https.conf.template
|
|
read_only: true
|
|
content: |
|
|
# Please do not directly edit this file. Instead, modify the .env variables related to NGINX configuration.
|
|
|
|
listen ${NGINX_SSL_PORT} ssl;
|
|
ssl_certificate ${SSL_CERTIFICATE_PATH};
|
|
ssl_certificate_key ${SSL_CERTIFICATE_KEY_PATH};
|
|
ssl_protocols ${NGINX_SSL_PROTOCOLS};
|
|
ssl_prefer_server_ciphers on;
|
|
ssl_session_cache shared:SSL:10m;
|
|
ssl_session_timeout 10m;
|
|
- type: bind
|
|
source: ./nginx/docker-entrypoint.sh
|
|
target: /docker-entrypoint-mount.sh
|
|
read_only: true
|
|
content: |
|
|
#!/bin/bash
|
|
|
|
if [ "${NGINX_HTTPS_ENABLED}" = "true" ]; then
|
|
# Check if the certificate and key files for the specified domain exist
|
|
if [ -n "${CERTBOT_DOMAIN}" ] && \
|
|
[ -f "/etc/letsencrypt/live/${CERTBOT_DOMAIN}/${NGINX_SSL_CERT_FILENAME}" ] && \
|
|
[ -f "/etc/letsencrypt/live/${CERTBOT_DOMAIN}/${NGINX_SSL_CERT_KEY_FILENAME}" ]; then
|
|
SSL_CERTIFICATE_PATH="/etc/letsencrypt/live/${CERTBOT_DOMAIN}/${NGINX_SSL_CERT_FILENAME}"
|
|
SSL_CERTIFICATE_KEY_PATH="/etc/letsencrypt/live/${CERTBOT_DOMAIN}/${NGINX_SSL_CERT_KEY_FILENAME}"
|
|
else
|
|
SSL_CERTIFICATE_PATH="/etc/ssl/${NGINX_SSL_CERT_FILENAME}"
|
|
SSL_CERTIFICATE_KEY_PATH="/etc/ssl/${NGINX_SSL_CERT_KEY_FILENAME}"
|
|
fi
|
|
export SSL_CERTIFICATE_PATH
|
|
export SSL_CERTIFICATE_KEY_PATH
|
|
|
|
# set the HTTPS_CONFIG environment variable to the content of the https.conf.template
|
|
HTTPS_CONFIG=$(envsubst < /etc/nginx/https.conf.template)
|
|
export HTTPS_CONFIG
|
|
# Substitute the HTTPS_CONFIG in the default.conf.template with content from https.conf.template
|
|
envsubst '${HTTPS_CONFIG}' < /etc/nginx/conf.d/default.conf.template > /etc/nginx/conf.d/default.conf
|
|
fi
|
|
|
|
if [ "${NGINX_ENABLE_CERTBOT_CHALLENGE}" = "true" ]; then
|
|
ACME_CHALLENGE_LOCATION='location /.well-known/acme-challenge/ { root /var/www/html; }'
|
|
else
|
|
ACME_CHALLENGE_LOCATION=''
|
|
fi
|
|
export ACME_CHALLENGE_LOCATION
|
|
|
|
env_vars=$(printenv | cut -d= -f1 | sed 's/^/$/g' | paste -sd, -)
|
|
|
|
envsubst "$env_vars" < /etc/nginx/nginx.conf.template > /etc/nginx/nginx.conf
|
|
envsubst "$env_vars" < /etc/nginx/proxy.conf.template > /etc/nginx/proxy.conf
|
|
|
|
envsubst < /etc/nginx/conf.d/default.conf.template > /etc/nginx/conf.d/default.conf
|
|
|
|
# Start Nginx using the default entrypoint
|
|
exec nginx -g 'daemon off;'
|
|
- type: bind
|
|
source: ./nginx/default.conf.template
|
|
target: /etc/nginx/conf.d/default.conf.template
|
|
read_only: true
|
|
content: |
|
|
# Please do not directly edit this file. Instead, modify the .env variables related to NGINX configuration.
|
|
|
|
server {
|
|
listen ${NGINX_PORT};
|
|
server_name ${NGINX_SERVER_NAME};
|
|
|
|
location /console/api {
|
|
proxy_pass http://api:5001;
|
|
include proxy.conf;
|
|
}
|
|
|
|
location /api {
|
|
proxy_pass http://api:5001;
|
|
include proxy.conf;
|
|
}
|
|
|
|
location /v1 {
|
|
proxy_pass http://api:5001;
|
|
include proxy.conf;
|
|
}
|
|
|
|
location /files {
|
|
proxy_pass http://api:5001;
|
|
include proxy.conf;
|
|
}
|
|
|
|
location / {
|
|
proxy_pass http://web:3000;
|
|
include proxy.conf;
|
|
}
|
|
|
|
# placeholder for acme challenge location
|
|
${ACME_CHALLENGE_LOCATION}
|
|
|
|
# placeholder for https config defined in https.conf.template
|
|
${HTTPS_CONFIG}
|
|
}
|
|
- './nginx/ssl:/etc/ssl'
|
|
- './volumes/certbot/conf/live:/etc/letsencrypt/live'
|
|
- './volumes/certbot/conf:/etc/letsencrypt'
|
|
- './volumes/certbot/www:/var/www/html'
|
|
entrypoint: [ "sh", "-c", "cp /docker-entrypoint-mount.sh /docker-entrypoint.sh && sed -i 's/\r$$//' /docker-entrypoint.sh && chmod +x /docker-entrypoint.sh && /docker-entrypoint.sh" ]
|
|
environment:
|
|
NGINX_SERVER_NAME: $SERVICE_FQDN_NGINX
|
|
NGINX_HTTPS_ENABLED: ${NGINX_HTTPS_ENABLED:-false}
|
|
NGINX_SSL_PORT: ${NGINX_SSL_PORT:-443}
|
|
NGINX_PORT: ${NGINX_PORT:-80}
|
|
# You're required to add your own SSL certificates/keys to the `./nginx/ssl` directory
|
|
# and modify the env vars below in .env if HTTPS_ENABLED is true.
|
|
NGINX_SSL_CERT_FILENAME: ${NGINX_SSL_CERT_FILENAME:-dify.crt}
|
|
NGINX_SSL_CERT_KEY_FILENAME: ${NGINX_SSL_CERT_KEY_FILENAME:-dify.key}
|
|
NGINX_SSL_PROTOCOLS: ${NGINX_SSL_PROTOCOLS:-TLSv1.1 TLSv1.2 TLSv1.3}
|
|
NGINX_WORKER_PROCESSES: ${NGINX_WORKER_PROCESSES:-auto}
|
|
NGINX_CLIENT_MAX_BODY_SIZE: ${NGINX_CLIENT_MAX_BODY_SIZE:-15M}
|
|
NGINX_KEEPALIVE_TIMEOUT: ${NGINX_KEEPALIVE_TIMEOUT:-65}
|
|
NGINX_PROXY_READ_TIMEOUT: ${NGINX_PROXY_READ_TIMEOUT:-3600s}
|
|
NGINX_PROXY_SEND_TIMEOUT: ${NGINX_PROXY_SEND_TIMEOUT:-3600s}
|
|
NGINX_ENABLE_CERTBOT_CHALLENGE: ${NGINX_ENABLE_CERTBOT_CHALLENGE:-false}
|
|
CERTBOT_DOMAIN: ${CERTBOT_DOMAIN:-}
|
|
depends_on:
|
|
- api
|
|
- web
|
|
healthcheck:
|
|
test: ["CMD", "nginx", "-t"]
|
|
interval: 30s
|
|
timeout: 10s
|
|
retries: 3
|
|
start_period: 40s
|
|
|
|
|
|
# The Weaviate vector store.
|
|
weaviate:
|
|
image: semitechnologies/weaviate:1.19.0
|
|
profiles:
|
|
- ''
|
|
- weaviate
|
|
volumes:
|
|
- dify-weaviate-data:/var/lib/weaviate
|
|
environment:
|
|
# The Weaviate configurations
|
|
# You can refer to the [Weaviate](https://weaviate.io/developers/weaviate/config-refs/env-vars) documentation for more information.
|
|
PERSISTENCE_DATA_PATH: ${WEAVIATE_PERSISTENCE_DATA_PATH:-/var/lib/weaviate}
|
|
QUERY_DEFAULTS_LIMIT: ${WEAVIATE_QUERY_DEFAULTS_LIMIT:-25}
|
|
AUTHENTICATION_ANONYMOUS_ACCESS_ENABLED: ${WEAVIATE_AUTHENTICATION_ANONYMOUS_ACCESS_ENABLED:-false}
|
|
DEFAULT_VECTORIZER_MODULE: ${WEAVIATE_DEFAULT_VECTORIZER_MODULE:-none}
|
|
CLUSTER_HOSTNAME: ${WEAVIATE_CLUSTER_HOSTNAME:-node1}
|
|
AUTHENTICATION_APIKEY_ENABLED: ${WEAVIATE_AUTHENTICATION_APIKEY_ENABLED:-true}
|
|
AUTHENTICATION_APIKEY_ALLOWED_KEYS: $SERVICE_PASSWORD_WEAVIATE
|
|
AUTHENTICATION_APIKEY_USERS: $SERVICE_USER_WEAVIATE
|
|
AUTHORIZATION_ADMINLIST_ENABLED: ${WEAVIATE_AUTHORIZATION_ADMINLIST_ENABLED:-true}
|
|
AUTHORIZATION_ADMINLIST_USERS: $SERVICE_USER_WEAVIATE
|
|
healthcheck:
|
|
test: ["CMD", "wget", "--spider", "-q", "http://localhost:8080/v1/.well-known/live"]
|
|
interval: 30s
|
|
timeout: 10s
|
|
retries: 3
|
|
start_period: 40s
|
|
|
|
networks:
|
|
# create a network between sandbox, api and ssrf_proxy, and can not access outside.
|
|
ssrf_proxy_network:
|
|
driver: bridge
|
|
internal: true
|
|
|
|
volumes:
|
|
ssrf_proxy_var_log_squid:
|
|
ssrf_proxy_var_spool_squid:
|