mirror of
https://github.com/langgenius/dify.git
synced 2026-05-08 00:02:34 -04:00
335 lines
7.4 KiB
Bash
Executable File
335 lines
7.4 KiB
Bash
Executable File
#!/usr/bin/env bash
|
|
|
|
set -euo pipefail
|
|
|
|
SCRIPT_DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)"
|
|
cd "$SCRIPT_DIR"
|
|
|
|
DEFAULT_ENV_FILE=".env.default"
|
|
USER_ENV_FILE=".env"
|
|
|
|
log() {
|
|
printf '%s\n' "$*" >&2
|
|
}
|
|
|
|
die() {
|
|
printf 'Error: %s\n' "$*" >&2
|
|
exit 1
|
|
}
|
|
|
|
detect_compose() {
|
|
if docker compose version >/dev/null 2>&1; then
|
|
COMPOSE_CMD=(docker compose)
|
|
return
|
|
fi
|
|
|
|
if command -v docker-compose >/dev/null 2>&1; then
|
|
COMPOSE_CMD=(docker-compose)
|
|
return
|
|
fi
|
|
|
|
die "Docker Compose is not available. Install Docker Compose, then run this command again."
|
|
}
|
|
|
|
generate_secret_key() {
|
|
if command -v openssl >/dev/null 2>&1; then
|
|
openssl rand -base64 42
|
|
return
|
|
fi
|
|
|
|
if command -v dd >/dev/null 2>&1 && command -v base64 >/dev/null 2>&1; then
|
|
dd if=/dev/urandom bs=42 count=1 2>/dev/null | base64 | tr -d '\n'
|
|
printf '\n'
|
|
return
|
|
fi
|
|
|
|
return 1
|
|
}
|
|
|
|
ensure_env_files() {
|
|
[[ -f "$DEFAULT_ENV_FILE" ]] || die "$DEFAULT_ENV_FILE is missing."
|
|
|
|
if [[ -f "$USER_ENV_FILE" ]]; then
|
|
return
|
|
fi
|
|
|
|
: >"$USER_ENV_FILE"
|
|
|
|
if [[ ! -t 0 ]]; then
|
|
log "Created $USER_ENV_FILE for local overrides."
|
|
return
|
|
fi
|
|
|
|
printf 'Created %s for local overrides.\n' "$USER_ENV_FILE"
|
|
printf 'Do you need a custom deployment now? (Most users can press Enter to skip.) [y/N] '
|
|
read -r answer
|
|
|
|
case "${answer:-}" in
|
|
y | Y | yes | YES | Yes)
|
|
cat <<'EOF'
|
|
Edit .env with the settings you want to override, using .env.example as the full reference.
|
|
Run ./dify-compose up -d again when you are ready.
|
|
EOF
|
|
exit 0
|
|
;;
|
|
esac
|
|
}
|
|
|
|
user_env_value() {
|
|
local key="$1"
|
|
awk -F= -v target="$key" '
|
|
/^[[:space:]]*#/ || !/=/{ next }
|
|
{
|
|
key = $1
|
|
gsub(/^[[:space:]]+|[[:space:]]+$/, "", key)
|
|
if (key == target) {
|
|
value = substr($0, index($0, "=") + 1)
|
|
gsub(/^[[:space:]]+|[[:space:]]+$/, "", value)
|
|
if ((value ~ /^".*"$/) || (value ~ /^'\''.*'\''$/)) {
|
|
value = substr(value, 2, length(value) - 2)
|
|
}
|
|
result = value
|
|
}
|
|
}
|
|
END { print result }
|
|
' "$USER_ENV_FILE"
|
|
}
|
|
|
|
set_user_env_value() {
|
|
local key="$1"
|
|
local value="$2"
|
|
local temp_file
|
|
|
|
temp_file="$(mktemp "${TMPDIR:-/tmp}/dify-env.XXXXXX")"
|
|
awk -F= -v target="$key" -v replacement="$key=$value" '
|
|
BEGIN { replaced = 0 }
|
|
/^[[:space:]]*#/ || !/=/{ print; next }
|
|
{
|
|
key = $1
|
|
gsub(/^[[:space:]]+|[[:space:]]+$/, "", key)
|
|
if (key == target) {
|
|
if (!replaced) {
|
|
print replacement
|
|
replaced = 1
|
|
}
|
|
next
|
|
}
|
|
print
|
|
}
|
|
END {
|
|
if (!replaced) {
|
|
print replacement
|
|
}
|
|
}
|
|
' "$USER_ENV_FILE" >"$temp_file"
|
|
mv "$temp_file" "$USER_ENV_FILE"
|
|
}
|
|
|
|
ensure_secret_key() {
|
|
local current_secret_key
|
|
local secret_key
|
|
|
|
current_secret_key="$(user_env_value SECRET_KEY)"
|
|
if [[ -n "$current_secret_key" ]]; then
|
|
return
|
|
fi
|
|
|
|
secret_key="$(generate_secret_key)" || die "Unable to generate SECRET_KEY. Install openssl or configure SECRET_KEY in .env."
|
|
set_user_env_value SECRET_KEY "$secret_key"
|
|
log "Generated SECRET_KEY in $USER_ENV_FILE."
|
|
}
|
|
|
|
env_value() {
|
|
local key="$1"
|
|
awk -F= -v target="$key" '
|
|
/^[[:space:]]*#/ || !/=/{ next }
|
|
{
|
|
key = $1
|
|
gsub(/^[[:space:]]+|[[:space:]]+$/, "", key)
|
|
if (key == target) {
|
|
value = substr($0, index($0, "=") + 1)
|
|
gsub(/^[[:space:]]+|[[:space:]]+$/, "", value)
|
|
if ((value ~ /^".*"$/) || (value ~ /^'\''.*'\''$/)) {
|
|
value = substr(value, 2, length(value) - 2)
|
|
}
|
|
result = value
|
|
}
|
|
}
|
|
END { print result }
|
|
' "$DEFAULT_ENV_FILE" "$USER_ENV_FILE"
|
|
}
|
|
|
|
user_overrides() {
|
|
local key="$1"
|
|
grep -Eq "^[[:space:]]*${key}[[:space:]]*=" "$USER_ENV_FILE"
|
|
}
|
|
|
|
write_merged_env() {
|
|
awk '
|
|
function trim(s) {
|
|
sub(/^[[:space:]]+/, "", s)
|
|
sub(/[[:space:]]+$/, "", s)
|
|
return s
|
|
}
|
|
|
|
/^[[:space:]]*#/ || !/=/{ next }
|
|
|
|
{
|
|
key = $0
|
|
sub(/=.*/, "", key)
|
|
key = trim(key)
|
|
if (key == "") {
|
|
next
|
|
}
|
|
|
|
value = substr($0, index($0, "=") + 1)
|
|
value = trim(value)
|
|
|
|
if (!(key in seen)) {
|
|
order[++count] = key
|
|
seen[key] = 1
|
|
}
|
|
|
|
values[key] = value
|
|
}
|
|
|
|
END {
|
|
for (i = 1; i <= count; i++) {
|
|
key = order[i]
|
|
print key "=" values[key]
|
|
}
|
|
}
|
|
' "$DEFAULT_ENV_FILE" "$USER_ENV_FILE" >"$MERGED_ENV_FILE"
|
|
}
|
|
|
|
set_merged_env_value() {
|
|
local key="$1"
|
|
local value="$2"
|
|
local temp_file
|
|
|
|
temp_file="$(mktemp "${TMPDIR:-/tmp}/dify-compose-env.XXXXXX")"
|
|
awk -F= -v target="$key" -v replacement="$key=$value" '
|
|
BEGIN { replaced = 0 }
|
|
/^[[:space:]]*#/ || !/=/{ print; next }
|
|
{
|
|
key = $1
|
|
gsub(/^[[:space:]]+|[[:space:]]+$/, "", key)
|
|
if (key == target) {
|
|
if (!replaced) {
|
|
print replacement
|
|
replaced = 1
|
|
}
|
|
next
|
|
}
|
|
print
|
|
}
|
|
END {
|
|
if (!replaced) {
|
|
print replacement
|
|
}
|
|
}
|
|
' "$MERGED_ENV_FILE" >"$temp_file"
|
|
mv "$temp_file" "$MERGED_ENV_FILE"
|
|
}
|
|
|
|
set_if_not_overridden() {
|
|
local key="$1"
|
|
local value="$2"
|
|
|
|
if user_overrides "$key"; then
|
|
return
|
|
fi
|
|
|
|
set_merged_env_value "$key" "$value"
|
|
}
|
|
|
|
metadata_db_host() {
|
|
case "$1" in
|
|
mysql) printf 'db_mysql' ;;
|
|
postgresql | '') printf 'db_postgres' ;;
|
|
*) printf '%s' "$(env_value DB_HOST)" ;;
|
|
esac
|
|
}
|
|
|
|
metadata_db_port() {
|
|
case "$1" in
|
|
mysql) printf '3306' ;;
|
|
postgresql | '') printf '5432' ;;
|
|
*) printf '%s' "$(env_value DB_PORT)" ;;
|
|
esac
|
|
}
|
|
|
|
metadata_db_user() {
|
|
case "$1" in
|
|
mysql) printf 'root' ;;
|
|
postgresql | '') printf 'postgres' ;;
|
|
*) printf '%s' "$(env_value DB_USERNAME)" ;;
|
|
esac
|
|
}
|
|
|
|
build_merged_env() {
|
|
MERGED_ENV_FILE="$(mktemp "${TMPDIR:-/tmp}/dify-compose.XXXXXX")"
|
|
trap 'rm -f "$MERGED_ENV_FILE"' EXIT
|
|
|
|
write_merged_env
|
|
|
|
local db_type
|
|
local redis_host
|
|
local redis_port
|
|
local redis_username
|
|
local redis_password
|
|
local redis_auth
|
|
local code_execution_api_key
|
|
local weaviate_api_key
|
|
|
|
db_type="$(env_value DB_TYPE)"
|
|
|
|
set_if_not_overridden DB_HOST "$(metadata_db_host "$db_type")"
|
|
set_if_not_overridden DB_PORT "$(metadata_db_port "$db_type")"
|
|
set_if_not_overridden DB_USERNAME "$(metadata_db_user "$db_type")"
|
|
|
|
if ! user_overrides CELERY_BROKER_URL; then
|
|
redis_host="$(env_value REDIS_HOST)"
|
|
redis_port="$(env_value REDIS_PORT)"
|
|
redis_username="$(env_value REDIS_USERNAME)"
|
|
redis_password="$(env_value REDIS_PASSWORD)"
|
|
redis_auth=""
|
|
|
|
if [[ -n "$redis_username" && -n "$redis_password" ]]; then
|
|
redis_auth="${redis_username}:${redis_password}@"
|
|
elif [[ -n "$redis_password" ]]; then
|
|
redis_auth=":${redis_password}@"
|
|
elif [[ -n "$redis_username" ]]; then
|
|
redis_auth="${redis_username}@"
|
|
fi
|
|
|
|
set_merged_env_value CELERY_BROKER_URL "redis://${redis_auth}${redis_host:-redis}:${redis_port:-6379}/1"
|
|
fi
|
|
|
|
if ! user_overrides SANDBOX_API_KEY; then
|
|
code_execution_api_key="$(env_value CODE_EXECUTION_API_KEY)"
|
|
set_if_not_overridden SANDBOX_API_KEY "${code_execution_api_key:-dify-sandbox}"
|
|
fi
|
|
|
|
if ! user_overrides WEAVIATE_AUTHENTICATION_APIKEY_ALLOWED_KEYS; then
|
|
weaviate_api_key="$(env_value WEAVIATE_API_KEY)"
|
|
set_if_not_overridden WEAVIATE_AUTHENTICATION_APIKEY_ALLOWED_KEYS \
|
|
"${weaviate_api_key:-WVF5YThaHlkYwhGUSmCRgsX3tD5ngdN8pkih}"
|
|
fi
|
|
}
|
|
|
|
main() {
|
|
detect_compose
|
|
ensure_env_files
|
|
ensure_secret_key
|
|
build_merged_env
|
|
|
|
if [[ "$#" -eq 0 ]]; then
|
|
set -- up -d
|
|
fi
|
|
|
|
"${COMPOSE_CMD[@]}" --env-file "$MERGED_ENV_FILE" "$@"
|
|
}
|
|
|
|
main "$@"
|