update
authorShane Jaroch <chown_tee@proton.me>
Wed, 21 Jan 2026 22:44:31 +0000 (17:44 -0500)
committerShane Jaroch <chown_tee@proton.me>
Wed, 21 Jan 2026 22:44:31 +0000 (17:44 -0500)
Makefile
etc/nginx/conf.d/dev/stalwart.conf
scripts/deploy.sh
scripts/gen_services_map.py
scripts/gitweb-simplefrontend/services.html
scripts/homepage.html

index 29a2f8c5e5bdaaa2a7095980975aa97acd5a11c6..4de008fd49dbfb6978de24b2a1a976cfa06c97a0 100644 (file)
--- a/Makefile
+++ b/Makefile
@@ -58,7 +58,7 @@ VPS := $(VPS_USER)@$(VPS_HOST)
 .PHONY: stage/nginx
 stage/nginx: ##H @Remote Stage files on the remote VPS
        @echo "Staging files on $(VPS_HOST) (ENV=$(ENV))..."
-       python3 scripts/gen_services_map.py etc/nginx/conf.d/default.$(ENV).conf
+       python3 scripts/gen_services_map.py etc/nginx/conf.d/$(ENV)/default.conf
        # Tar files and stream to remote
        # Include only: "$(ENV)/*.conf" and non-env-specific "*.conf" files
        tar cz \
index 6a6c1a7b1de1bc432504cd115e9ed3a7b6464c0a..42a19345670405bf3a74aafdb2690fde81834dca 100644 (file)
@@ -59,4 +59,24 @@ server {
         proxy_read_timeout 3600s;
         proxy_send_timeout 3600s;
     }
+
+    # Optimizations for Stalwart Webadmin (WASM/Static Assets)
+    location ~* \.(wasm|js|css|json|png|jpg|jpeg|gif|ico|svg|woff|woff2)$ {
+        proxy_pass http://127.0.0.1:8080;
+
+        # Enable Gzip/Brotli
+        gzip on;
+        gzip_types application/wasm application/javascript application/json text/css;
+        gzip_vary on;
+
+        # Cache heavily
+        expires 30d;
+        add_header Cache-Control "public, max-age=2592000, immutable";
+
+        # Standard Proxy Headers needed here too
+        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;
+    }
 }
index a89f6265e325558c09ae51f9bc5b408bd9542fa0..87090a58fc16a99d6a49c3effa1fe541421d6ac3 100755 (executable)
@@ -66,38 +66,41 @@ fi
 if [ "$1" = "test" ]; then
     ENV="${2:-dev}"
     echo "Running pre-flight validation for ENV=$ENV..."
+
+    # DEBUG: List what we are working with
+    echo "DEBUG: Staging Directory Contents:"
+    find "$NGINX_CONF_SRC" -print
+
     TMP_WORK_DIR=$(mktemp -d)
     TMP_NGINX_CONF="$TMP_WORK_DIR/nginx.conf"
     TMP_CONF_D="$TMP_WORK_DIR/conf.d"
     mkdir -p "$TMP_CONF_D"
 
     # Copy config files to temp dir for testing, respecting secrets
