3 Commits

Author SHA1 Message Date
8d5c2e2b7f Correction pour éviter que la fenêtre ce ferme sans qu'on voit le message d'erreur
Some checks failed
E2E Tests / e2e (push) Failing after 16s
Build & Push Images / build (brain) (push) Successful in 48s
Build & Push Images / build (core) (push) Successful in 1m18s
Build & Push Images / build (web) (push) Successful in 1m24s
2026-04-25 18:37:40 +02:00
788d2c12f2 Ajout d'un .bat pour l'exécution du .ps1
Some checks failed
E2E Tests / e2e (push) Failing after 16s
2026-04-25 18:34:52 +02:00
b25a9746cf Changement sur l'installation automatique : réduction des patterns suspects dans l'installation pour les antivirus (par exemple, monter automatiquement les privilèges en admin...),
Some checks failed
E2E Tests / e2e (push) Failing after 17s
afin d'éviter que l'appli ne soit détectée comme un virus
2026-04-25 18:24:44 +02:00
4 changed files with 268 additions and 27 deletions

View File

@@ -91,6 +91,29 @@ services:
WATCHTOWER_TOKEN: ${WATCHTOWER_TOKEN:-} WATCHTOWER_TOKEN: ${WATCHTOWER_TOKEN:-}
restart: unless-stopped restart: unless-stopped
# Ollama embarque (option par defaut pour les utilisateurs sans Ollama installe).
# Active via COMPOSE_PROFILES=local-ollama (gere par l'installeur).
# Si l'utilisateur a deja Ollama sur l'hote, ce service reste inactif et
# OLLAMA_BASE_URL pointe vers http://host.docker.internal:11434.
ollama:
image: ollama/ollama:latest
container_name: loremind-ollama
profiles: ["local-ollama"]
volumes:
- ollama-data:/root/.ollama
# Port expose sur loopback uniquement pour debug / pull manuel de modeles.
ports:
- "127.0.0.1:11434:11434"
# GPU NVIDIA si disponible (silencieusement ignore sinon).
deploy:
resources:
reservations:
devices:
- driver: nvidia
count: all
capabilities: [gpu]
restart: unless-stopped
brain: brain:
image: ${REGISTRY:-git.igmlcreation.fr}/ietm64/brain:${TAG:-latest} image: ${REGISTRY:-git.igmlcreation.fr}/ietm64/brain:${TAG:-latest}
container_name: loremind-brain container_name: loremind-brain
@@ -98,7 +121,10 @@ services:
- "com.centurylinklabs.watchtower.enable=true" - "com.centurylinklabs.watchtower.enable=true"
environment: environment:
LLM_PROVIDER: ${LLM_PROVIDER:-ollama} LLM_PROVIDER: ${LLM_PROVIDER:-ollama}
OLLAMA_BASE_URL: ${OLLAMA_BASE_URL:-http://host.docker.internal:11434} # Defaut = Ollama embarque (service ollama du compose).
# L'installeur reecrit cette valeur en http://host.docker.internal:11434
# si l'utilisateur choisit le mode "Ollama deja installe sur l'hote".
OLLAMA_BASE_URL: ${OLLAMA_BASE_URL:-http://ollama:11434}
LLM_MODEL: ${LLM_MODEL:-gemma4:26b} LLM_MODEL: ${LLM_MODEL:-gemma4:26b}
ONEMIN_API_KEY: ${ONEMIN_API_KEY:-} ONEMIN_API_KEY: ${ONEMIN_API_KEY:-}
ONEMIN_MODEL: ${ONEMIN_MODEL:-gpt-4o-mini} ONEMIN_MODEL: ${ONEMIN_MODEL:-gpt-4o-mini}
@@ -154,3 +180,4 @@ volumes:
postgres-data: postgres-data:
minio-data: minio-data:
brain-data: brain-data:
ollama-data:

59
installers/install.bat Normal file
View File

@@ -0,0 +1,59 @@
@echo off
REM ============================================================================
REM LoreMindMJ - Lanceur Windows pour install.ps1
REM ----------------------------------------------------------------------------
REM Procedure :
REM 1. Clic-DROIT sur ce fichier (install.bat)
REM 2. Choisir "Executer en tant qu'administrateur"
REM 3. Accepter le prompt UAC
REM ============================================================================
setlocal
title LoreMindMJ - Installeur
echo.
echo ============================================================
echo LoreMindMJ - Installeur Windows
echo ============================================================
echo.
REM --- Verification des droits administrateur --------------------------------
net session >nul 2>&1
if %errorlevel% NEQ 0 (
echo [ERREUR] Ce script doit etre execute en tant qu'administrateur.
echo.
echo Procedure :
echo 1. Fermez cette fenetre.
echo 2. Clic-DROIT sur install.bat ^> "Executer en tant qu'administrateur".
echo 3. Acceptez le prompt UAC.
echo.
pause
exit /b 1
)
REM --- Verification de la presence d'install.ps1 -----------------------------
if not exist "%~dp0install.ps1" (
echo [ERREUR] install.ps1 introuvable dans le meme dossier que ce .bat.
echo Dossier attendu : %~dp0
echo.
pause
exit /b 1
)
REM --- Lancement du script PowerShell ----------------------------------------
REM -ExecutionPolicy Bypass : uniquement pour cette session, ne modifie pas
REM les parametres systeme.
cd /d "%~dp0"
powershell.exe -NoProfile -ExecutionPolicy Bypass -File "%~dp0install.ps1" %*
set "PS_EXIT=%errorlevel%"
echo.
if %PS_EXIT% EQU 0 (
echo Installation terminee avec succes.
) else (
echo [ATTENTION] Le script PowerShell s'est termine avec le code %PS_EXIT%.
)
echo.
pause
endlocal

View File

@@ -1,14 +1,49 @@
#Requires -Version 5.1 #Requires -Version 5.1
<# <#
.SYNOPSIS .SYNOPSIS
Installeur LoreMindMJ pour Windows 10/11. Installeur officiel de LoreMindMJ pour Windows 10/11.
.DESCRIPTION .DESCRIPTION
- Verifie / installe WSL2 et Docker Desktop (via winget) Script d'installation pas-a-pas qui :
- Genere un .env avec mots de passe aleatoires - Verifie la presence de WSL2 et Docker Desktop ; les installe via winget si absents
- Recupere le docker-compose.yml officiel - Telecharge le fichier docker-compose.yml officiel depuis le depot du projet
- Lance la stack et ouvre le navigateur - Genere un fichier .env contenant des secrets aleatoires (RNG cryptographique)
- Configure le mode Ollama (embarque dans Docker ou Ollama deja installe sur l'hote)
- Demarre la stack Docker et ouvre l'application dans le navigateur
Aucune connexion sortante n'est etablie en dehors :
- du depot officiel du projet (fichier docker-compose.yml)
- du Docker Hub / registry Docker pour les images
Le code source de ce script est public et auditable a l'adresse indiquee dans .LINK.
.PARAMETER InstallDir
Dossier d'installation. Defaut : %LOCALAPPDATA%\LoreMind
.PARAMETER ComposeUrl
URL du fichier docker-compose.yml a recuperer. Defaut : version officielle du depot.
.PARAMETER WebPort
Port HTTP local sur lequel l'application sera exposee. Defaut : 8081.
.PARAMETER NonInteractive
Mode automatique pour CI / re-installation. Utilise les valeurs par defaut.
.EXAMPLE .EXAMPLE
iwr https://git.igmlcreation.fr/ietm64/loremind/raw/branch/main/installers/install.ps1 | iex Procedure recommandee :
1. Telechargez install.ps1 dans un dossier (clic droit -> Enregistrer la cible sous).
2. Ouvrez PowerShell en tant qu'administrateur (clic droit sur PowerShell).
3. Naviguez vers le dossier : cd C:\Chemin\Vers\Le\Dossier
4. Lancez : .\install.ps1
.NOTES
Auteur : ietm64
Licence : AGPL-3.0
Projet : LoreMindMJ - assistant pour Maitres de Jeu de JDR
Version : 0.6.6
.LINK
https://git.igmlcreation.fr/ietm64/loremind
#> #>
[CmdletBinding()] [CmdletBinding()]
@@ -27,19 +62,16 @@ function Write-Warn2($msg) { Write-Host " !! $msg" -ForegroundColor Yellow }
function Write-Err($msg) { Write-Host " XX $msg" -ForegroundColor Red } function Write-Err($msg) { Write-Host " XX $msg" -ForegroundColor Red }
function Test-Admin { function Test-Admin {
# Verifie si la session courante a les droits administrateur Windows.
$current = [Security.Principal.WindowsIdentity]::GetCurrent() $current = [Security.Principal.WindowsIdentity]::GetCurrent()
return ([Security.Principal.WindowsPrincipal]$current).IsInRole( return ([Security.Principal.WindowsPrincipal]$current).IsInRole(
[Security.Principal.WindowsBuiltInRole]::Administrator) [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) { function New-RandomSecret([int]$Length = 32) {
# Genere un secret aleatoire imprimable (hex) via le RNG cryptographique
# de .NET. Utilise pour les mots de passe Postgres / MinIO / tokens internes
# afin que chaque installation ait des credentials uniques.
$bytes = New-Object byte[] $Length $bytes = New-Object byte[] $Length
[System.Security.Cryptography.RandomNumberGenerator]::Create().GetBytes($bytes) [System.Security.Cryptography.RandomNumberGenerator]::Create().GetBytes($bytes)
return ([BitConverter]::ToString($bytes) -replace '-','').ToLower().Substring(0, $Length) return ([BitConverter]::ToString($bytes) -replace '-','').ToLower().Substring(0, $Length)
@@ -71,9 +103,23 @@ function Wait-Docker([int]$TimeoutSec = 180) {
} }
# --------------------------------------------------------------------------- # ---------------------------------------------------------------------------
# 0. Pre-requis admin # 0. Verification des droits administrateur
# --------------------------------------------------------------------------- # ---------------------------------------------------------------------------
if (-not (Test-Admin)) { Invoke-Elevated } # On NE force PAS l'elevation automatique : on demande a l'utilisateur de
# relancer le script lui-meme avec les droits admin. C'est plus transparent
# et evite les avertissements antivirus liees a l'elevation silencieuse.
if (-not (Test-Admin)) {
Write-Host ""
Write-Host "Ce script doit etre execute en tant qu'administrateur." -ForegroundColor Yellow
Write-Host ""
Write-Host "Procedure :"
Write-Host " 1. Fermez cette fenetre PowerShell."
Write-Host " 2. Cliquez-droit sur l'icone PowerShell > 'Executer en tant qu'administrateur'."
Write-Host " 3. Naviguez a nouveau vers ce dossier et relancez : .\install.ps1"
Write-Host ""
Read-Host "Appuyez sur Entree pour quitter"
exit 1
}
Write-Host "" Write-Host ""
Write-Host "============================================================" Write-Host "============================================================"
@@ -106,9 +152,12 @@ if (Test-Docker) {
Write-Err "winget introuvable. Installez Docker Desktop manuellement : https://www.docker.com/products/docker-desktop/" Write-Err "winget introuvable. Installez Docker Desktop manuellement : https://www.docker.com/products/docker-desktop/"
exit 1 exit 1
} }
Write-Warn2 "Installation de Docker Desktop via winget..." Write-Warn2 "Installation de Docker Desktop via winget (gestionnaire de paquets officiel Microsoft)..."
# On invoque winget en mode interactif (l'utilisateur voit la progression).
# Les flags --accept-* sont necessaires pour ne pas bloquer sur les CGU
# (Docker Desktop a des conditions d'utilisation a accepter).
winget install --id Docker.DockerDesktop -e --accept-package-agreements --accept-source-agreements winget install --id Docker.DockerDesktop -e --accept-package-agreements --accept-source-agreements
if ($LASTEXITCODE -ne 0) { Write-Err "Echec winget"; exit 1 } if ($LASTEXITCODE -ne 0) { Write-Err "Echec de l'installation Docker Desktop via winget"; exit 1 }
Write-Step "Lancement de Docker Desktop..." Write-Step "Lancement de Docker Desktop..."
$dd = "$env:ProgramFiles\Docker\Docker\Docker Desktop.exe" $dd = "$env:ProgramFiles\Docker\Docker\Docker Desktop.exe"
@@ -128,9 +177,13 @@ New-Item -ItemType Directory -Force -Path $InstallDir | Out-Null
Set-Location $InstallDir Set-Location $InstallDir
$composePath = Join-Path $InstallDir 'docker-compose.yml' $composePath = Join-Path $InstallDir 'docker-compose.yml'
Write-Step "Telechargement de docker-compose.yml" Write-Step "Telechargement de docker-compose.yml depuis le depot officiel"
Write-Host " Source : $ComposeUrl"
# Seul telechargement reseau effectue par ce script. Aucune execution de code
# distant : le fichier est uniquement enregistre sur le disque puis passe a
# 'docker compose' pour interpretation locale.
Invoke-WebRequest -Uri $ComposeUrl -OutFile $composePath -UseBasicParsing Invoke-WebRequest -Uri $ComposeUrl -OutFile $composePath -UseBasicParsing
Write-Ok "docker-compose.yml recupere" Write-Ok "docker-compose.yml recupere ($composePath)"
# --------------------------------------------------------------------------- # ---------------------------------------------------------------------------
# 4. Generation du .env # 4. Generation du .env
@@ -160,11 +213,51 @@ if ($llmProvider -eq 'onemin' -and -not $NonInteractive) {
$onemKey = Read-Host " Cle API 1min.ai" $onemKey = Read-Host " Cle API 1min.ai"
} }
# --- Mode Ollama : embarque (defaut) vs hote -------------------------------
# Embarque : service 'ollama' du compose (profile local-ollama). Zero config reseau.
# Hote : Ollama deja installe sur la machine. Necessite OLLAMA_HOST=0.0.0.0
# pour que Docker Desktop puisse l'atteindre via host.docker.internal.
$useEmbeddedOllama = $true
$ollamaBaseUrl = 'http://ollama:11434'
if ($llmProvider -eq 'ollama') {
$useEmbeddedOllama = if ($NonInteractive) { $true } else {
$r = Read-Host " Avez-vous deja Ollama installe sur cette machine ? [o/N]"
-not ($r -match '^(o|O|y|Y|oui|yes)$')
}
if (-not $useEmbeddedOllama) {
$ollamaBaseUrl = 'http://host.docker.internal:11434'
Write-Step "Configuration d'Ollama hote..."
# Pour que le conteneur Docker puisse atteindre Ollama via host.docker.internal,
# Ollama doit ecouter sur 0.0.0.0 (et non 127.0.0.1 par defaut). On positionne
# la variable d'environnement utilisateur OLLAMA_HOST en consequence.
try {
[Environment]::SetEnvironmentVariable('OLLAMA_HOST','0.0.0.0:11434','User')
Write-Ok "Variable d'environnement utilisateur OLLAMA_HOST=0.0.0.0:11434 definie"
Write-Host ""
Write-Host " Pour que ce changement prenne effet, vous devez :" -ForegroundColor Yellow
Write-Host " 1. Quitter completement Ollama (icone systray > Quit Ollama)"
Write-Host " 2. Relancer Ollama"
Write-Host ""
Read-Host " Appuyez sur Entree une fois Ollama redemarre"
} catch {
Write-Warn2 "Impossible de definir OLLAMA_HOST automatiquement. Definissez-la manuellement (Parametres systeme > Variables d'environnement) puis redemarrez Ollama."
}
} else {
Write-Ok "Ollama sera lance dans Docker (modeles dans un volume Docker dedie)"
}
}
$llmModel = 'gemma4:26b'
$autoUpdate = if ($NonInteractive) { $true } else { $autoUpdate = if ($NonInteractive) { $true } else {
$r = Read-Host " Activer les mises a jour auto (chaque nuit a 4h) ? [O/n]" $r = Read-Host " Activer les mises a jour auto (chaque nuit a 4h) ? [O/n]"
-not ($r -match '^(n|N|no|non)$') -not ($r -match '^(n|N|no|non)$')
} }
$composeProfiles = if ($autoUpdate) { 'autoupdate' } else { '' } # Combinaison de profiles : autoupdate et/ou local-ollama (separes par virgule).
$profilesList = @()
if ($autoUpdate) { $profilesList += 'autoupdate' }
if ($useEmbeddedOllama -and $llmProvider -eq 'ollama') { $profilesList += 'local-ollama' }
$composeProfiles = $profilesList -join ','
$envContent = @" $envContent = @"
# Genere par install.ps1 le $(Get-Date -Format 'yyyy-MM-dd HH:mm') # Genere par install.ps1 le $(Get-Date -Format 'yyyy-MM-dd HH:mm')
@@ -186,8 +279,8 @@ MINIO_USER=minioadmin
MINIO_PASSWORD=$(New-RandomSecret 24) MINIO_PASSWORD=$(New-RandomSecret 24)
LLM_PROVIDER=$llmProvider LLM_PROVIDER=$llmProvider
OLLAMA_BASE_URL=http://host.docker.internal:11434 OLLAMA_BASE_URL=$ollamaBaseUrl
LLM_MODEL=gemma4:26b LLM_MODEL=$llmModel
ONEMIN_API_KEY=$onemKey ONEMIN_API_KEY=$onemKey
ONEMIN_MODEL=gpt-4o-mini ONEMIN_MODEL=gpt-4o-mini
@@ -229,6 +322,16 @@ if ($autoUpdate) {
} else { } else {
Write-Host " Auto-update : desactive (mise a jour manuelle uniquement)" Write-Host " Auto-update : desactive (mise a jour manuelle uniquement)"
} }
if ($llmProvider -eq 'ollama') {
if ($useEmbeddedOllama) {
Write-Host " Ollama : embarque (service Docker 'ollama')" -ForegroundColor Green
Write-Host ""
Write-Host " IMPORTANT : telechargez un modele avant utilisation :"
Write-Host " docker exec -it loremind-ollama ollama pull $llmModel"
} else {
Write-Host " Ollama : hote (http://host.docker.internal:11434)"
}
}
Write-Host "" Write-Host ""
Write-Host " Commandes utiles (depuis $InstallDir) :" Write-Host " Commandes utiles (depuis $InstallDir) :"
Write-Host " docker compose ps # etat" Write-Host " docker compose ps # etat"

View File

@@ -123,12 +123,54 @@ if [ "$LLM_PROVIDER" = "onemin" ] && [ "$NON_INTERACTIVE" != "1" ]; then
ONEMIN_API_KEY="$(ask "Cle API 1min.ai" "")" ONEMIN_API_KEY="$(ask "Cle API 1min.ai" "")"
fi fi
# --- Mode Ollama : embarque (defaut) vs hote -------------------------------
# Embarque : service 'ollama' du compose (profile local-ollama). Zero config reseau.
# Hote : Ollama deja installe sur la machine. Necessite OLLAMA_HOST=0.0.0.0
# via override systemd pour que le conteneur Brain l'atteigne.
USE_EMBEDDED_OLLAMA=1
OLLAMA_BASE_URL_VAL="http://ollama:11434"
LLM_MODEL_VAL="gemma4:26b"
if [ "$LLM_PROVIDER" = "ollama" ]; then
HOST_OLLAMA_REPLY="$(ask "Avez-vous deja Ollama installe sur cette machine ? [o/N]" "N")"
case "$HOST_OLLAMA_REPLY" in
o|O|y|Y|oui|yes|Oui|Yes)
USE_EMBEDDED_OLLAMA=0
OLLAMA_BASE_URL_VAL="http://host.docker.internal:11434"
step "Configuration d'Ollama hote (OLLAMA_HOST=0.0.0.0:11434)..."
if systemctl list-unit-files 2>/dev/null | grep -q '^ollama\.service'; then
sudo mkdir -p /etc/systemd/system/ollama.service.d
sudo tee /etc/systemd/system/ollama.service.d/loremind-host.conf >/dev/null <<EOF
[Service]
Environment="OLLAMA_HOST=0.0.0.0:11434"
EOF
sudo systemctl daemon-reload
sudo systemctl restart ollama
ok "Service systemd ollama redemarre avec OLLAMA_HOST=0.0.0.0:11434"
else
warn "Service systemd 'ollama' introuvable. Definissez OLLAMA_HOST=0.0.0.0:11434 manuellement avant de relancer Ollama."
fi
;;
*)
USE_EMBEDDED_OLLAMA=1
ok "Ollama sera lance dans Docker (modeles dans un volume Docker)"
;;
esac
fi
AUTO_UPDATE_REPLY="$(ask "Activer les mises a jour auto (chaque nuit a 4h) ? [O/n]" "O")" AUTO_UPDATE_REPLY="$(ask "Activer les mises a jour auto (chaque nuit a 4h) ? [O/n]" "O")"
case "$AUTO_UPDATE_REPLY" in case "$AUTO_UPDATE_REPLY" in
n|N|no|non|No|Non) COMPOSE_PROFILES="" ; AUTO_UPDATE=0 ;; n|N|no|non|No|Non) AUTO_UPDATE=0 ;;
*) COMPOSE_PROFILES="autoupdate" ; AUTO_UPDATE=1 ;; *) AUTO_UPDATE=1 ;;
esac esac
# Combinaison de profiles : autoupdate et/ou local-ollama (separes par virgule).
PROFILES_ARR=()
[ "$AUTO_UPDATE" = "1" ] && PROFILES_ARR+=("autoupdate")
if [ "$LLM_PROVIDER" = "ollama" ] && [ "$USE_EMBEDDED_OLLAMA" = "1" ]; then
PROFILES_ARR+=("local-ollama")
fi
COMPOSE_PROFILES="$(IFS=,; echo "${PROFILES_ARR[*]}")"
cat > .env <<EOF cat > .env <<EOF
# Genere par install.sh le $(date '+%Y-%m-%d %H:%M') # Genere par install.sh le $(date '+%Y-%m-%d %H:%M')
REGISTRY=git.igmlcreation.fr REGISTRY=git.igmlcreation.fr
@@ -149,8 +191,8 @@ MINIO_USER=minioadmin
MINIO_PASSWORD=$(rand_hex 24) MINIO_PASSWORD=$(rand_hex 24)
LLM_PROVIDER=${LLM_PROVIDER} LLM_PROVIDER=${LLM_PROVIDER}
OLLAMA_BASE_URL=http://host.docker.internal:11434 OLLAMA_BASE_URL=${OLLAMA_BASE_URL_VAL}
LLM_MODEL=gemma4:26b LLM_MODEL=${LLM_MODEL_VAL}
ONEMIN_API_KEY=${ONEMIN_API_KEY} ONEMIN_API_KEY=${ONEMIN_API_KEY}
ONEMIN_MODEL=gpt-4o-mini ONEMIN_MODEL=gpt-4o-mini
@@ -184,6 +226,16 @@ if [ "$AUTO_UPDATE" = "1" ]; then
else else
echo " Auto-update : desactive (mise a jour manuelle uniquement)" echo " Auto-update : desactive (mise a jour manuelle uniquement)"
fi fi
if [ "$LLM_PROVIDER" = "ollama" ]; then
if [ "$USE_EMBEDDED_OLLAMA" = "1" ]; then
echo -e " Ollama : ${c_green}embarque${c_off} (service Docker 'ollama')"
echo
echo " IMPORTANT : telechargez un modele avant utilisation :"
echo " docker exec -it loremind-ollama ollama pull ${LLM_MODEL_VAL}"
else
echo " Ollama : hote (http://host.docker.internal:11434)"
fi
fi
echo echo
echo " Commandes utiles (depuis $INSTALL_DIR) :" echo " Commandes utiles (depuis $INSTALL_DIR) :"
echo " docker compose ps # etat" echo " docker compose ps # etat"