Go · minimal infra · defensive defaults

About this site

A small Go web server with a deliberately small surface area: no CMS, no database, no reverse-proxy tier, just explicit routing, embedded files, and a security posture that’s strict by default.

RuntimeDigitalOcean · single node · Docker
StackGo (net/http/templates) · chi
TLSLet’s Encrypt autocert · TLS 1.3 only
Opstimeouts · throttling · request IDs · /ping

What’s here

Expand a section if you want the implementation details. Everything below matches what the server is doing in production.

How it runs Process, ports, static
  • Single node deployment (DigitalOcean Droplet).
  • One Go binary running in a Docker container (no Nginx/Caddy in front).
  • Production listeners:
    • :80 serves ACME HTTP-01 + /ping and redirects everything else to HTTPS.
    • :443 serves the actual site over TLS (autocert).
  • Embedded assets are served directly by the application, split into UI assets (CSS/JS/fonts) and media assets (gallery images).
  • Hotlink protection applies only to media assets under /static/albums/*, using Sec-Fetch-Site with a Referer allowlist fallback.
Security posture headers, CSP, CSRF
  • TLS 1.3 only (minimum pinned).
  • HSTS enabled on HTTPS responses (max-age=15552000; includeSubDomains).
  • Strict security headers including:
    • X-Frame-Options: DENY (clickjacking)
    • X-Content-Type-Options: nosniff
    • Referrer-Policy: strict-origin-when-cross-origin
    • Permissions-Policy disables camera/mic/geolocation
  • Locked-down CSP (default-src 'none', allowlisted 'self' resources; no inline JS/CSS). On HTTPS, upgrade-insecure-requests is enabled.
  • Cross-origin hardening: COOP (same-origin) and CORP (same-origin) are enabled. COEP is intentionally not enabled by default to avoid breaking third-party resources.
  • CSRF protection is scoped to the contact form (gorilla/csrf).
  • Low-interaction bot filtering via a hidden honeypot field (company_fax).
  • Contact submit body capped using MaxBytesReader (64KB).
Operational defaults timeouts, throttles, logging
  • Timeouts at the server level plus a 20s middleware timeout.
  • Throttling: light for public GET/HEAD, stricter for contact form POST.
  • Request IDs and sanitized single-line logs (parser-safe).
  • Health: /ping endpoint (also used by Docker healthchecks).
  • Configuration: production is fully env-driven (no dotenv loading in prod).
Caching behavior HTML vs UI assets vs media
  • HTML responses: Cache-Control: no-cache, must-revalidate. Browsers may store HTML but must revalidate before reuse (applies only to page routes).
  • HTML ETag: strong, content-based ETag (hash of the rendered HTML), enabling efficient 304 Not Modified responses.
  • UI assets (CSS / JS / SVG): precompressed at build time, embedded into the binary, and served with Brotli (br) preferred and gzip as fallback. Responses include Vary: Accept-Encoding.
  • UI asset caching: Cache-Control: public, max-age=0, must-revalidate, allowing updates to propagate without filename versioning.
  • Media assets (gallery images): served as-is (no additional compression), already optimized formats (WebP/JPEG), with hotlink protection applied to /static/albums/*.
  • ETags:
    • UI assets use strong, content-based ETags for the exact bytes served (identity vs br/gzip).
    • Media assets use content-based ETags without encoding variance.
  • Fonts: cached long-term (max-age=31536000).