Skip to content

Self-hosting

Plystra v1.0 is designed to be self-hosted with PostgreSQL. The recommended production pattern is:

reverse proxy / load balancer
-> plystra-core
-> PostgreSQL

Use the provided Dockerfile, docker-compose.yml, migrations, and plystractl checks as the baseline.

Terminal window
cp .env.example .env
docker compose up -d

Important Compose variables:

VariableDefaultPurpose
SERVER_PORT8080Host port for Core.
DOCKER_DATABASE_URLCompose PostgreSQL URLDatabase URL used by the container.
CORS_ALLOWED_ORIGINS* in Compose fallbackDevelopment-friendly fallback. Production mode rejects wildcard CORS.
PLYSTRA_ADMIN_TOKENdevelopment placeholderBootstrap token for protected routes.
DATA_CONSOLE_ENABLEDfalseKeeps preview data routes disabled.
METRICS_ENABLEDfalseKeeps /metrics disabled.

For local development, .env.example uses explicit localhost CORS values.

Always apply migrations before relying on the server:

Terminal window
go run ./cmd/plystractl migrate up
go run ./cmd/plystractl migrate verify
go run ./cmd/plystractl ent check
go run ./cmd/plystractl doctor

Production upgrades must use versioned migrations. Do not use Ent auto migration as the production upgrade mechanism.

Terminal window
go run ./cmd/plystrad

or with Compose:

Terminal window
docker compose up -d plystra-core

Core exposes:

GET /api/v1/health
GET /api/v1/ready
GET /api/v1/version

The readiness endpoint checks database connectivity and expected migration/schema state.

When SERVER_MODE=production, startup validates:

SettingProduction rule
DATABASE_URL or PLYSTRA_DATABASE_URLRequired; must not use default plystra:plystra credentials.
PLYSTRA_SESSION_SECRET, SESSION_SECRET, JWT_SECRET, or PLYSTRA_JWT_SECRETAt least 32 characters and not a default placeholder.
PLYSTRA_ADMIN_TOKEN or ADMIN_TOKENAt least 32 characters and not a default placeholder.
CORS_ALLOWED_ORIGINSRequired; must not include *.
SERVER_PUBLIC_URL or PLYSTRA_SERVER_PUBLIC_URLRequired; must not point to localhost.

JWT_SECRET is a compatibility alias. The current runtime uses opaque bearer tokens, stores HMAC token hashes, and does not issue JWT claims.

Plystra only trusts forwarded IP headers when TRUSTED_PROXIES is configured. Otherwise request IP metadata comes from RemoteAddr.

Use this only for reverse proxies you operate:

TRUSTED_PROXIES=127.0.0.1,10.0.0.0/8

Keep production audit mode enabled:

AUDIT_WRITE_MODE=always
TRACE_VERSION=1.0

Authorization decisions and Core management mutations write audit traces. AuditLog is append-only and should be included in backup and retention planning.

Before upgrading:

  1. Read release notes.
  2. Run plystractl doctor.
  3. Back up PostgreSQL.
  4. Stop or quiesce write traffic if needed.
  5. Apply migrations.
  6. Run migrate verify, ent check, and doctor.
  7. Smoke test health, ready, version, authz/check, authz/explain, Resource Registry, and AuditLog query.

Minimum backup:

Terminal window
pg_dump "$DATABASE_URL" > plystra-backup.sql

Store backups outside the server and verify restore on staging for production deployments.