From 8486504b498e5018f3fb48bdcbd46fba2fd9df2e Mon Sep 17 00:00:00 2001 From: Thomas Date: Thu, 9 Jul 2026 08:18:07 +0200 Subject: [PATCH] Merge admin panel into the port-80 webtools site under /admin/ webtools' nginx now reverse-proxies /admin/ to the webadmin container (docker/conf/webtools-nginx.conf), which no longer publishes its own port -- everything is reachable through port 80 alongside the GM toolbox. Added a link to it in webtools/index.html's sidebar. Flask needs to know it's mounted under /admin/ to generate correct url_for()/redirect() targets, so app.py now wraps the app in werkzeug's ProxyFix (x_prefix/x_proto/x_for/x_host) reading the X-Forwarded-Prefix header nginx sets; verified redirects, form actions, and links all come back /admin/-prefixed end to end through port 80. Co-Authored-By: Claude Sonnet 5 --- docker-compose.yml | 7 +++++-- docker/conf/webtools-nginx.conf | 19 +++++++++++++++++++ webadmin/app.py | 5 +++++ webtools/index.html | 9 ++++++--- 4 files changed, 35 insertions(+), 5 deletions(-) create mode 100644 docker/conf/webtools-nginx.conf diff --git a/docker-compose.yml b/docker-compose.yml index 4f178cb..3ee2949 100644 --- a/docker-compose.yml +++ b/docker-compose.yml @@ -88,6 +88,9 @@ services: - "80:80" volumes: - "./webtools:/usr/share/nginx/html:ro" + - "./docker/conf/webtools-nginx.conf:/etc/nginx/conf.d/default.conf:ro" + depends_on: + - webadmin webadmin: build: @@ -101,8 +104,8 @@ services: DB_NAME: ${DB_NAME:-ktrose} ADMIN_SECRET_KEY: ${ADMIN_SECRET_KEY:-change-me-too} ADMIN_MIN_ACCESSLEVEL: ${ADMIN_MIN_ACCESSLEVEL:-900} - ports: - - "8081:8080" + expose: + - "8080" depends_on: db: condition: service_healthy diff --git a/docker/conf/webtools-nginx.conf b/docker/conf/webtools-nginx.conf new file mode 100644 index 0000000..dfef35e --- /dev/null +++ b/docker/conf/webtools-nginx.conf @@ -0,0 +1,19 @@ +server { + listen 80; + + root /usr/share/nginx/html; + index index.html; + + location /admin/ { + proxy_pass http://webadmin:8080/; + proxy_set_header Host $host; + proxy_set_header X-Real-IP $remote_addr; + proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for; + proxy_set_header X-Forwarded-Proto $scheme; + proxy_set_header X-Forwarded-Prefix /admin; + } + + location / { + try_files $uri $uri/ =404; + } +} diff --git a/webadmin/app.py b/webadmin/app.py index 81866ed..8df329f 100644 --- a/webadmin/app.py +++ b/webadmin/app.py @@ -5,9 +5,14 @@ import hashlib import pymysql import pymysql.cursors from flask import Flask, request, session, redirect, url_for, render_template, flash +from werkzeug.middleware.proxy_fix import ProxyFix app = Flask(__name__) app.secret_key = os.environ.get("ADMIN_SECRET_KEY", "dev-only-change-me") +# Sits behind the webtools nginx container at /admin/ (see webtools/nginx.conf); +# this reads X-Forwarded-Prefix/-Proto/-For so url_for()/redirect() produce +# correct /admin/-prefixed URLs instead of root-relative ones. +app.wsgi_app = ProxyFix(app.wsgi_app, x_prefix=1, x_proto=1, x_for=1, x_host=1) def hash_password(plaintext): diff --git a/webtools/index.html b/webtools/index.html index 6abdf41..20d3e24 100644 --- a/webtools/index.html +++ b/webtools/index.html @@ -56,13 +56,15 @@ .brand .sub{font-size:0.7rem; letter-spacing:0.1em; text-transform:uppercase; color:var(--ink-faint); margin-top:2px;} .tabs{display:flex; flex-direction:column; gap:3px;} - .tab{ + .tab, .tab-link{ display:flex; align-items:center; gap:9px; padding:9px 11px; border-radius:8px; font-size:0.9rem; color:var(--ink-dim); cursor:pointer; border:1px solid transparent; + text-decoration:none; } - .tab:hover{background:var(--bg-card); color:var(--ink);} + .tab:hover, .tab-link:hover{background:var(--bg-card); color:var(--ink);} .tab.active{background:var(--bg-card); border-color:var(--line); color:var(--ink); font-weight:600;} - .tab .ico{font-size:1rem; width:1.2em; text-align:center;} + .tab .ico, .tab-link .ico{font-size:1rem; width:1.2em; text-align:center;} + .tab-link{border-top:1px solid var(--line); margin-top:6px; padding-top:12px;} .side-panel{display:none; flex-direction:column; gap:10px;} .side-panel.active{display:flex;} @@ -173,6 +175,7 @@
⌘ GM Commands
◆ Item Configurator
⌗ Maps
+ ⚙ Admin Panel