gotifacts

module
v0.15.0 Latest Latest
Warning

This package is not in the latest version of its module.

Go to latest
Published: Jul 24, 2026 License: MIT

README ¶

gotifacts

A single, self-hosted Go service that hosts static sites by host-based routing and serves a dynamic portal to browse them.

CI Go Report Card


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.

📖 Documentation

Full documentation lives at → https://lmgarret.github.io/gotifacts

It's organized by the Diátaxis framework:

How it works

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/&lt;group&gt;/&lt;slug&gt;/")]

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.

Quickstart (Docker)

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 -d

gotifacts 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.

Contributing & security

go test -race ./...          # backend tests
golangci-lint run ./...      # backend lint
cd web && npm ci && npm run lint && npm run build   # frontend

The Go module path is github.com/lmgarret/gotifacts; go.mod is the single source of truth for the Go version.

License

MIT.

Directories ¶

Path Synopsis
cmd
gotifacts command
Command gotifacts is a self-hosted service that hosts static sites by host-based routing and serves a dynamic management portal.
Command gotifacts is a self-hosted service that hosts static sites by host-based routing and serves a dynamic management portal.
internal
api
Package api wires the management plane (/api/*, forward-auth) and the ingest plane (/ingest/*, API-key) onto the apex host, plus the embedded SPA.
Package api wires the management plane (/api/*, forward-auth) and the ingest plane (/ingest/*, API-key) onto the apex host, plus the embedded SPA.
archive
Package archive safely extracts site bundles, defending against zip-slip, tar-bombs, symlink escapes, and oversized payloads.
Package archive safely extracts site bundles, defending against zip-slip, tar-bombs, symlink escapes, and oversized payloads.
auth
Package auth implements the two-plane authorization model.
Package auth implements the two-plane authorization model.
config
Package config loads and validates the gotifacts runtime configuration.
Package config loads and validates the gotifacts runtime configuration.
httplog
Package httplog provides request-logging middleware.
Package httplog provides request-logging middleware.
ingest
Package ingest implements site publishing: staging an upload to a temp dir on the same volume, validating it, atomically swapping it into place (with optional versioning), and recording the registry row in a transaction.
Package ingest implements site publishing: staging an upload to a temp dir on the same volume, validating it, atomically swapping it into place (with optional versioning), and recording the registry row in a transaction.
keys
Package keys handles API-key token generation, hashing, and scope semantics.
Package keys handles API-key token generation, hashing, and scope semantics.
logging
Package logging builds the process-wide structured logger from configuration.
Package logging builds the process-wide structured logger from configuration.
mcpserver
Package mcpserver embeds an OAuth 2.1-protected Model Context Protocol server inside gotifacts, exposing a single publish_site tool over Streamable HTTP.
Package mcpserver embeds an OAuth 2.1-protected Model Context Protocol server inside gotifacts, exposing a single publish_site tool over Streamable HTTP.
portal
Package portal serves static site content (host-routed) and the embedded management SPA.
Package portal serves static site content (host-routed) and the embedded management SPA.
router
Package router implements the URL ⇄ filesystem-path convention that is the core contract of gotifacts, plus host-based request classification.
Package router implements the URL ⇄ filesystem-path convention that is the core contract of gotifacts, plus host-based request classification.
store
Package store is the SQLite-backed registry: the sole source of truth for sites and API keys.
Package store is the SQLite-backed registry: the sole source of truth for sites and API keys.
Package web embeds the built management SPA (web/dist) for serving by the portal.
Package web embeds the built management SPA (web/dist) for serving by the portal.

Jump to

Keyboard shortcuts

? : This menu
/ : Search site
f or F : Jump to
y or Y : Canonical URL