From 02473fafbfd563d2f5109708cacfbe127b82f570 Mon Sep 17 00:00:00 2001 From: Fabrice Date: Fri, 9 Oct 2026 16:59:27 +0000 Subject: [PATCH] =?UTF-8?q?Administration=20dans=20un=20conteneur=20Docker?= =?UTF-8?q?=20(Dockerfile,=20exemples=20compose=20et=20nginx)=20;=20arr?= =?UTF-8?q?=C3=AAt=20propre=20sur=20SIGTERM?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Co-Authored-By: Claude Opus 5.5 Claude-Session: https://claude.ai/code/session_01Mf2kATMtqVABHSYdxJMnim --- .dockerignore | 8 ++++++++ Dockerfile | 24 ++++++++++++++++++++++++ README.md | 11 +++++++++++ exemples/docker-compose.yml | 29 +++++++++++++++++++++++++++++ exemples/nginx-admin.conf | 14 ++++++++------ rtg/interface/serveur.py | 11 +++++++++-- 6 files changed, 89 insertions(+), 8 deletions(-) create mode 100644 .dockerignore create mode 100644 Dockerfile create mode 100644 exemples/docker-compose.yml diff --git a/.dockerignore b/.dockerignore new file mode 100644 index 0000000..66c6d0a --- /dev/null +++ b/.dockerignore @@ -0,0 +1,8 @@ +.git +Scripts +tests +exemples +**/__pycache__ +*.egg-info +build +dist diff --git a/Dockerfile b/Dockerfile new file mode 100644 index 0000000..5e2cdcb --- /dev/null +++ b/Dockerfile @@ -0,0 +1,24 @@ +# Interface RTG en conteneur, derrière le nginx du site +# (README, « L'administration dans Docker »). +FROM python:3.12-slim + +# ffmpeg (libx265, libx264), exiftool, fuseaux horaires +RUN apt-get update \ + && apt-get install -y --no-install-recommends ffmpeg libimage-exiftool-perl tzdata \ + && rm -rf /var/lib/apt/lists/* + +WORKDIR /app +COPY pyproject.toml README.md ./ +COPY rtg ./rtg +RUN pip install --no-cache-dir . && rtg verifier + +# Mot de passe (acces.toml) : /config/rtg, à monter depuis le Mac. +# Le conteneur voit les disques du Mac sous /Volumes, aux mêmes chemins que +# le Mac : les sources notées dans les voyage.toml restent valables. +ENV XDG_CONFIG_HOME=/config TZ=Europe/Paris PYTHONUNBUFFERED=1 \ + RTG_RACINE=/Volumes/CLEROADTRIPS/Road-Trips RTG_PREFIXE=/admin +EXPOSE 8765 + +# Aucun port publié : seul le nginx du site (même réseau Docker) le joint. +CMD exec rtg --racine "$RTG_RACINE" interface --proxy --prefixe "$RTG_PREFIXE" \ + --ecoute 0.0.0.0 --sans-navigateur diff --git a/README.md b/README.md index 6e5590f..44a1bc3 100644 --- a/README.md +++ b/README.md @@ -181,6 +181,17 @@ Pour administrer le site depuis son adresse publique (bouton « Connexion » en ``` 4. Dans l'interface, Réglages → « Administration depuis le site » : adresse `/admin/`. Après « Refaire l'accueil », le bouton « Connexion » apparaît sur la page d'accueil. +### L'administration dans Docker + +Plutôt que de laisser `rtg interface` ouvert dans un Terminal, on peut le faire tourner dans un conteneur, à côté du nginx du site : il démarre avec Docker et redémarre tout seul. Le `Dockerfile` est à la racine de RoadTripsGenerator (Python, ffmpeg, exiftool). + +1. Définir le mot de passe sur le Mac, une fois : `rtg mot-de-passe`. Le conteneur lit le même fichier. +2. Ajouter le service `rtg` au `docker-compose.yml` du site : voir `exemples/docker-compose.yml`. Le conteneur voit `/Volumes` aux mêmes chemins que le Mac : la clé, le disque des rushs… Les sources notées dans les `voyage.toml` restent donc valables. +3. Dans `nginx.conf`, faire pointer `/admin/` vers ce conteneur : voir `exemples/nginx-admin.conf`. Le site reste en ligne même si le conteneur RTG est arrêté. +4. `docker compose up -d --build`. + +Après une mise à jour de RTG : `docker compose up -d --build rtg`. Un disque branché après le démarrage du conteneur peut demander `docker compose restart rtg`. L'encodage utilise les processeurs attribués à Docker (réglages de Docker Desktop, « Resources ») ; l'encodeur matériel VideoToolbox du Mac n'est pas disponible dans le conteneur. + Le bouton n'est qu'un lien : la protection est celle de l'interface (mot de passe, blocage après plusieurs essais faux, cookie de session limité à `/admin/`, envoyé seulement en HTTPS). Tout ce que fait l'interface s'écrit dans `site.toml` et les `voyage.toml`. On peut toujours utiliser les commandes ci-dessous ou modifier ces fichiers à la main. Une réécriture par l'interface conserve les valeurs mais pas les commentaires. diff --git a/exemples/docker-compose.yml b/exemples/docker-compose.yml new file mode 100644 index 0000000..5155bc7 --- /dev/null +++ b/exemples/docker-compose.yml @@ -0,0 +1,29 @@ +# docker-compose.yml du site, avec l'administration RTG dans son propre conteneur. +# Après une mise à jour de RTG : docker compose up -d --build rtg +services: + roadtrip: + image: nginx:alpine + restart: unless-stopped + networks: + - ouaibe_network + volumes: + - /Volumes/CLEROADTRIPS/Road-Trips:/usr/share/nginx/html:ro + - ./nginx.conf:/etc/nginx/nginx.conf:ro + labels: + - traefik.enable=true + - traefik.docker.network=ouaibe_network + - traefik.http.routers.ouaibe_roadtrip.rule=Host(`roadtrip.ouaibe.fr`) || Host(`roadtrips.ouaibe.fr`) + - traefik.http.routers.ouaibe_roadtrip.entrypoints=websecure + + rtg: + build: /Volumes/CLEROADTRIPS/RoadTripsGenerator + restart: unless-stopped + networks: + - ouaibe_network + volumes: + - /Volumes:/Volumes # la clé, le LaCie… aux mêmes chemins que sur le Mac + - ${HOME}/.config/rtg:/config/rtg # le mot de passe défini avec « rtg mot-de-passe » + +networks: + ouaibe_network: + external: true diff --git a/exemples/nginx-admin.conf b/exemples/nginx-admin.conf index 7db8a42..32adcdb 100644 --- a/exemples/nginx-admin.conf +++ b/exemples/nginx-admin.conf @@ -1,15 +1,17 @@ # Bloc à ajouter dans nginx.conf, à l'intérieur de « server { … } », quand le # site est servi par un conteneur nginx derrière Traefik (Traefik → nginx → RTG). -# RTG tourne sur le Mac : rtg interface --proxy --prefixe /admin -# -# Dans docker-compose.yml, sous le service nginx, ajouter aussi : -# extra_hosts: -# - "host.docker.internal:host-gateway" # « ^~ » : sinon une règle du type « location ~* \.(js|css|png)$ » déjà # présente dans nginx.conf prendrait les fichiers de l'interface pour ceux du site. location ^~ /admin/ { - proxy_pass http://host.docker.internal:8765; + # RTG dans le conteneur « rtg » (exemples/docker-compose.yml). Passer par + # une variable laisse nginx démarrer même si ce conteneur est arrêté. + resolver 127.0.0.11 valid=30s; + set $rtg http://rtg:8765; + proxy_pass $rtg; + # RTG lancé à la main sur le Mac à la place : remplacer les trois lignes + # ci-dessus par « proxy_pass http://host.docker.internal:8765; ». + proxy_set_header Host $host; # Traefik a déjà noté l'adresse du visiteur et le https : on les transmet tels quels. proxy_set_header X-Forwarded-For $http_x_forwarded_for; diff --git a/rtg/interface/serveur.py b/rtg/interface/serveur.py index e308474..0e3648b 100644 --- a/rtg/interface/serveur.py +++ b/rtg/interface/serveur.py @@ -17,12 +17,13 @@ Sécurité (voir aussi securite.py) : """ import io import json -import ssl import mimetypes import os import platform import re import shutil +import signal +import ssl import string import threading import webbrowser @@ -466,7 +467,8 @@ class Application: raccourcis = [("Dossier personnel", os.path.expanduser("~")), ("Site", self.racine)] if r.q("v"): raccourcis.append(("Ce voyage", os.path.join(self.racine, r.q("v")))) - if platform.system() == "Darwin" and os.path.isdir("/Volumes"): + # /Volumes : disques du Mac, y compris vus depuis le conteneur Docker. + if os.path.isdir("/Volumes"): raccourcis += [(d, os.path.join("/Volumes", d)) for d in sorted(os.listdir("/Volumes")) if not d.startswith(".")] elif platform.system() == "Windows": @@ -908,6 +910,11 @@ def lancer(racine, port=8765, ouvrir=True, distant=False, certificat=None, cle=N print(" (Ctrl+C pour arrêter)") if ouvrir: threading.Timer(0.5, lambda: webbrowser.open(url)).start() + + # « docker stop » envoie SIGTERM : on s'arrête aussitôt, comme sur Ctrl+C. + def sur_sigterm(*_): + raise KeyboardInterrupt + signal.signal(signal.SIGTERM, sur_sigterm) try: serveur.serve_forever() except KeyboardInterrupt: