diff --git a/webapp/Dockerfile b/webapp/Dockerfile index 99588ae..f0cee3a 100644 --- a/webapp/Dockerfile +++ b/webapp/Dockerfile @@ -12,7 +12,7 @@ COPY requirements.txt . RUN pip install --no-cache-dir -r requirements.txt # Code applicatif -COPY app.py core.py ./ +COPY app.py core.py config.json ./ COPY static/ ./static/ # Répertoires de données (sera écrasé par le volume en production) diff --git a/webapp/app.py b/webapp/app.py index fce9311..c7b288a 100644 --- a/webapp/app.py +++ b/webapp/app.py @@ -4,6 +4,7 @@ app.py - Backend FastAPI pour planning2ics web app. import asyncio import json +import os import secrets import uuid from datetime import datetime @@ -21,8 +22,33 @@ CONFIG_PATH = Path("/app/config.json") DATA_DIR = Path("/app/data") def load_config() -> dict: - with open(CONFIG_PATH) as f: - return json.load(f) + if CONFIG_PATH.exists() and CONFIG_PATH.is_file(): + with open(CONFIG_PATH) as f: + config = json.load(f) + else: + config = { + "ollama": {"url": "", "cluster_model": "", "local_model": ""}, + "site": {"calendar_url": "", "base_url": ""}, + "auth": {"session_secret": "changez-cette-cle-secrete-en-production", "users": []}, + } + + # Les variables d'environnement ont priorité sur config.json + if os.getenv("OLLAMA_URL"): + config["ollama"]["url"] = os.environ["OLLAMA_URL"] + if os.getenv("OLLAMA_CLUSTER_MODEL"): + config["ollama"]["cluster_model"] = os.environ["OLLAMA_CLUSTER_MODEL"] + if os.getenv("OLLAMA_LOCAL_MODEL"): + config["ollama"]["local_model"] = os.environ["OLLAMA_LOCAL_MODEL"] + if os.getenv("SITE_CALENDAR_URL"): + config["site"]["calendar_url"] = os.environ["SITE_CALENDAR_URL"] + if os.getenv("SITE_BASE_URL"): + config["site"]["base_url"] = os.environ["SITE_BASE_URL"] + if os.getenv("AUTH_SESSION_SECRET"): + config["auth"]["session_secret"] = os.environ["AUTH_SESSION_SECRET"] + if os.getenv("AUTH_USERS"): + config["auth"]["users"] = json.loads(os.environ["AUTH_USERS"]) + + return config # ── App ─────────────────────────────────────────────────────────────────────── diff --git a/webapp/docker-compose.swarm.yml b/webapp/docker-compose.swarm.yml new file mode 100644 index 0000000..331bcc0 --- /dev/null +++ b/webapp/docker-compose.swarm.yml @@ -0,0 +1,40 @@ +# Déploiement Docker Swarm +# 1. Construire l'image : docker build -t git.piaf.im/sylvain/planning2ics:latest ./webapp +# 2. Déployer : docker stack deploy -c webapp/docker-compose.swarm.yml planning2ics + +services: + app: + image: git.piaf.im/sylvain/planning2ics:latest + ports: + - "8080:8000" + volumes: + - planning_data:/app/data + # Optionnel : surcharger la config avec un fichier local + # - ./config.json:/app/config.json:ro + environment: + - TZ=Europe/Paris + # Variables de configuration (priorité sur config.json embarqué) + # - OLLAMA_URL=http://192.168.7.119:11434 + # - OLLAMA_CLUSTER_MODEL=qwen3.5:cloud + # - OLLAMA_LOCAL_MODEL=qwen3:8b + # - SITE_CALENDAR_URL=https://www.opera-orchestre-montpellier.fr/calendrier/?saisons=32669 + # - SITE_BASE_URL=https://www.opera-orchestre-montpellier.fr + # - AUTH_SESSION_SECRET=changez-cette-cle-secrete-en-production + # - AUTH_USERS=[{"username":"admin","password":"changeme"}] + deploy: + replicas: 1 + restart_policy: + condition: on-failure + delay: 5s + max_attempts: 3 + update_config: + parallelism: 1 + delay: 10s + failure_action: rollback + resources: + limits: + memory: 512M + +volumes: + planning_data: + driver: local diff --git a/webapp/docker-compose.yml b/webapp/docker-compose.yml index a9e03c9..5d9e16f 100644 --- a/webapp/docker-compose.yml +++ b/webapp/docker-compose.yml @@ -1,34 +1,23 @@ -version: '3.8' - -# Déploiement Docker Swarm -# 1. Construire l'image : docker build -t planning2ics:latest ./webapp -# 2. Déployer : docker stack deploy -c webapp/docker-compose.yml planning2ics - services: app: image: git.piaf.im/sylvain/planning2ics:latest ports: - "8080:8000" volumes: - # Données persistantes (cache, jobs, uploads) - planning_data:/app/data - # Config montée en lecture seule — éditez config.json sur l'hôte - - ./config.json:/app/config.json:ro + # Optionnel : surcharger la config avec un fichier local + # - ./config.json:/app/config.json:ro environment: - TZ=Europe/Paris - deploy: - replicas: 1 - restart_policy: - condition: on-failure - delay: 5s - max_attempts: 3 - update_config: - parallelism: 1 - delay: 10s - failure_action: rollback - resources: - limits: - memory: 512M + # Variables de configuration (priorité sur config.json embarqué) + # - OLLAMA_URL=http://192.168.7.119:11434 + # - OLLAMA_CLUSTER_MODEL=qwen3.5:cloud + # - OLLAMA_LOCAL_MODEL=qwen3:8b + # - SITE_CALENDAR_URL=https://www.opera-orchestre-montpellier.fr/calendrier/?saisons=32669 + # - SITE_BASE_URL=https://www.opera-orchestre-montpellier.fr + # - AUTH_SESSION_SECRET=changez-cette-cle-secrete-en-production + # - AUTH_USERS=[{"username":"admin","password":"changeme"}] + restart: unless-stopped volumes: planning_data: