# --- Web build stage (browser-edge SPA, contract §10.2) --- # Produces /web/dist, copied into the Go build context as web/dist so the # //go:embed all:web/dist directive in src/web_assets.go picks it up. FROM oven/bun:1.3.9-alpine AS web-builder WORKDIR /web COPY web/package.json web/bun.lock ./ RUN bun ci COPY web/ ./ RUN bun run build # --- Build Stage --- FROM golang:1.26 AS builder WORKDIR /app # Shared modules (git.dcntrlized.org/dcntrlized/dcntrlized-auth) are served by # the dev Gitea Go module proxy. Override via --build-arg in production. ARG GOPROXY_VALUE=http://192.168.122.183:3000/api/packages/Dcntrlized/go ARG GONOSUMDB_VALUE=git.dcntrlized.org ENV GOPROXY=${GOPROXY_VALUE},https://proxy.golang.org,direct ENV GONOSUMDB=${GONOSUMDB_VALUE} COPY src/go.mod src/go.sum ./ RUN go mod download COPY src/ ./ COPY --from=web-builder /web/dist ./web/dist # Build the whole main package (not just main.go): the browser-edge SPA embed # lives in web_assets.go, so a single-file build would not see embeddedWeb. RUN CGO_ENABLED=0 GOOS=linux go build -o server . # --- Run Stage --- FROM alpine:latest WORKDIR /root/ ARG IMAGE_VERSION=dev ARG IMAGE_REVISION= LABEL org.dcntrlized.service=KeepNote LABEL org.dcntrlized.port=8080 LABEL org.opencontainers.image.version=$IMAGE_VERSION LABEL org.opencontainers.image.revision=$IMAGE_REVISION COPY --from=builder /app/server . # Contract rev 9 §3.3: exactly ONE plaintext listener (:8080) serves the API # and the embedded browser web app (SPA + /web/*). No second port, no PKI. EXPOSE 8080 CMD ./server