Stage-0 web UI needs a self-contained container image. Two changes: - Dockerfile: multi-stage build (golang:1.25 builder, CGO off + static link, -trimpath -s -w) into distroless static nonroot. The committed templ output and vendored asset mean a plain `go build` suffices — no codegen or CDN at build/run time. Existing .gitea CI already builds and pushes localhost:5000/tapir:<sha> + mirrors to GitHub (deploy patch intentionally omitted — cutover is held), so it only needed this file. - Vendor htmx 1.9.12 locally (internal/web/static/, embed.FS, served at /static/ outside the auth guard) and point Layout at /static/htmx.min.js instead of unpkg. The deployed UI must not depend on an external CDN being reachable from the cluster. task check green. Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
25 lines
779 B
Go
25 lines
779 B
Go
package web
|
|
|
|
import (
|
|
"embed"
|
|
"net/http"
|
|
)
|
|
|
|
// staticFS holds the vendored client assets (htmx) served under /static/. They
|
|
// are embedded into the binary so a deployed image works without any external
|
|
// CDN — the UI must not depend on unpkg being reachable from the cluster.
|
|
//
|
|
//go:embed static/*
|
|
var staticFS embed.FS
|
|
|
|
// staticHandler serves the embedded assets with a long cache lifetime. The
|
|
// files are content-stable (versioned by filename, e.g. htmx.min.js pinned to a
|
|
// release), so aggressive caching is safe.
|
|
func staticHandler() http.Handler {
|
|
fs := http.FileServer(http.FS(staticFS))
|
|
return http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
|
|
w.Header().Set("Cache-Control", "public, max-age=31536000, immutable")
|
|
fs.ServeHTTP(w, r)
|
|
})
|
|
}
|