# Copyright (C) 2026 Dcntrlized # # This program is free software: you can redistribute it and/or modify # it under the terms of the GNU Affero General Public License as published # by the Free Software Foundation, either version 3 of the License, or # (at your option) any later version. # # This program is distributed in the hope that it will be useful, # but WITHOUT ANY WARRANTY; without even the implied warranty of # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the # GNU Affero General Public License for more details. # # You should have received a copy of the GNU Affero General Public License # along with this program. If not, see . # Debug build: same embedded UI as the prod Dockerfile, but the final stage # keeps the golang:alpine base (shell + tooling) for live debugging. Rebuild # this image when the frontend changes; Air handles Go hot-reload at runtime. # Stage 1: Build the UI bundle FROM oven/bun:1.3.9-alpine AS frontend-builder WORKDIR /app # Copy the lockfile so `bun ci` can accurately install COPY src/frontend/package.json src/frontend/bun.lock ./ RUN bun ci COPY src/frontend/ ./ RUN bun run build # Stage 1b: Build the PUBLIC hub SPA bundle (separate bundle, served at /hub/ # outside the owner gate; browser-edge contract ยง10.5). FROM oven/bun:1.3.9-alpine AS hub-builder WORKDIR /app COPY src/hub/package.json src/hub/bun.lock ./ RUN bun ci COPY src/hub/ ./ RUN bun run build # Stage 2: Build the static Go binary FROM golang:1.26-alpine AS go-builder WORKDIR /app COPY src/go.mod src/go.sum ./ RUN go mod download COPY src/ . # Copy the built UI into the frontend folder so go:embed finds it COPY --from=frontend-builder /app/dist ./frontend/dist # Copy the built hub SPA into hub/dist so go:embed all:hub/dist finds it COPY --from=hub-builder /app/dist ./hub/dist RUN CGO_ENABLED=0 GOOS=linux go build -ldflags="-s -w" -o /server . # Stage 3: Debug-final image (alpine base, not scratch, for shell access) FROM golang:1.26-alpine RUN apk add --no-cache ca-certificates COPY --from=go-builder /server /server EXPOSE 8080 ENTRYPOINT ["/server"]