Traefik : exemple de route /admin vers l'interface ; option --ecoute

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01Mf2kATMtqVABHSYdxJMnim
This commit is contained in:
FabriceandClaude Opus 5.5 committed 2026-10-09 15:01:09 +00:00
1 parent 4366db94ed
commit d3a8394bc1
4 files changed
+40 -6

No files matched your search

+2 -1
View File
@@ -148,7 +148,7 @@ L'interface permet de modifier le site et de lire les fichiers de l'ordinateur :
### Administration depuis le site ### Administration depuis le site
Pour administrer le site depuis son adresse publique (bouton « Connexion » en haut à droite de l'accueil, qui mène à `https://roadtrip.ouaibe.fr/admin/`), l'interface tourne sur la machine qui sert le site, derrière son serveur web en HTTPS. Les sources (rushs, traces, photos) doivent alors être accessibles depuis cette machine pour encoder et générer. Pour administrer le site depuis son adresse publique (bouton « Connexion » en haut à droite de l'accueil, qui mène à `https://roadtrips.ouaibe.fr/admin/`), l'interface tourne sur la machine qui sert le site, derrière son serveur web en HTTPS. Les sources (rushs, traces, photos) doivent alors être accessibles depuis cette machine pour encoder et générer.
1. Sur cette machine, une fois : `rtg mot-de-passe`. 1. Sur cette machine, une fois : `rtg mot-de-passe`.
2. Lancer l'interface, en permanence de préférence (service, `tmux`…) : 2. Lancer l'interface, en permanence de préférence (service, `tmux`…) :
@@ -157,6 +157,7 @@ Pour administrer le site depuis son adresse publique (bouton « Connexion » en
``` ```
Elle n'écoute que sur 127.0.0.1 : seul le serveur web peut la joindre. Le mot de passe est obligatoire. Elle n'écoute que sur 127.0.0.1 : seul le serveur web peut la joindre. Le mot de passe est obligatoire.
3. Transmettre `/admin/` à l'interface depuis le serveur web. 3. Transmettre `/admin/` à l'interface depuis le serveur web.
- Traefik : copier `exemples/traefik-rtg-admin.yml` dans le dossier de configuration dynamique de Traefik, en y mettant les mêmes `entryPoints` et `certResolver` que pour le site. Le fichier indique l'adresse à mettre selon que Traefik tourne dans Docker sur le Mac, directement sur le Mac, ou sur une autre machine (dans ce dernier cas, lancer RTG avec `--ecoute 0.0.0.0` en plus).
- nginx, dans le bloc `server` du site en HTTPS : - nginx, dans le bloc `server` du site en HTTPS :
```nginx ```nginx
location /admin/ { location /admin/ {
+27
View File
@@ -0,0 +1,27 @@
# Traefik : envoie https://roadtrips.ouaibe.fr/admin/ vers l'interface RTG.
#
# 1. Copier ce fichier dans le dossier de configuration « dynamique » de
# Traefik (celui de providers.file), à côté de la configuration du site.
# 2. Mettre ci-dessous les mêmes entryPoints et certResolver que ceux du site.
# 3. Sur le Mac, laisser tourner :
# rtg --racine /Volumes/CLEROADTRIPS/Road-Trips interface --proxy --prefixe /admin
#
# Traefik transmet lui-même l'adresse du visiteur et le « https » à RTG
# (X-Forwarded-For, X-Forwarded-Proto) : rien d'autre à régler.
http:
routers:
rtg-admin:
rule: "Host(`roadtrips.ouaibe.fr`) && PathPrefix(`/admin`)"
entryPoints: [websecure] # même nom que pour le site
service: rtg-admin
tls:
certResolver: letsencrypt # même nom que pour le site
services:
rtg-admin:
loadBalancer:
servers:
# Traefik dans Docker sur ce Mac :
- url: "http://host.docker.internal:8765"
# Traefik installé directement sur ce Mac : "http://127.0.0.1:8765"
# Traefik sur une autre machine : "http://<adresse du Mac>:8765",
# et lancer RTG avec --ecoute 0.0.0.0 en plus.
+3 -1
View File
@@ -57,6 +57,7 @@ def main(argv=None):
i.add_argument("--proxy", action="store_true", i.add_argument("--proxy", action="store_true",
help="derrière le serveur web du site (mot de passe obligatoire)") help="derrière le serveur web du site (mot de passe obligatoire)")
i.add_argument("--prefixe", default="", help="chemin de l'interface sur le site, par exemple /admin") i.add_argument("--prefixe", default="", help="chemin de l'interface sur le site, par exemple /admin")
i.add_argument("--ecoute", help="adresse d'écoute (défaut 127.0.0.1 ; 0.0.0.0 si le serveur web est ailleurs)")
mp = sp.add_parser("mot-de-passe", help="définir ou supprimer le mot de passe de l'interface") mp = sp.add_parser("mot-de-passe", help="définir ou supprimer le mot de passe de l'interface")
mp.add_argument("--supprimer", action="store_true") mp.add_argument("--supprimer", action="store_true")
@@ -109,7 +110,8 @@ def main(argv=None):
if bool(args.certificat) != bool(args.cle): if bool(args.certificat) != bool(args.cle):
sys.exit("❌ --certificat et --cle vont ensemble.") sys.exit("❌ --certificat et --cle vont ensemble.")
lancer(racine, args.port, ouvrir=not (args.sans_navigateur or args.proxy), distant=args.distant, lancer(racine, args.port, ouvrir=not (args.sans_navigateur or args.proxy), distant=args.distant,
certificat=args.certificat, cle=args.cle, proxy=args.proxy, prefixe=args.prefixe) certificat=args.certificat, cle=args.cle, proxy=args.proxy, prefixe=args.prefixe,
ecoute=args.ecoute)
except KeyboardInterrupt: except KeyboardInterrupt:
print("\nInterrompu.") print("\nInterrompu.")
sys.exit(130) sys.exit(130)
+8 -4
View File
@@ -837,13 +837,16 @@ def _echapper(s):
def lancer(racine, port=8765, ouvrir=True, distant=False, certificat=None, cle=None, def lancer(racine, port=8765, ouvrir=True, distant=False, certificat=None, cle=None,
proxy=False, prefixe=""): proxy=False, prefixe="", ecoute=None):
"""Lance l'interface. """Lance l'interface.
distant : écoute sur toutes les interfaces réseau, mot de passe obligatoire ; distant : écoute sur toutes les interfaces réseau, mot de passe obligatoire ;
certificat, cle : HTTPS ; certificat, cle : HTTPS ;
proxy : derrière le serveur web du site (qui transmet https://…/admin/ à proxy : derrière le serveur web du site (qui transmet https://…/admin/ à
127.0.0.1:port), mot de passe obligatoire ; prefixe : « /admin ».""" 127.0.0.1:port), mot de passe obligatoire ; prefixe : « /admin » ;
if (distant or proxy) and not acces.defini(): ecoute : adresse d'écoute imposée (« 0.0.0.0 » si le serveur web est sur
une autre machine)."""
hors_machine = ecoute and ecoute not in ("127.0.0.1", "localhost", "::1")
if (distant or proxy or hors_machine) and not acces.defini():
raise SystemExit("❌ L'accès depuis le réseau demande un mot de passe : lancez d'abord « rtg mot-de-passe ».") raise SystemExit("❌ L'accès depuis le réseau demande un mot de passe : lancez d'abord « rtg mot-de-passe ».")
contexte_tls = None contexte_tls = None
if certificat: if certificat:
@@ -856,7 +859,8 @@ def lancer(racine, port=8765, ouvrir=True, distant=False, certificat=None, cle=N
for p in ([port] if proxy else range(port, port + 20)): for p in ([port] if proxy else range(port, port + 20)):
try: try:
gardien = Gardien(p, distant=distant, https=bool(contexte_tls), proxy=proxy, prefixe=app.prefixe) gardien = Gardien(p, distant=distant, https=bool(contexte_tls), proxy=proxy, prefixe=app.prefixe)
serveur = ThreadingHTTPServer(("0.0.0.0" if distant else "127.0.0.1", p), adresse = ecoute or ("0.0.0.0" if distant else "127.0.0.1")
serveur = ThreadingHTTPServer((adresse, p),
creer_gestionnaire(app, p, gardien)) creer_gestionnaire(app, p, gardien))
port = p port = p
break break