From 769087ba4a89f0d28720583c43b020a95153bb04 Mon Sep 17 00:00:00 2001 From: thomas Date: Sat, 23 May 2026 17:56:38 +0800 Subject: [PATCH] Route same-origin API via /apnew/api to bypass ALB /api* rule. ALB sends /api/* to an unreachable backend target group (502 on apex). Use VITE_API_PREFIX=/apnew with nginx proxy to backend-1 until the listener rule is removed. Co-authored-by: Cursor --- .gitea/workflows/deploy.yml | 1 + deploy/nginx-frontend-locations.inc | 20 +++++++++++++++++++- src/api.ts | 3 ++- src/vite-env.d.ts | 1 + vite.config.ts | 5 +++++ 5 files changed, 28 insertions(+), 2 deletions(-) diff --git a/.gitea/workflows/deploy.yml b/.gitea/workflows/deploy.yml index 3b5163a..c8a9335 100644 --- a/.gitea/workflows/deploy.yml +++ b/.gitea/workflows/deploy.yml @@ -35,6 +35,7 @@ jobs: run: npm run build env: VITE_API_URL: "" + VITE_API_PREFIX: "/apnew" VITE_DISABLE_ADMIN: "true" - name: Setup SSH key diff --git a/deploy/nginx-frontend-locations.inc b/deploy/nginx-frontend-locations.inc index 1ccd934..bc7b2c2 100644 --- a/deploy/nginx-frontend-locations.inc +++ b/deploy/nginx-frontend-locations.inc @@ -1,4 +1,5 @@ -# Shared SPA locations. Browser calls same-origin /api/ + /uploads/ (VITE_API_URL empty). +# Shared SPA locations. Browser calls same-origin /apnew/api/ + /uploads/ (VITE_API_PREFIX=/apnew). +# /apnew/api/ avoids ALB listener rule that sends /api/* to an unreachable backend target group. # Nginx proxies internally to ark-library-backend-1 (Tailscale); Host header for backend TLS. gzip on; gzip_vary on; @@ -7,6 +8,9 @@ gzip_comp_level 5; gzip_types text/plain text/css application/javascript application/json application/xml image/svg+xml; gzip_min_length 256; +location ^~ /apnew/api/admin { + return 404; +} location ^~ /api/admin { return 404; } @@ -14,6 +18,20 @@ location ^~ /admin { return 404; } +location ^~ /apnew/api/ { + proxy_pass https://100.93.205.19/api/; + proxy_http_version 1.1; + proxy_ssl_server_name on; + proxy_set_header Host api.ark-library.com; + 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; + client_max_body_size 512m; + client_body_timeout 600s; + proxy_read_timeout 600s; + proxy_send_timeout 600s; +} + location ^~ /api/ { proxy_pass https://100.93.205.19/api/; proxy_http_version 1.1; diff --git a/src/api.ts b/src/api.ts index bd67d4e..bfbafa6 100644 --- a/src/api.ts +++ b/src/api.ts @@ -1,4 +1,5 @@ -export const apiBase = import.meta.env.VITE_API_URL || ""; +export const apiPrefix = import.meta.env.VITE_API_PREFIX || ""; +export const apiBase = (import.meta.env.VITE_API_URL || "") + apiPrefix; /** Go JSON encodes nil slices as null — normalize before .map() */ export function itemsOrEmpty(items: T[] | null | undefined): T[] { diff --git a/src/vite-env.d.ts b/src/vite-env.d.ts index d4a562b..0724325 100644 --- a/src/vite-env.d.ts +++ b/src/vite-env.d.ts @@ -2,6 +2,7 @@ interface ImportMetaEnv { readonly VITE_API_URL: string; + readonly VITE_API_PREFIX?: string; readonly VITE_WALLETCONNECT_PROJECT_ID: string; readonly VITE_ADMIN_UI_PREFIX?: string; /** When `"true"`, bundle admin UI only (no public pages); use with `VITE_ADMIN_UI_PREFIX` or default secret prefix. */ diff --git a/vite.config.ts b/vite.config.ts index 4f8619d..685ae82 100644 --- a/vite.config.ts +++ b/vite.config.ts @@ -20,6 +20,11 @@ export default defineConfig(({ mode }) => { server: { port: 5173, proxy: { + "/apnew/api": { + target: apiProxyTarget, + changeOrigin: true, + rewrite: (path) => path.replace(/^\/apnew/, ""), + }, "/api": { target: apiProxyTarget, changeOrigin: true }, "/uploads": { target: apiProxyTarget, changeOrigin: true }, },