feat(staging): runtime API-base injection via /env.js
Parameterize the previously hardcoded API_BASE so a staging build can point at
the staging API without forking the code:
- env.js.template + /docker-entrypoint.d/30-fleetnow-env.sh render ${API_BASE}
into /env.js on container start (envsubst ships with the nginx image)
- index.html loads /env.js and uses window.FLEETNOW_API_BASE, falling back to
the prod API (https://fleetapi.rahamafresh.com) when unset — so prod/main is
unchanged; staging sets API_BASE=https://fleetapi.fivetitude.com
- nginx: serve /env.js with no-store
Enables the fleetnow.fivetitude.com staging app (Coolify, staging branch).
Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
This commit is contained in:
parent
a6d5a19273
commit
7138571c0e
5 changed files with 42 additions and 1 deletions
|
|
@ -11,6 +11,13 @@ COPY nginx.conf /etc/nginx/conf.d/fleetnow.conf
|
||||||
# The whole app is one self-contained file (inline CSS/JS; MapLibre from a CDN).
|
# The whole app is one self-contained file (inline CSS/JS; MapLibre from a CDN).
|
||||||
COPY index.html /usr/share/nginx/html/index.html
|
COPY index.html /usr/share/nginx/html/index.html
|
||||||
|
|
||||||
|
# Runtime API-base injection: the entrypoint renders ${API_BASE} -> /env.js at
|
||||||
|
# container start (envsubst ships with the nginx image). Set API_BASE per env;
|
||||||
|
# unset falls back to the prod API, so prod/main is unaffected.
|
||||||
|
COPY env.js.template /usr/share/nginx/html/env.js.template
|
||||||
|
COPY docker-entrypoint.d/30-fleetnow-env.sh /docker-entrypoint.d/30-fleetnow-env.sh
|
||||||
|
RUN chmod +x /docker-entrypoint.d/30-fleetnow-env.sh
|
||||||
|
|
||||||
# Static map-overlay data (toggleable layers: gas stations, etc.), served at /layers/.
|
# Static map-overlay data (toggleable layers: gas stations, etc.), served at /layers/.
|
||||||
COPY layers/ /usr/share/nginx/html/layers/
|
COPY layers/ /usr/share/nginx/html/layers/
|
||||||
|
|
||||||
|
|
|
||||||
17
docker-entrypoint.d/30-fleetnow-env.sh
Normal file
17
docker-entrypoint.d/30-fleetnow-env.sh
Normal file
|
|
@ -0,0 +1,17 @@
|
||||||
|
#!/bin/sh
|
||||||
|
# Render the runtime API base into /env.js before nginx starts.
|
||||||
|
# The official nginx image runs every executable /docker-entrypoint.d/*.sh at
|
||||||
|
# startup, so this fires on each container boot — letting one image serve staging
|
||||||
|
# (API_BASE=https://fleetapi.fivetitude.com) and prod (…rahamafresh.com) from the
|
||||||
|
# same build. Only ${API_BASE} is substituted; index.html falls back to the prod
|
||||||
|
# API if it's empty.
|
||||||
|
set -e
|
||||||
|
|
||||||
|
: "${API_BASE:=}"
|
||||||
|
TEMPLATE=/usr/share/nginx/html/env.js.template
|
||||||
|
OUT=/usr/share/nginx/html/env.js
|
||||||
|
|
||||||
|
if [ -f "$TEMPLATE" ]; then
|
||||||
|
envsubst '${API_BASE}' < "$TEMPLATE" > "$OUT"
|
||||||
|
echo "fleetnow: rendered /env.js with API_BASE='${API_BASE}'"
|
||||||
|
fi
|
||||||
4
env.js.template
Normal file
4
env.js.template
Normal file
|
|
@ -0,0 +1,4 @@
|
||||||
|
// Rendered at container start by /docker-entrypoint.d/30-fleetnow-env.sh
|
||||||
|
// (envsubst replaces ${API_BASE} with the API_BASE env var). If API_BASE is
|
||||||
|
// unset, this becomes an empty string and index.html falls back to the prod API.
|
||||||
|
window.FLEETNOW_API_BASE = "${API_BASE}";
|
||||||
|
|
@ -380,6 +380,8 @@
|
||||||
<script src="https://unpkg.com/maplibre-gl@4.7.1/dist/maplibre-gl.js"></script>
|
<script src="https://unpkg.com/maplibre-gl@4.7.1/dist/maplibre-gl.js"></script>
|
||||||
<!-- Supercluster: Folium-style marker clustering while keeping our DOM pins. -->
|
<!-- Supercluster: Folium-style marker clustering while keeping our DOM pins. -->
|
||||||
<script src="https://unpkg.com/supercluster@8.0.1/dist/supercluster.min.js"></script>
|
<script src="https://unpkg.com/supercluster@8.0.1/dist/supercluster.min.js"></script>
|
||||||
|
<!-- Runtime config: nginx entrypoint renders ${API_BASE} into /env.js at start. -->
|
||||||
|
<script src="/env.js"></script>
|
||||||
</head>
|
</head>
|
||||||
<body>
|
<body>
|
||||||
|
|
||||||
|
|
@ -492,7 +494,12 @@
|
||||||
// ============================================================================
|
// ============================================================================
|
||||||
// CONFIG
|
// CONFIG
|
||||||
// ============================================================================
|
// ============================================================================
|
||||||
const API_BASE = 'https://fleetapi.rahamafresh.com';
|
// API base is injected per-environment via /env.js (nginx renders ${API_BASE}
|
||||||
|
// at container start). Falls back to the prod API when unset, so a build with no
|
||||||
|
// API_BASE env (e.g. prod/main) is unchanged. Staging sets API_BASE=https://fleetapi.fivetitude.com.
|
||||||
|
const API_BASE = (window.FLEETNOW_API_BASE && /^https?:\/\//.test(window.FLEETNOW_API_BASE))
|
||||||
|
? window.FLEETNOW_API_BASE.replace(/\/$/, '')
|
||||||
|
: 'https://fleetapi.rahamafresh.com';
|
||||||
const EP_LIVE = `${API_BASE}/webhook/live-positions`;
|
const EP_LIVE = `${API_BASE}/webhook/live-positions`;
|
||||||
const EP_TRACK = `${API_BASE}/webhook/live-positions/track`;
|
const EP_TRACK = `${API_BASE}/webhook/live-positions/track`;
|
||||||
const EP_FLEET = `${API_BASE}/webhook/fleet-dashboard`;
|
const EP_FLEET = `${API_BASE}/webhook/fleet-dashboard`;
|
||||||
|
|
|
||||||
|
|
@ -25,6 +25,12 @@ server {
|
||||||
add_header Referrer-Policy "no-referrer-when-downgrade";
|
add_header Referrer-Policy "no-referrer-when-downgrade";
|
||||||
}
|
}
|
||||||
|
|
||||||
|
# Runtime config (per-environment API base) — must never be cached.
|
||||||
|
location = /env.js {
|
||||||
|
add_header Cache-Control "no-store, no-cache, must-revalidate";
|
||||||
|
default_type application/javascript;
|
||||||
|
}
|
||||||
|
|
||||||
gzip on;
|
gzip on;
|
||||||
gzip_vary on;
|
gzip_vary on;
|
||||||
gzip_min_length 1024;
|
gzip_min_length 1024;
|
||||||
|
|
|
||||||
Loading…
Reference in a new issue