feat(ops): /api/version endpoint with git SHA + build time
Adds a public, no-auth endpoint at /api/version that returns:
{ commit, commitShort, buildTime, nodeEnv, cutover, nextVersion }
Build-time injection via GIT_COMMIT + BUILD_TIME ARG/ENV propagated
from compose build.args through Dockerfile builder + runner stages.
Excluded from middleware auth gating.
Deploy command (run on satra after git pull):
GIT_COMMIT=$(git rev-parse HEAD) \
BUILD_TIME=$(date -u +%FT%TZ) \
docker compose build architools
Without these env vars, falls back to "unknown" so the build never
fails; only the endpoint shows reduced info.
Useful for: confirming what's actually deployed after CI, cross-app
deploy correlation (api.gis.ac, eterra.live, orchestrator), uptime
monitors.
Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
This commit is contained in:
+11
@@ -26,11 +26,16 @@ ARG NEXT_PUBLIC_APP_NAME=ArchiTools
|
||||
ARG NEXT_PUBLIC_APP_URL=https://tools.beletage.ro
|
||||
ARG NEXT_PUBLIC_MARTIN_URL=https://tools.beletage.ro/tiles
|
||||
ARG NEXT_PUBLIC_PMTILES_URL=
|
||||
# Version metadata baked at build time → /api/version
|
||||
ARG GIT_COMMIT=unknown
|
||||
ARG BUILD_TIME=unknown
|
||||
ENV NEXT_PUBLIC_STORAGE_ADAPTER=${NEXT_PUBLIC_STORAGE_ADAPTER}
|
||||
ENV NEXT_PUBLIC_APP_NAME=${NEXT_PUBLIC_APP_NAME}
|
||||
ENV NEXT_PUBLIC_APP_URL=${NEXT_PUBLIC_APP_URL}
|
||||
ENV NEXT_PUBLIC_MARTIN_URL=${NEXT_PUBLIC_MARTIN_URL}
|
||||
ENV NEXT_PUBLIC_PMTILES_URL=${NEXT_PUBLIC_PMTILES_URL}
|
||||
ENV GIT_COMMIT=${GIT_COMMIT}
|
||||
ENV BUILD_TIME=${BUILD_TIME}
|
||||
|
||||
# Increase memory for Next.js build if VM has limited RAM
|
||||
ENV NODE_OPTIONS="--max-old-space-size=2048"
|
||||
@@ -40,6 +45,12 @@ RUN npm run build
|
||||
FROM node:22-alpine AS runner
|
||||
WORKDIR /app
|
||||
|
||||
# Re-declare build-time version args so they propagate into runner ENV
|
||||
ARG GIT_COMMIT=unknown
|
||||
ARG BUILD_TIME=unknown
|
||||
ENV GIT_COMMIT=${GIT_COMMIT}
|
||||
ENV BUILD_TIME=${BUILD_TIME}
|
||||
|
||||
ENV NODE_ENV=production
|
||||
ENV TZ=Europe/Bucharest
|
||||
|
||||
|
||||
@@ -8,6 +8,10 @@ services:
|
||||
- NEXT_PUBLIC_APP_URL=${NEXT_PUBLIC_APP_URL:-https://tools.beletage.ro}
|
||||
- NEXT_PUBLIC_MARTIN_URL=${NEXT_PUBLIC_MARTIN_URL}
|
||||
- NEXT_PUBLIC_PMTILES_URL=${NEXT_PUBLIC_PMTILES_URL}
|
||||
# Inject git SHA + build timestamp; deploy via:
|
||||
# GIT_COMMIT=$(git rev-parse HEAD) BUILD_TIME=$(date -u +%FT%TZ) docker compose build
|
||||
- GIT_COMMIT=${GIT_COMMIT:-unknown}
|
||||
- BUILD_TIME=${BUILD_TIME:-unknown}
|
||||
container_name: architools
|
||||
restart: unless-stopped
|
||||
ports:
|
||||
|
||||
@@ -0,0 +1,31 @@
|
||||
import { NextResponse } from "next/server";
|
||||
|
||||
export const runtime = "nodejs";
|
||||
export const dynamic = "force-dynamic";
|
||||
|
||||
/**
|
||||
* Public version endpoint. Returns the git commit + build time baked at
|
||||
* `docker compose build` (via GIT_COMMIT / BUILD_TIME build args) plus
|
||||
* a few runtime flags useful for ops + remote verification.
|
||||
*
|
||||
* No auth. Excluded from middleware matcher.
|
||||
*
|
||||
* Deploy command on satra (after `git pull`):
|
||||
* GIT_COMMIT=$(git rev-parse HEAD) \
|
||||
* BUILD_TIME=$(date -u +%FT%TZ) \
|
||||
* docker compose build architools
|
||||
*/
|
||||
export async function GET() {
|
||||
const commit = process.env.GIT_COMMIT || "unknown";
|
||||
return NextResponse.json({
|
||||
commit,
|
||||
commitShort: commit.slice(0, 7),
|
||||
buildTime: process.env.BUILD_TIME || "unknown",
|
||||
nodeEnv: process.env.NODE_ENV || "unknown",
|
||||
cutover: {
|
||||
useGisAcDefault: process.env.USE_GIS_AC === "1",
|
||||
pilotUsers: (process.env.GIS_AC_PILOT_USERS || "").split(",").filter(Boolean).length,
|
||||
},
|
||||
nextVersion: "16.1.6",
|
||||
});
|
||||
}
|
||||
+1
-1
@@ -58,6 +58,6 @@ export const config = {
|
||||
* - /favicon.ico, /robots.txt, /sitemap.xml
|
||||
* - Files with extensions (images, fonts, etc.)
|
||||
*/
|
||||
"/((?!api/auth|api/notifications/digest|api/eterra/auto-refresh|api/compress-pdf|api/address-book|api/projects|auth/signin|_next|favicon\\.ico|robots\\.txt|sitemap\\.xml|.*\\..*).*)",
|
||||
"/((?!api/auth|api/version|api/notifications/digest|api/eterra/auto-refresh|api/compress-pdf|api/address-book|api/projects|auth/signin|_next|favicon\\.ico|robots\\.txt|sitemap\\.xml|.*\\..*).*)",
|
||||
],
|
||||
};
|
||||
|
||||
Reference in New Issue
Block a user