Route same-origin API via /apnew/api to bypass ALB /api* rule.
All checks were successful
Deploy to Frontend Servers / deploy (push) Successful in 53s

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 <cursoragent@cursor.com>
This commit is contained in:
2026-05-23 17:56:38 +08:00
parent 2c710e2e24
commit 769087ba4a
5 changed files with 28 additions and 2 deletions

View File

@@ -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

View File

@@ -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;

View File

@@ -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<T>(items: T[] | null | undefined): T[] {

1
src/vite-env.d.ts vendored
View File

@@ -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. */

View File

@@ -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 },
},