A single, self-hosted Go service that hosts static sites by host-based routing and serves a dynamic portal to browse them.
You publish sites over an HTTP API; gotifacts stores them on a volume with a
SQLite registry and serves them at https://<slug>.<group>.<base>.
gotifacts runs behind any reverse proxy you provide (nginx, Caddy, …) for TLS and SSO/forward-auth. It serves plain HTTP on one port, never TLS, and enforces its own authorization.
- One static binary (CGO-free, built
FROM scratch). - SQLite + a volume are the only state.
- No hardcoded domains/hosts/paths — everything is configurable.
Full documentation lives at → https://lmgarret.github.io/gotifacts
It's organized by the Diátaxis framework:
- Tutorials — run gotifacts locally and publish your first site.
- How-to guides — Docker, nginx / Caddy, API keys, publishing from CI, Claude via MCP.
- Reference — configuration, the HTTP API, the CLI.
- Explanation — architecture, the two-plane auth model, the threat model.
flowchart TB
client([Client])
proxy["Reverse proxy<br/>(operator-provided: TLS, forward-auth/SSO)"]
client --> proxy
proxy -->|"apex / and /api/* — forward-auth ON"| mgmt["Portal UI + management API"]
proxy -->|"apex /ingest/* — forward-auth OFF"| ingest["Machine publish API (API key)"]
proxy -->|"*.base, *.*.base"| sites["Static site content"]
subgraph gotifacts["gotifacts (Go, static scratch binary) — HTTP :8080"]
router{"Host router"}
mgmt --> router
ingest --> router
sites --> router
router -->|"Host == base"| apex["portal + /api + /ingest"]
router -->|"else"| serve["serve site files"]
end
gotifacts --> volume[("Volume (rw)<br/>/data/gotifacts.db<br/>/data/sites/<group>/<slug>/")]
The service routes purely by the request Host: the apex host serves the portal
and the /api/* + /ingest/* APIs; any other host maps to a site directory and
serves static files.
A proxy-agnostic docker-compose.yml is provided; the
image is published to ghcr.io/lmgarret/gotifacts.
cp .env.example .env
# edit .env: set GOTIFACTS_BASE_DOMAIN, GOTIFACTS_ADMIN_USERS, GOTIFACTS_TRUSTED_PROXIES
docker compose up -dgotifacts is reachable only on the internal network — never expose port 8080
to the internet. Put your reverse proxy in front of it for TLS and
forward-auth. See the
Docker and
reverse-proxy guides for the full setup, and
examples/ for reference nginx/Caddy configs.
- Development setup and the docs workflow:
CONTRIBUTING.mdandAGENTS.md. - Threat model and private vulnerability reporting:
SECURITY.md.
go test -race ./... # backend tests
golangci-lint run ./... # backend lint
cd web && npm ci && npm run lint && npm run build # frontendThe Go module path is github.com/lmgarret/gotifacts; go.mod is the single
source of truth for the Go version.
MIT.