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:
:80serves ACME HTTP-01 +/pingand redirects everything else to HTTPS.:443serves 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/*, usingSec-Fetch-Sitewith 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: nosniffReferrer-Policy: strict-origin-when-cross-originPermissions-Policydisables camera/mic/geolocation
-
Locked-down CSP (
default-src 'none', allowlisted'self'resources; no inline JS/CSS). On HTTPS,upgrade-insecure-requestsis enabled. -
Cross-origin hardening:
COOP(same-origin) andCORP(same-origin) are enabled.COEPis 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
20smiddleware timeout. - Throttling: light for public GET/HEAD, stricter for contact form POST.
- Request IDs and sanitized single-line logs (parser-safe).
- Health:
/pingendpoint (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 Modifiedresponses. -
UI assets (CSS / JS / SVG):
precompressed at build time, embedded into the binary, and served with
Brotli(br) preferred andgzipas fallback. Responses includeVary: 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.
- UI assets use strong, content-based ETags for the exact bytes served
(identity vs
- Fonts: cached long-term (
max-age=31536000).