A static file server built on GoFr — for SPAs and prerendered sites, with sensible cache headers by default, runtime config injection, compression, and header policies, plus Prometheus metrics, a health endpoint, and structured logging for free. Single binary, container-first, no nginx.
Generic static servers tend to get two things wrong for a Kubernetes frontend
stack: they send no useful Cache-Control headers, and they bake configuration
in at build time. gostatic fixes both. See docs/FEATURES.md
for the full feature set.
As a Docker base image for your built site (the usual way):
FROM opengittr/gostatic:latest
COPY --chown=nonroot:nonroot ./dist /srv/staticOr install the binary directly:
go install github.com/opengittr/gostatic@latestThe container serves /srv/static on port 8000 (metrics on 9090).
Run it against a directory:
gostatic # serves ./static on :8000, SPA fallback to index.htmlSimple options come from the environment (a configs/.env file is read
automatically, with configs/.local.env for local overrides):
| Variable | Default | Description |
|---|---|---|
HTTP_PORT |
8000 |
Main HTTP port |
METRICS_PORT |
9090 |
Prometheus metrics port |
STATIC_DIR |
./static |
Directory to serve |
SPA_MODE |
true |
Fall back to the SPA entry for unmatched routes |
SPA_FALLBACK |
index.html |
Entry file served on fallback |
COMPRESS |
true |
gzip on the fly + serve precompressed sidecars |
SECURITY_HEADERS |
false |
Apply the security-headers preset |
INJECT |
— | Comma-separated globs to hydrate at startup |
GOSTATIC_CONFIG |
./gostatic.yaml |
Path to the optional rules file |
Richer rules — per-glob cache overrides, custom headers, CORS, redirects, SPA
excludes — live in an optional YAML file (./gostatic.yaml, or GOSTATIC_CONFIG):
spaExclude: ["/api/*"] # these 404 instead of serving the SPA shell
cacheRules:
- { glob: "config.js", control: "no-store" }
headers:
X-Powered-By: gostatic
cors:
allowOrigin: "*"
allowMethods: "GET, OPTIONS"
redirects:
- { from: "/old", to: "/new", status: 301 }
inject: ["config.js"]Defaults are sensible without any of this: HTML is served no-cache,
fingerprinted (hashed) assets get immutable, and SPA routing is on.
List files under inject (or INJECT) and gostatic replaces ${VAR}
placeholders in them with environment values at startup — so one built image can
be deployed to many environments without a rebuild. Ship a config.js
containing window.API_URL = "${API_URL}", then set API_URL per deployment.
Build, test, and layout notes are in docs/DEVELOPMENT.md.
MIT — see LICENSE. An OpenGittr project.