Ajout d'une partie mise à jour automatique : plus besoin de docker pull en ligne de commande ; on peut passer par l'interface Refactoring partie Java pour respecter d'avantage le DDD : plus de jackson dans la partie domain Passage version 0.6.6
241 lines
8.5 KiB
PowerShell
241 lines
8.5 KiB
PowerShell
#Requires -Version 5.1
|
|
<#
|
|
.SYNOPSIS
|
|
Installeur LoreMindMJ pour Windows 10/11.
|
|
.DESCRIPTION
|
|
- Verifie / installe WSL2 et Docker Desktop (via winget)
|
|
- Genere un .env avec mots de passe aleatoires
|
|
- Recupere le docker-compose.yml officiel
|
|
- Lance la stack et ouvre le navigateur
|
|
.EXAMPLE
|
|
iwr https://git.igmlcreation.fr/ietm64/loremind/raw/branch/main/installers/install.ps1 | iex
|
|
#>
|
|
|
|
[CmdletBinding()]
|
|
param(
|
|
[string]$InstallDir = "$env:LOCALAPPDATA\LoreMind",
|
|
[string]$ComposeUrl = "https://git.igmlcreation.fr/ietm64/loremind/raw/branch/main/docker-compose.yml",
|
|
[int]$WebPort = 8081,
|
|
[switch]$NonInteractive
|
|
)
|
|
|
|
$ErrorActionPreference = 'Stop'
|
|
|
|
function Write-Step($msg) { Write-Host "==> $msg" -ForegroundColor Cyan }
|
|
function Write-Ok($msg) { Write-Host " OK $msg" -ForegroundColor Green }
|
|
function Write-Warn2($msg) { Write-Host " !! $msg" -ForegroundColor Yellow }
|
|
function Write-Err($msg) { Write-Host " XX $msg" -ForegroundColor Red }
|
|
|
|
function Test-Admin {
|
|
$current = [Security.Principal.WindowsIdentity]::GetCurrent()
|
|
return ([Security.Principal.WindowsPrincipal]$current).IsInRole(
|
|
[Security.Principal.WindowsBuiltInRole]::Administrator)
|
|
}
|
|
|
|
function Invoke-Elevated {
|
|
Write-Step "Relance en mode administrateur..."
|
|
$args = @('-NoProfile','-ExecutionPolicy','Bypass','-File',$PSCommandPath)
|
|
Start-Process powershell -Verb RunAs -ArgumentList $args
|
|
exit
|
|
}
|
|
|
|
function New-RandomSecret([int]$Length = 32) {
|
|
$bytes = New-Object byte[] $Length
|
|
[System.Security.Cryptography.RandomNumberGenerator]::Create().GetBytes($bytes)
|
|
return ([BitConverter]::ToString($bytes) -replace '-','').ToLower().Substring(0, $Length)
|
|
}
|
|
|
|
function Test-Wsl2 {
|
|
try {
|
|
$out = wsl.exe --status 2>$null
|
|
return ($LASTEXITCODE -eq 0)
|
|
} catch { return $false }
|
|
}
|
|
|
|
function Test-Docker {
|
|
$cmd = Get-Command docker -ErrorAction SilentlyContinue
|
|
if (-not $cmd) { return $false }
|
|
docker info *>$null
|
|
return ($LASTEXITCODE -eq 0)
|
|
}
|
|
|
|
function Wait-Docker([int]$TimeoutSec = 180) {
|
|
Write-Step "Attente du demarrage de Docker Desktop (max ${TimeoutSec}s)..."
|
|
$deadline = (Get-Date).AddSeconds($TimeoutSec)
|
|
while ((Get-Date) -lt $deadline) {
|
|
docker info *>$null
|
|
if ($LASTEXITCODE -eq 0) { Write-Ok "Docker repond"; return $true }
|
|
Start-Sleep -Seconds 3
|
|
}
|
|
return $false
|
|
}
|
|
|
|
# ---------------------------------------------------------------------------
|
|
# 0. Pre-requis admin
|
|
# ---------------------------------------------------------------------------
|
|
if (-not (Test-Admin)) { Invoke-Elevated }
|
|
|
|
Write-Host ""
|
|
Write-Host "============================================================"
|
|
Write-Host " LoreMindMJ - Installeur Windows" -ForegroundColor Magenta
|
|
Write-Host "============================================================"
|
|
Write-Host ""
|
|
|
|
# ---------------------------------------------------------------------------
|
|
# 1. WSL2
|
|
# ---------------------------------------------------------------------------
|
|
Write-Step "Verification de WSL2..."
|
|
if (Test-Wsl2) {
|
|
Write-Ok "WSL2 deja installe"
|
|
} else {
|
|
Write-Warn2 "WSL2 absent - installation en cours"
|
|
wsl.exe --install --no-launch
|
|
Write-Warn2 "REDEMARRAGE REQUIS. Relancez ce script apres reboot."
|
|
Read-Host "Appuyez sur Entree pour quitter"
|
|
exit 1
|
|
}
|
|
|
|
# ---------------------------------------------------------------------------
|
|
# 2. Docker Desktop
|
|
# ---------------------------------------------------------------------------
|
|
Write-Step "Verification de Docker Desktop..."
|
|
if (Test-Docker) {
|
|
Write-Ok "Docker fonctionnel"
|
|
} else {
|
|
if (-not (Get-Command winget -ErrorAction SilentlyContinue)) {
|
|
Write-Err "winget introuvable. Installez Docker Desktop manuellement : https://www.docker.com/products/docker-desktop/"
|
|
exit 1
|
|
}
|
|
Write-Warn2 "Installation de Docker Desktop via winget..."
|
|
winget install --id Docker.DockerDesktop -e --accept-package-agreements --accept-source-agreements
|
|
if ($LASTEXITCODE -ne 0) { Write-Err "Echec winget"; exit 1 }
|
|
|
|
Write-Step "Lancement de Docker Desktop..."
|
|
$dd = "$env:ProgramFiles\Docker\Docker\Docker Desktop.exe"
|
|
if (Test-Path $dd) { Start-Process $dd }
|
|
|
|
if (-not (Wait-Docker 240)) {
|
|
Write-Err "Docker n'a pas demarre. Lancez-le manuellement puis relancez ce script."
|
|
exit 1
|
|
}
|
|
}
|
|
|
|
# ---------------------------------------------------------------------------
|
|
# 3. Dossier d'installation + docker-compose.yml
|
|
# ---------------------------------------------------------------------------
|
|
Write-Step "Preparation du dossier $InstallDir"
|
|
New-Item -ItemType Directory -Force -Path $InstallDir | Out-Null
|
|
Set-Location $InstallDir
|
|
|
|
$composePath = Join-Path $InstallDir 'docker-compose.yml'
|
|
Write-Step "Telechargement de docker-compose.yml"
|
|
Invoke-WebRequest -Uri $ComposeUrl -OutFile $composePath -UseBasicParsing
|
|
Write-Ok "docker-compose.yml recupere"
|
|
|
|
# ---------------------------------------------------------------------------
|
|
# 4. Generation du .env
|
|
# ---------------------------------------------------------------------------
|
|
$envPath = Join-Path $InstallDir '.env'
|
|
if (Test-Path $envPath) {
|
|
Write-Warn2 ".env deja present - sauvegarde en .env.bak"
|
|
Copy-Item $envPath "$envPath.bak" -Force
|
|
}
|
|
|
|
Write-Step "Configuration"
|
|
|
|
$adminUser = if ($NonInteractive) { 'admin' } else {
|
|
$r = Read-Host " Nom d'utilisateur admin [admin]"; if ([string]::IsNullOrWhiteSpace($r)) { 'admin' } else { $r }
|
|
}
|
|
$adminPass = if ($NonInteractive) { New-RandomSecret 16 } else {
|
|
$r = Read-Host " Mot de passe admin (vide = genere automatiquement)"
|
|
if ([string]::IsNullOrWhiteSpace($r)) { New-RandomSecret 16 } else { $r }
|
|
}
|
|
|
|
$llmProvider = if ($NonInteractive) { 'ollama' } else {
|
|
$r = Read-Host " Provider LLM : [ollama] / onemin"
|
|
if ($r -eq 'onemin') { 'onemin' } else { 'ollama' }
|
|
}
|
|
$onemKey = ''
|
|
if ($llmProvider -eq 'onemin' -and -not $NonInteractive) {
|
|
$onemKey = Read-Host " Cle API 1min.ai"
|
|
}
|
|
|
|
$autoUpdate = if ($NonInteractive) { $true } else {
|
|
$r = Read-Host " Activer les mises a jour auto (chaque nuit a 4h) ? [O/n]"
|
|
-not ($r -match '^(n|N|no|non)$')
|
|
}
|
|
$composeProfiles = if ($autoUpdate) { 'autoupdate' } else { '' }
|
|
|
|
$envContent = @"
|
|
# Genere par install.ps1 le $(Get-Date -Format 'yyyy-MM-dd HH:mm')
|
|
REGISTRY=git.igmlcreation.fr
|
|
TAG=latest
|
|
|
|
WEB_PORT=$WebPort
|
|
|
|
POSTGRES_DB=loremind
|
|
POSTGRES_USER=loremind
|
|
POSTGRES_PASSWORD=$(New-RandomSecret 24)
|
|
|
|
ADMIN_USERNAME=$adminUser
|
|
ADMIN_PASSWORD=$adminPass
|
|
|
|
BRAIN_INTERNAL_SECRET=$(New-RandomSecret 32)
|
|
|
|
MINIO_USER=minioadmin
|
|
MINIO_PASSWORD=$(New-RandomSecret 24)
|
|
|
|
LLM_PROVIDER=$llmProvider
|
|
OLLAMA_BASE_URL=http://host.docker.internal:11434
|
|
LLM_MODEL=gemma4:26b
|
|
ONEMIN_API_KEY=$onemKey
|
|
ONEMIN_MODEL=gpt-4o-mini
|
|
|
|
COMPOSE_PROFILES=$composeProfiles
|
|
WATCHTOWER_TOKEN=$(New-RandomSecret 32)
|
|
WATCHTOWER_MONITOR_ONLY=false
|
|
WATCHTOWER_SCHEDULE=0 0 4 * * *
|
|
TZ=Europe/Paris
|
|
"@
|
|
|
|
Set-Content -Path $envPath -Value $envContent -Encoding UTF8
|
|
Write-Ok ".env genere ($envPath)"
|
|
|
|
# ---------------------------------------------------------------------------
|
|
# 5. Pull + up
|
|
# ---------------------------------------------------------------------------
|
|
Write-Step "Telechargement des images Docker (peut prendre quelques minutes)"
|
|
docker compose pull
|
|
if ($LASTEXITCODE -ne 0) { Write-Err "Echec docker compose pull"; exit 1 }
|
|
|
|
Write-Step "Demarrage de la stack"
|
|
docker compose up -d
|
|
if ($LASTEXITCODE -ne 0) { Write-Err "Echec docker compose up"; exit 1 }
|
|
|
|
# ---------------------------------------------------------------------------
|
|
# 6. Recap
|
|
# ---------------------------------------------------------------------------
|
|
$url = "http://localhost:$WebPort"
|
|
Write-Host ""
|
|
Write-Host "============================================================" -ForegroundColor Green
|
|
Write-Host " LoreMindMJ est lance !" -ForegroundColor Green
|
|
Write-Host "============================================================" -ForegroundColor Green
|
|
Write-Host " URL : $url"
|
|
Write-Host " Identifiant : $adminUser"
|
|
Write-Host " Mot de passe : $adminPass"
|
|
Write-Host " Dossier : $InstallDir"
|
|
if ($autoUpdate) {
|
|
Write-Host " Auto-update : active (chaque nuit a 4h via Watchtower)" -ForegroundColor Green
|
|
} else {
|
|
Write-Host " Auto-update : desactive (mise a jour manuelle uniquement)"
|
|
}
|
|
Write-Host ""
|
|
Write-Host " Commandes utiles (depuis $InstallDir) :"
|
|
Write-Host " docker compose ps # etat"
|
|
Write-Host " docker compose logs -f # logs"
|
|
Write-Host " docker compose down # arret"
|
|
Write-Host " docker compose pull && docker compose up -d # mise a jour"
|
|
Write-Host ""
|
|
|
|
Start-Process $url
|