-    for FILE in "$NGINX_CONF_SRC"/*.conf; do
+    # Copy config files to temp dir for testing, respecting secrets
+    # We scan recursively to find configs in dev/ or prod/ subdirs
+    find "$NGINX_CONF_SRC" -name "*.conf" | while read -r FILE; do
         BASENAME=$(basename "$FILE")
+
+        # Skip secrets.conf if it's not text (encrypted)
         if [ "$BASENAME" = "secrets.conf" ] && ! is_text_file "$FILE"; then
             echo "Skipping encrypted secrets.conf for test..."
             continue
         fi
 
-        # Generic handling for *.dev.conf and *.prod.conf
-        if [[ "$BASENAME" =~ ^(.*)\.(dev|prod)\.conf$ ]]; then
-            STEM="${BASH_REMATCH[1]}"
-            CONF_ENV="${BASH_REMATCH[2]}"
-
-            if [ "$CONF_ENV" == "$ENV" ]; then
-                cp "$FILE" "$TMP_CONF_D/$STEM.conf"
-            else
-                continue
-            fi
-        else
-            cp "$FILE" "$TMP_CONF_D/"
-        fi
+        # We copy all found .conf files to the flat temp directory
+        # Since we use Makefile to only stage the correct ENV, we don't need to filter by name here anymore.
+        cp "$FILE" "$TMP_CONF_D/"
     done
 
     # Generate test nginx.conf
     # We strictly replace the include path
     sed "s|/etc/nginx/conf.d/\*\.conf|$TMP_CONF_D/*.conf|g" /etc/nginx/nginx.conf >"$TMP_NGINX_CONF"
 
+    # DEBUG: Show what we are testing
+    echo "DEBUG: Test Config Structure:"
+    tree "$TMP_WORK_DIR" 2>/dev/null || ls -R "$TMP_WORK_DIR"
+
     if sudo nginx -t -c "$TMP_NGINX_CONF"; then
         echo "✓ Pre-flight validation passed."
         if [ -n "$DEBUG" ]; then
@@ -144,7 +147,8 @@ for FILE in "$NGINX_CONF_SRC"/*.conf.disabled; do
     fi
 done
 
-for FILE in "$NGINX_CONF_SRC"/*.conf; do
+# Install configs
+find "$NGINX_CONF_SRC" -name "*.conf" | while read -r FILE; do
     BASENAME=$(basename "$FILE")
 
     # Skip encrypted secrets
@@ -153,22 +157,9 @@ for FILE in "$NGINX_CONF_SRC"/*.conf; do
         continue
     fi
 
-    # Generic handling for *.dev.conf and *.prod.conf
-    if [[ "$BASENAME" =~ ^(.*)\.(dev|prod)\.conf$ ]]; then
-        STEM="${BASH_REMATCH[1]}"
-        CONF_ENV="${BASH_REMATCH[2]}"
-
-        if [ "$CONF_ENV" == "$ENV" ]; then
-            echo "Installing $BASENAME as $STEM.conf..."
-            sudo cp "$FILE" "$DEST_CONF_DIR/$STEM.conf"
-        else
-            echo "Skipping mismatch config: $BASENAME"
-            continue
-        fi
-    else
-        # Install all other configs as-is
-        sudo cp "$FILE" "$DEST_CONF_DIR/"
-    fi
+    # Install to destination (flattening directory structure)
+    echo "Installing $BASENAME..."
+    sudo cp "$FILE" "$DEST_CONF_DIR/"
 done
 
 echo "Verifying configuration..."
index 35e64d020d9b4f3eac0fae5c017879d691ca15dc..608517a4f78099465f1551f78edf2ce91f332647 100755 (executable)
@@ -6,7 +6,7 @@ from pathlib import Path
 
 # Paths relative to repo root
 REPO_ROOT = Path(__file__).parent.parent
-NGINX_CONF = REPO_ROOT / "etc/nginx/conf.d/git-http.dev.conf"
+NGINX_CONF = REPO_ROOT / "etc/nginx/conf.d/dev/git-http.conf"
 OUTPUT_HTML = REPO_ROOT / "scripts/gitweb-simplefrontend/services.html"
 
 HTML_TEMPLATE = """<!DOCTYPE html>
@@ -101,9 +101,9 @@ def get_all_services(custom_config_path=None):
 
     NGINX_CONF_DIR = REPO_ROOT / "etc/nginx/conf.d"
 
-    # Always scan all .conf files in the directory
+    # Always scan all .conf files in the directory (recursively)
     if NGINX_CONF_DIR.exists():
-        conf_files = list(NGINX_CONF_DIR.glob("*.conf"))
+        conf_files = list(NGINX_CONF_DIR.rglob("*.conf"))
         print(f"Scanning {len(conf_files)} config files in {NGINX_CONF_DIR}...")
     else:
         print(f"Warning: Config directory not found at {NGINX_CONF_DIR}")
@@ -112,7 +112,7 @@ def get_all_services(custom_config_path=None):
     services_other = []
     for conf_file in conf_files:
         # Skip the git-http conf as it's parsed separately
-        if conf_file.name == "git-http.dev.conf":
+        if conf_file.name in ["git-http.conf", "git-http.dev.conf"]:
             continue
 
         print(f"  Parsing {conf_file.name}...")
index 3fab7b21f4971f89b10f7dfca628656d6a9ab535..eb81eee3f634a0fc8c96c8999458a40673dc9652 100644 (file)
@@ -36,7 +36,7 @@
         </div>
 
     <footer>
-        <p>Built: 2026-01-21 16:37:49  | Services: 3 | Server: San Jose, CA</p>
+        <p>Built: 2026-01-21 17:41:17  | Services: 3 | Server: San Jose, CA</p>
         <p>Nginx: <span class="ssi">v<!--#echo var="nginx_version"--></span> |
            Protocol: <span class="ssi"><!--#echo var="server_protocol"--></span> |
            Served: <span class="ssi"><!--#echo var="date_local"--></span> |
index 27d122879f76c4d995bae18dd8cf2eef111c2a24..c27817fa946762b81b6661e230a5621e86622d1d 100644 (file)
@@ -51,7 +51,7 @@
         </div>
 
     <footer>
-        <p>Built: 2026-01-21 16:37:49  | Services: 6 | Server: San Jose, CA</p>
+        <p>Built: 2026-01-21 17:41:17  | Services: 6 | Server: San Jose, CA</p>
         <p>Nginx: <span class="ssi">v<!--#echo var="nginx_version"--></span> |
            Protocol: <span class="ssi"><!--#echo var="server_protocol"--></span> |
            Served: <span class="ssi"><!--#echo var="date_local"--></span> |