mirror of
https://github.com/langgenius/dify.git
synced 2026-05-08 18:00:56 -04:00
318 lines
8.6 KiB
PowerShell
318 lines
8.6 KiB
PowerShell
$ErrorActionPreference = "Stop"
|
|
Set-StrictMode -Version Latest
|
|
|
|
$ScriptDir = Split-Path -Parent $MyInvocation.MyCommand.Path
|
|
Set-Location $ScriptDir
|
|
|
|
$DefaultEnvFile = ".env.default"
|
|
$UserEnvFile = ".env"
|
|
$MergedEnvFile = $null
|
|
$Utf8NoBom = New-Object System.Text.UTF8Encoding -ArgumentList $false
|
|
|
|
function Write-Info {
|
|
param([string]$Message)
|
|
[Console]::Error.WriteLine($Message)
|
|
}
|
|
|
|
function Fail {
|
|
param([string]$Message)
|
|
[Console]::Error.WriteLine("Error: $Message")
|
|
exit 1
|
|
}
|
|
|
|
function Test-CommandSuccess {
|
|
param([string[]]$Command)
|
|
|
|
try {
|
|
$Executable = $Command[0]
|
|
$CommandArgs = @()
|
|
if ($Command.Length -gt 1) {
|
|
$CommandArgs = @($Command[1..($Command.Length - 1)])
|
|
}
|
|
|
|
& $Executable @CommandArgs *> $null
|
|
return $LASTEXITCODE -eq 0
|
|
}
|
|
catch {
|
|
return $false
|
|
}
|
|
}
|
|
|
|
function Get-ComposeCommand {
|
|
if (Test-CommandSuccess @("docker", "compose", "version")) {
|
|
return @("docker", "compose")
|
|
}
|
|
|
|
if ((Get-Command "docker-compose" -ErrorAction SilentlyContinue) -and (Test-CommandSuccess @("docker-compose", "version"))) {
|
|
return @("docker-compose")
|
|
}
|
|
|
|
Fail "Docker Compose is not available. Install Docker Compose, then run this command again."
|
|
}
|
|
|
|
function New-SecretKey {
|
|
$Bytes = New-Object byte[] 42
|
|
$Generator = [System.Security.Cryptography.RandomNumberGenerator]::Create()
|
|
|
|
try {
|
|
$Generator.GetBytes($Bytes)
|
|
}
|
|
finally {
|
|
$Generator.Dispose()
|
|
}
|
|
|
|
return [Convert]::ToBase64String($Bytes)
|
|
}
|
|
|
|
function Ensure-EnvFiles {
|
|
if (-not (Test-Path $DefaultEnvFile -PathType Leaf)) {
|
|
Fail "$DefaultEnvFile is missing."
|
|
}
|
|
|
|
if (Test-Path $UserEnvFile -PathType Leaf) {
|
|
return
|
|
}
|
|
|
|
New-Item -ItemType File -Path $UserEnvFile | Out-Null
|
|
|
|
if ([Console]::IsInputRedirected) {
|
|
Write-Info "Created $UserEnvFile for local overrides."
|
|
return
|
|
}
|
|
|
|
Write-Info "Created $UserEnvFile for local overrides."
|
|
$Answer = Read-Host "Do you need a custom deployment now? (Most users can press Enter to skip.) [y/N]"
|
|
|
|
if ($Answer -match "^(y|yes)$") {
|
|
Write-Output "Edit .env with the settings you want to override, using .env.example as the full reference."
|
|
Write-Output "Run .\dify-compose.ps1 up -d again when you are ready."
|
|
exit 0
|
|
}
|
|
}
|
|
|
|
function Read-EnvFile {
|
|
param([string]$Path)
|
|
|
|
$Values = [ordered]@{}
|
|
|
|
if (-not (Test-Path $Path -PathType Leaf)) {
|
|
return $Values
|
|
}
|
|
|
|
foreach ($Line in Get-Content -Path $Path) {
|
|
if ($Line -match "^\s*#" -or $Line -notmatch "=") {
|
|
continue
|
|
}
|
|
|
|
$SeparatorIndex = $Line.IndexOf("=")
|
|
$Key = $Line.Substring(0, $SeparatorIndex).Trim()
|
|
$Value = $Line.Substring($SeparatorIndex + 1).Trim()
|
|
|
|
if (($Value.StartsWith('"') -and $Value.EndsWith('"')) -or ($Value.StartsWith("'") -and $Value.EndsWith("'"))) {
|
|
$Value = $Value.Substring(1, $Value.Length - 2)
|
|
}
|
|
|
|
if ($Key.Length -gt 0) {
|
|
$Values[$Key] = $Value
|
|
}
|
|
}
|
|
|
|
return $Values
|
|
}
|
|
|
|
function Set-UserEnvValue {
|
|
param(
|
|
[string]$Key,
|
|
[string]$Value
|
|
)
|
|
|
|
$Path = [string](Resolve-Path $UserEnvFile)
|
|
$Lines = [System.IO.File]::ReadAllLines($Path, [System.Text.Encoding]::UTF8)
|
|
$Output = New-Object System.Collections.Generic.List[string]
|
|
$Replaced = $false
|
|
|
|
foreach ($Line in $Lines) {
|
|
if ($Line -match "^\s*#" -or $Line -notmatch "=") {
|
|
$Output.Add($Line)
|
|
continue
|
|
}
|
|
|
|
$SeparatorIndex = $Line.IndexOf("=")
|
|
$CurrentKey = $Line.Substring(0, $SeparatorIndex).Trim()
|
|
|
|
if ($CurrentKey -eq $Key) {
|
|
if (-not $Replaced) {
|
|
$Output.Add("$Key=$Value")
|
|
$Replaced = $true
|
|
}
|
|
continue
|
|
}
|
|
|
|
$Output.Add($Line)
|
|
}
|
|
|
|
if (-not $Replaced) {
|
|
$Output.Add("$Key=$Value")
|
|
}
|
|
|
|
[System.IO.File]::WriteAllLines($Path, $Output, $Utf8NoBom)
|
|
}
|
|
|
|
function Ensure-SecretKey {
|
|
$Values = Read-EnvFile $UserEnvFile
|
|
|
|
if ($Values.Contains("SECRET_KEY") -and $Values["SECRET_KEY"]) {
|
|
return
|
|
}
|
|
|
|
Set-UserEnvValue "SECRET_KEY" (New-SecretKey)
|
|
Write-Info "Generated SECRET_KEY in $UserEnvFile."
|
|
}
|
|
|
|
function Merge-EnvValues {
|
|
$Values = [ordered]@{}
|
|
|
|
foreach ($Entry in (Read-EnvFile $DefaultEnvFile).GetEnumerator()) {
|
|
$Values[$Entry.Key] = $Entry.Value
|
|
}
|
|
|
|
foreach ($Entry in (Read-EnvFile $UserEnvFile).GetEnumerator()) {
|
|
$Values[$Entry.Key] = $Entry.Value
|
|
}
|
|
|
|
return $Values
|
|
}
|
|
|
|
function User-Overrides {
|
|
param([string]$Key)
|
|
|
|
if (-not (Test-Path $UserEnvFile -PathType Leaf)) {
|
|
return $false
|
|
}
|
|
|
|
return [bool](Select-String -Path $UserEnvFile -Pattern "^\s*$([regex]::Escape($Key))\s*=" -Quiet)
|
|
}
|
|
|
|
function Metadata-DbHost {
|
|
param([string]$DbType, $Values)
|
|
|
|
switch ($DbType) {
|
|
"mysql" { return "db_mysql" }
|
|
"postgresql" { return "db_postgres" }
|
|
"" { return "db_postgres" }
|
|
default { return $Values["DB_HOST"] }
|
|
}
|
|
}
|
|
|
|
function Metadata-DbPort {
|
|
param([string]$DbType, $Values)
|
|
|
|
switch ($DbType) {
|
|
"mysql" { return "3306" }
|
|
"postgresql" { return "5432" }
|
|
"" { return "5432" }
|
|
default { return $Values["DB_PORT"] }
|
|
}
|
|
}
|
|
|
|
function Metadata-DbUser {
|
|
param([string]$DbType, $Values)
|
|
|
|
switch ($DbType) {
|
|
"mysql" { return "root" }
|
|
"postgresql" { return "postgres" }
|
|
"" { return "postgres" }
|
|
default { return $Values["DB_USERNAME"] }
|
|
}
|
|
}
|
|
|
|
function Write-MergedEnv {
|
|
param($Values)
|
|
|
|
$Output = New-Object System.Collections.Generic.List[string]
|
|
|
|
foreach ($Entry in $Values.GetEnumerator()) {
|
|
$Output.Add("$($Entry.Key)=$($Entry.Value)")
|
|
}
|
|
|
|
[System.IO.File]::WriteAllLines($MergedEnvFile, $Output, $Utf8NoBom)
|
|
}
|
|
|
|
function Build-MergedEnv {
|
|
$Values = Merge-EnvValues
|
|
$script:MergedEnvFile = [System.IO.Path]::GetTempFileName()
|
|
|
|
$DbType = if ($Values.Contains("DB_TYPE")) { $Values["DB_TYPE"] } else { "postgresql" }
|
|
|
|
if (-not (User-Overrides "DB_HOST")) {
|
|
$Values["DB_HOST"] = Metadata-DbHost $DbType $Values
|
|
}
|
|
|
|
if (-not (User-Overrides "DB_PORT")) {
|
|
$Values["DB_PORT"] = Metadata-DbPort $DbType $Values
|
|
}
|
|
|
|
if (-not (User-Overrides "DB_USERNAME")) {
|
|
$Values["DB_USERNAME"] = Metadata-DbUser $DbType $Values
|
|
}
|
|
|
|
if (-not (User-Overrides "CELERY_BROKER_URL")) {
|
|
$RedisHost = if ($Values.Contains("REDIS_HOST") -and $Values["REDIS_HOST"]) { $Values["REDIS_HOST"] } else { "redis" }
|
|
$RedisPort = if ($Values.Contains("REDIS_PORT") -and $Values["REDIS_PORT"]) { $Values["REDIS_PORT"] } else { "6379" }
|
|
$RedisUsername = if ($Values.Contains("REDIS_USERNAME")) { $Values["REDIS_USERNAME"] } else { "" }
|
|
$RedisPassword = if ($Values.Contains("REDIS_PASSWORD")) { $Values["REDIS_PASSWORD"] } else { "" }
|
|
$RedisAuth = ""
|
|
|
|
if ($RedisUsername -and $RedisPassword) {
|
|
$RedisAuth = "${RedisUsername}:${RedisPassword}@"
|
|
}
|
|
elseif ($RedisPassword) {
|
|
$RedisAuth = ":${RedisPassword}@"
|
|
}
|
|
elseif ($RedisUsername) {
|
|
$RedisAuth = "${RedisUsername}@"
|
|
}
|
|
|
|
$Values["CELERY_BROKER_URL"] = "redis://$RedisAuth${RedisHost}:${RedisPort}/1"
|
|
}
|
|
|
|
if (-not (User-Overrides "SANDBOX_API_KEY")) {
|
|
$CodeExecutionApiKey = if ($Values.Contains("CODE_EXECUTION_API_KEY") -and $Values["CODE_EXECUTION_API_KEY"]) { $Values["CODE_EXECUTION_API_KEY"] } else { "dify-sandbox" }
|
|
$Values["SANDBOX_API_KEY"] = $CodeExecutionApiKey
|
|
}
|
|
|
|
if (-not (User-Overrides "WEAVIATE_AUTHENTICATION_APIKEY_ALLOWED_KEYS")) {
|
|
$WeaviateApiKey = if ($Values.Contains("WEAVIATE_API_KEY") -and $Values["WEAVIATE_API_KEY"]) { $Values["WEAVIATE_API_KEY"] } else { "WVF5YThaHlkYwhGUSmCRgsX3tD5ngdN8pkih" }
|
|
$Values["WEAVIATE_AUTHENTICATION_APIKEY_ALLOWED_KEYS"] = $WeaviateApiKey
|
|
}
|
|
|
|
Write-MergedEnv $Values
|
|
}
|
|
|
|
$ComposeCommand = Get-ComposeCommand
|
|
|
|
try {
|
|
Ensure-EnvFiles
|
|
Ensure-SecretKey
|
|
Build-MergedEnv
|
|
|
|
$ComposeArgs = @($args)
|
|
if ($ComposeArgs.Count -eq 0) {
|
|
$ComposeArgs = @("up", "-d")
|
|
}
|
|
|
|
$ComposeCommandArgs = @()
|
|
if ($ComposeCommand.Length -gt 1) {
|
|
$ComposeCommandArgs = @($ComposeCommand[1..($ComposeCommand.Length - 1)])
|
|
}
|
|
|
|
$ComposeExecutable = $ComposeCommand[0]
|
|
& $ComposeExecutable @ComposeCommandArgs --env-file $MergedEnvFile @ComposeArgs
|
|
exit $LASTEXITCODE
|
|
}
|
|
finally {
|
|
if ($MergedEnvFile -and (Test-Path $MergedEnvFile -PathType Leaf)) {
|
|
Remove-Item -Force $MergedEnvFile
|
|
}
|
|
}
|