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).
59 lines
1.8 KiB
Desktop File
59 lines
1.8 KiB
Desktop File
# neuronetz-gateway — systemd unit for non-Compose deployments.
|
|
#
|
|
# Assumes the project is installed into a virtualenv at /opt/neuronetz-gateway/venv
|
|
# (e.g. `uv venv /opt/neuronetz-gateway/venv && uv pip install ...`) and that
|
|
# configuration lives in /etc/neuronetz-gateway/gateway.env (same keys as
|
|
# .env.example). Postgres, Redis and Ollama are reached over the network/loopback
|
|
# per that env file — Ollama must remain bound to localhost / a private network
|
|
# and never be published publicly.
|
|
#
|
|
# Install:
|
|
# sudo cp neuronetz-gateway.service /etc/systemd/system/
|
|
# sudo systemctl daemon-reload
|
|
# sudo systemctl enable --now neuronetz-gateway
|
|
|
|
[Unit]
|
|
Description=neuronetz-gateway — secure API gateway in front of Ollama
|
|
Documentation=https://github.com/neuronetz/neuronetz-gateway
|
|
After=network-online.target
|
|
Wants=network-online.target
|
|
|
|
[Service]
|
|
Type=simple
|
|
|
|
# Dedicated unprivileged service account (create with: useradd --system gateway).
|
|
User=gateway
|
|
Group=gateway
|
|
|
|
WorkingDirectory=/opt/neuronetz-gateway
|
|
EnvironmentFile=/etc/neuronetz-gateway/gateway.env
|
|
|
|
# Apply migrations before starting (idempotent; no-op when already at head).
|
|
ExecStartPre=/opt/neuronetz-gateway/venv/bin/alembic upgrade head
|
|
ExecStart=/opt/neuronetz-gateway/venv/bin/python -m neuronetz_gateway
|
|
|
|
Restart=on-failure
|
|
RestartSec=5
|
|
TimeoutStopSec=30
|
|
|
|
# --- Hardening ---
|
|
NoNewPrivileges=true
|
|
ProtectSystem=strict
|
|
ProtectHome=true
|
|
PrivateTmp=true
|
|
PrivateDevices=true
|
|
ProtectKernelTunables=true
|
|
ProtectKernelModules=true
|
|
ProtectControlGroups=true
|
|
RestrictNamespaces=true
|
|
RestrictRealtime=true
|
|
RestrictSUIDSGID=true
|
|
LockPersonality=true
|
|
MemoryDenyWriteExecute=true
|
|
RestrictAddressFamilies=AF_INET AF_INET6 AF_UNIX
|
|
# Allow writing only where the app legitimately needs to (none by default).
|
|
ReadWritePaths=
|
|
|
|
[Install]
|
|
WantedBy=multi-user.target
|