Docs/Operations

Operations

Production deployment

Deploy SAG with PostgreSQL/pgvector, HTTPS, and an external access-control layer.
Updated 2026-07-22Applies to SAG v1.2.2

SAG is currently designed as a local, single-user product. The first production rule is: do not expose the Web and API ports directly to the public internet. Use HTTPS and place a VPN, IP allowlist, or authenticated reverse proxy in front of the application.

text
trusted user
  -> HTTPS / access control
  -> SAG Web
  -> SAG API
  -> PostgreSQL + pgvector
  -> persistent upload/index volume

SAG JWT provides identity inside the application but does not replace perimeter access control on the public internet.

Prepare configuration

bash
cp .env.example .env
openssl rand -hex 32
openssl rand -hex 24

Use the first random value for SAG_SECRET_KEY and the second for POSTGRES_PASSWORD. Set the real domains at the same time:

dotenv
SAG_ENVIRONMENT=prod
SAG_SECRET_KEY=<STRONG_RANDOM_VALUE>
POSTGRES_PASSWORD=<STRONG_DATABASE_PASSWORD>
SAG_CORS_ORIGINS=https://sag.example.com
NEXT_PUBLIC_API_BASE=https://sag-api.example.com

SAG_ENVIRONMENT=prod rejects known weak development secrets from the Compose configuration.

PostgreSQL and pgvector

The repository provides a production override:

bash
docker compose \
  -f compose.yaml \
  -f compose.postgres.yaml \
  config

docker compose \
  -f compose.yaml \
  -f compose.postgres.yaml \
  up -d --build

The override stores application metadata and SAG relational data in PostgreSQL and uses pgvector as the vector backend. pgdata holds the database, while sagdata continues to hold uploads and the engine data directory.

Reverse-proxy requirements

At minimum, the proxy must:

  • provide valid HTTPS for both Web and API;
  • forward Host, X-Forwarded-Proto, and the client address;
  • disable response buffering and allow long-lived connections for SSE routes;
  • set a suitable request-body limit for document uploads;
  • enforce access control before traffic reaches SAG.

If Web and API use different origins, SAG_CORS_ORIGINS must contain the exact Web origin. Do not replace an explicit origin with public *.

Build-time API address

NEXT_PUBLIC_API_BASE is embedded in the Web image. Rebuild Web after changing the domain, protocol, or port:

bash
docker compose \
  -f compose.yaml \
  -f compose.postgres.yaml \
  up -d --build web

Health checks

An orchestrator should check each component separately:

  • Web: the root path returns a status below 500;
  • API: GET /api/v1/system/ready returns 200;
  • PostgreSQL: pg_isready succeeds.

health only means that a process can respond. ready means critical dependencies can accept application traffic.

Data protection

Back up both pgdata and sagdata before an upgrade. A database-only backup loses uploaded files; a volume-only backup loses application metadata and index relationships.

Manage model keys, database passwords, and SAG_SECRET_KEY as secrets. Never place them in an image, public repository, or frontend environment variable.

Go-live checklist

  • External access passes through HTTPS and an authentication layer.
  • API readiness, document ingestion, fast/precise retrieval, cited conversations, and MCP each pass an acceptance check.
  • SSE continues streaming through the proxy.
  • Backups can restore into an independent environment.
  • Ports 3000, 8000, and 5432 are not directly exposed to the public internet.
Found an issue? Treat the public repository as the source of truth.View SAG source