feat: show the build commit as a faint corner mark

Declares ARG NEXT_PUBLIC_APP_COMMIT, supplied by Ship, and renders it as a
nearly transparent, click-through stamp. Renders nothing when unset.

Co-Authored-By: Claude Sonnet 5.5 <noreply@anthropic.com>
This commit is contained in:
Dave 2026-10-30 01:27:22 +02:00
parent 3eea87ec03
commit 18cdc2976e
3 changed files with 65 additions and 27 deletions

View file

@ -1,31 +1,35 @@
FROM node:20-alpine AS base
FROM node:20-alpine AS deps
RUN apk add --no-cache libc6-compat
WORKDIR /app
COPY package.json package-lock.json* ./
RUN npm ci
FROM node:20-alpine AS builder
WORKDIR /app
COPY --from=deps /app/node_modules ./node_modules
COPY . .
RUN npm run build
FROM node:20-alpine AS runner
WORKDIR /app
FROM node:20-alpine AS base
FROM node:20-alpine AS deps
RUN apk add --no-cache libc6-compat
WORKDIR /app
COPY package.json package-lock.json* ./
RUN npm ci
FROM node:20-alpine AS builder
WORKDIR /app
COPY --from=deps /app/node_modules ./node_modules
COPY . .
# The commit being built, supplied by Ship. Declared late so the layers above
# stay cached; it is empty for builds that do not pass it.
ARG NEXT_PUBLIC_APP_COMMIT
ENV NEXT_PUBLIC_APP_COMMIT=${NEXT_PUBLIC_APP_COMMIT}
RUN npm run build
FROM node:20-alpine AS runner
WORKDIR /app
ENV NODE_ENV=production
RUN addgroup --system --gid 1001 nodejs
RUN adduser --system --uid 1001 nextjs
COPY --from=builder /app/public ./public
COPY --from=builder --chown=nextjs:nodejs /app/.next/standalone ./
COPY --from=builder --chown=nextjs:nodejs /app/.next/static ./.next/static
USER nextjs
EXPOSE 3000
RUN addgroup --system --gid 1001 nodejs
RUN adduser --system --uid 1001 nextjs
COPY --from=builder /app/public ./public
COPY --from=builder --chown=nextjs:nodejs /app/.next/standalone ./
COPY --from=builder --chown=nextjs:nodejs /app/.next/static ./.next/static
USER nextjs
EXPOSE 3000
ENV PORT=3000
ENV HOSTNAME="0.0.0.0"
CMD ["node", "server.js"]

View file

@ -8,6 +8,7 @@ import { Toaster } from "@/components/ui/sonner";
import { TooltipProvider } from "@/components/ui/tooltip";
import { ServiceWorkerRegistration } from "@/components/service-worker-registration";
import { ThemeBootstrapScript } from "@/components/theme-bootstrap";
import { BuildStamp } from "@/components/build-stamp";
// Fonts are self-hosted from ./fonts (Latin subsets of the Google Fonts
// files, downloaded 2026-10-20). With next/font/google every build fetched
@ -197,6 +198,7 @@ export default function RootLayout({ children }: { children: React.ReactNode })
<TooltipProvider>
<AuthProvider>
{children}
<BuildStamp />
</AuthProvider>
</TooltipProvider>
<Toaster richColors />

View file

@ -0,0 +1,32 @@
/**
* The commit this build came from, as a faint mark in the corner.
*
* `NEXT_PUBLIC_APP_COMMIT` is set by Ship (the Forgejo Desktop app) when it
* builds the image. A build made any other way has no value, so nothing is
* rendered. It never takes a click and is nearly transparent.
*/
export function BuildStamp() {
const commit = process.env.NEXT_PUBLIC_APP_COMMIT;
if (!commit) return null;
return (
<div
aria-hidden="true"
title={`Build ${commit}`}
style={{
position: "fixed",
right: 6,
bottom: "calc(env(safe-area-inset-bottom, 0px) + 3px)",
zIndex: 2147483647,
fontSize: 9,
lineHeight: 1,
fontFamily: "ui-monospace, SFMono-Regular, Menlo, monospace",
opacity: 0.3,
pointerEvents: "none",
userSelect: "none",
}}
>
{commit}
</div>
);
}