scaffold: project skeleton, schema, healthz/readyz, CI
Initial project structure for neuronetz-gateway per scope-docs/SPEC.md: - Python 3.12 / FastAPI / SQLAlchemy 2.0 (async) / Redis / Postgres stack managed by uv. Multi-stage non-root Dockerfile, prod + dev compose files (ollama service is NEVER published in either), Caddyfile + systemd unit, justfile, GitHub Actions CI (ruff, mypy --strict, pytest, bandit, pip-audit). - Pydantic-Settings config covering every env var from SPEC §7, including the MODEL_DISCOVERY_* keys for the dynamic-discovery feature (§4.6). - Alembic 0001_initial creates the full gateway schema (8 tables, 3 enums, notify_key_revoked() trigger), incl. allow_all_models on tenant_limits and key_limits for the per-tenant auto-grant toggle. - Working /healthz, /readyz (fail-closed when deps unreachable), and a Prometheus /metrics stub. Sanitizing error handlers that attach X-Request-ID to every response and never leak upstream internals. - SPEC + AGENT_PROMPT included under scope-docs/ (source of truth).
This commit is contained in:
59
ops/caddy/Caddyfile.example
Normal file
59
ops/caddy/Caddyfile.example
Normal file
@@ -0,0 +1,59 @@
|
||||
# neuronetz-gateway — Caddy reverse proxy (SPEC §4.1, §6.5).
|
||||
#
|
||||
# Caddy is the only public-facing component. It terminates TLS (HTTP/2 + HTTP/3),
|
||||
# obtains a Let's Encrypt certificate for api.neuronetz.ai automatically, applies
|
||||
# security headers, and reverse-proxies to the internal-only gateway:8080.
|
||||
#
|
||||
# Copy this file to `Caddyfile` and edit the site address / admin email.
|
||||
# The production docker-compose.yml mounts it at /etc/caddy/Caddyfile.
|
||||
{
|
||||
# Email for Let's Encrypt account + expiry notices. Replace before deploy.
|
||||
email ops@neuronetz.ai
|
||||
}
|
||||
|
||||
api.neuronetz.ai {
|
||||
# --- Reverse proxy to the internal gateway ---
|
||||
# `gateway` is the Docker service name on the internal network; it is never
|
||||
# published to the host. Caddy forwards plain HTTP/1.1 to it.
|
||||
reverse_proxy gateway:8080
|
||||
|
||||
# --- Security headers ---
|
||||
header {
|
||||
# HSTS: force HTTPS for two years, include subdomains, allow preload.
|
||||
Strict-Transport-Security "max-age=63072000; includeSubDomains; preload"
|
||||
# Disable MIME sniffing.
|
||||
X-Content-Type-Options "nosniff"
|
||||
# Clickjacking defense (API has no UI, deny framing outright).
|
||||
X-Frame-Options "DENY"
|
||||
# Conservative referrer policy.
|
||||
Referrer-Policy "no-referrer"
|
||||
# Strip server-identifying headers so we don't advertise the stack.
|
||||
-Server
|
||||
-X-Powered-By
|
||||
}
|
||||
|
||||
# Structured access logs to stdout (collected by the container runtime).
|
||||
log {
|
||||
output stdout
|
||||
format json
|
||||
}
|
||||
}
|
||||
|
||||
# ─────────────────────────────────────────────────────────────────────────────
|
||||
# DEV / LOCAL note:
|
||||
#
|
||||
# For local testing without a public domain or real certificate, replace the
|
||||
# site block above with a localhost block that uses Caddy's internal self-signed
|
||||
# CA (no Let's Encrypt round-trip):
|
||||
#
|
||||
# localhost {
|
||||
# tls internal
|
||||
# reverse_proxy gateway:8080
|
||||
# }
|
||||
#
|
||||
# Caddy will install its local root CA; trust it or pass `-k` to curl. Note the
|
||||
# Phase 1 *dev* compose stack (docker-compose.dev.yml) ships WITHOUT Caddy and
|
||||
# exposes the gateway directly on localhost:8080 — this file is for the full
|
||||
# production stack only.
|
||||
# ─────────────────────────────────────────────────────────────────────────────
|
||||
|
||||
Reference in New Issue
Block a user