Skip to main content

Reference configurations

Two named configurations rather than a blank values file. Each ships in the install kit, and each is reproduced in full on this page, so you can read it before you download anything.

ConfigurationForRedundancyStorage
Single nodeEvaluation, training, upgrade rehearsalNoneSmallest
ProductionAnything you depend onFullSmallest production grade

Single node

Not for production. Everything at one replica on one node. Losing the node loses the data.

Ships as three overlays in the kit:

$KIT/examples/single-node/infra-values.yaml
$KIT/examples/single-node/data-values.yaml
$KIT/examples/single-node/platform-values.yaml

Layer each one after the production values file, so it wins. Full procedure: Quickstart.

ProductionSingle node
Object store3 replicas, erasure coded, StatefulSet1 replica, standalone, Deployment
Postgres3 instances, both poolers on1 instance, replica pooler off
Kafka3 brokers, replication factor 31 broker, every factor 1
Services2 or 3 replicas1 each
StorageClassYours, set explicitlyThe cluster's default (empty in the overlay)

What the overlays set

Verbatim from the v0.1.0 kit, so you can read them without unpacking it first.

infra-values.yaml — object store and cache
$KIT/examples/single-node/infra-values.yaml
# ============================================================================
# gen0sec-infra — SINGLE-NODE EVALUATION overlay
# ============================================================================
# Layered ON TOP of values-onprem.yaml (pass both, in this order):
# helm install g0s-infra charts/gen0sec-infra -n gen0sec-system \
# -f values/gen0sec-infra-values-onprem.yaml \
# -f examples/single-node/infra-values.yaml
#
# Shrinks the footprint to fit one worker node. NOT for production: the object
# store loses erasure coding and every component becomes a single point of
# failure. Use it for evaluation, training, and dry-running an upgrade.
# ============================================================================

rustfs:
# Distributed mode needs >= 2 nodes for erasure coding; on one node the pods
# would schedule but the cluster is not fault-tolerant anyway, so run the
# single-process server and be explicit about it.
mode:
standalone:
enabled: true
distributed:
enabled: false
replicaCount: 1
storageclass:
# Empty = the cluster's default StorageClass, matching values-onprem.yaml. On
# k3s that resolves to local-path, which this overlay used to hardcode — but a
# literal `local-path` exists on no other distribution, so the PVCs bound
# nowhere and only surfaced as pods Pending past the rollout timeout.
name: ""
dataStorageSize: 20Gi
logStorageSize: 5Gi

dragonfly:
# Cache only — shrink it so the node's RAM goes to Postgres and Kafka. Keep
# maxMemory under resources.limits.memory so it evicts instead of being killed.
maxMemory: 256mb
proactorThreads: 1
resources:
requests: { cpu: 100m, memory: 128Mi }
limits: { cpu: 500m, memory: 512Mi }
data-values.yaml — Postgres and Kafka
$KIT/examples/single-node/data-values.yaml
# ============================================================================
# gen0sec-data — SINGLE-NODE EVALUATION overlay
# ============================================================================
# helm install g0s-data charts/gen0sec-data -n gen0sec-system \
# -f values/gen0sec-data-values-onprem.yaml \
# -f examples/single-node/data-values.yaml
#
# One Postgres instance, one Kafka node, replication factor 1. Any node loss is
# data loss — evaluation only.
# ============================================================================

postgres:
numberOfInstances: 1
# With a single instance there is no replica to pool.
enableReplicaConnectionPooler: false
volume:
size: 20Gi
# Empty = the cluster's default StorageClass (see infra-values.yaml).
storageClass: ""
resources:
requests: { cpu: 500m, memory: 1Gi }
limits: { cpu: "4", memory: 6Gi }
parameters:
shared_buffers: 512MB
effective_cache_size: 1536MB
max_connections: "400"
max_worker_processes: "16"
max_parallel_workers: "8"
timescaledb.max_background_workers: "8"

kafka:
replicas: 1
storage:
size: 20Gi
# Empty = the cluster's default StorageClass (see infra-values.yaml).
class: ""
# min.insync.replicas must stay < replicas, so every factor drops to 1
# together with the node count.
config:
offsets.topic.replication.factor: 1
transaction.state.log.replication.factor: 1
transaction.state.log.min.isr: 1
default.replication.factor: 1
min.insync.replicas: 1
log.compression.type: zstd
topicDefaults:
partitions: 1
replicas: 1
platform-values.yaml — one replica per service
$KIT/examples/single-node/platform-values.yaml
# ============================================================================
# gen0sec-platform — SINGLE-NODE EVALUATION overlay
# ============================================================================
# helm install g0s charts/gen0sec-platform -n gen0sec \
# -f values/gen0sec-platform-values-onprem.yaml \
# -f examples/single-node/platform-values.yaml \
# --set global.imageTag=$VERSION --timeout 20m
#
# One replica of everything: no HA, and a rolling update is a short outage per
# service. Resource requests are unchanged — they are already small.
# ============================================================================

services:
auth-api: { replicaCount: 1 }
ban-ledger-api: { replicaCount: 1 }
config-api: { replicaCount: 1 }
data-api: { replicaCount: 1 }
download-api: { replicaCount: 1 }
feeds-api: { replicaCount: 1 }
ids-rules-api: { replicaCount: 1 }
rules-validator: { replicaCount: 1 }
service-graph-api: { replicaCount: 1 }
signal-api: { replicaCount: 1 }
telemetry-api: { replicaCount: 1 }
threat-api: { replicaCount: 1 }
agent-status: { replicaCount: 1 }
ui: { replicaCount: 1 }

Production

The default. values-onprem.yaml in the bundle is the production configuration, so there is no overlay to apply: what you install in Install is this.

What you set yourself:

# gen0sec-infra
rustfs:
storageclass:
name: your-block-storage-class

# gen0sec-data
postgres:
volume:
storageClass: your-block-storage-class
kafka:
storage:
class: your-block-storage-class

For requirements see Sizing.

Extending retention

The shipped sizes are deliberately modest, so growing is the normal direction. Which key you grow depends on what you are retaining. See Sizing storage for your retention.

eg.

# gen0sec-data
postgres:
volume:
size: 200Gi
storageClass: your-block-storage-class
kafka:
storage:
size: 200Gi
class: your-block-storage-class
# gen0sec-infra
rustfs:
storageclass:
name: your-block-storage-class
dataStorageSize: 100Gi
You can also grow later

Volume expansion grows a volume if your StorageClass has allowVolumeExpansion: true. Starting at the defaults and expanding when you need to is a reasonable plan, and it is the direction that works: nothing shrinks a volume.

Publishing endpoints

Independent of the three above, and needed by all of them:

$KIT/examples/single-entrypoint/ingress-values.yaml

One address for the dashboard and every agent-facing API, routed by path prefix. See Publish the endpoints for the route table and the two values you set.

The header of that file, with both customer inputs and why they exist

The rest of the file is the per-service route list. It is reproduced as a table on Publish the endpoints rather than twice here.

$KIT/examples/single-entrypoint/ingress-values.yaml (head)
# ============================================================================
# gen0sec-platform — SINGLE-ENTRYPOINT INGRESS overlay
# ============================================================================
# Publishes the dashboard and the agent-facing APIs through ONE address, served
# by the Synapse proxy that gen0sec-infra deploys for the `synapse` IngressClass.
#
# helm upgrade --install g0s charts/gen0sec-platform -n gen0sec \
# -f values/gen0sec-platform-values-onprem.yaml \
# -f examples/single-entrypoint/ingress-values.yaml
#
# Layered ON TOP of values-onprem.yaml, which leaves every ingress disabled.
# That default is deliberate — turning this on makes the APIs reachable from
# wherever the proxy Service is reachable — so this is opt-in, not the default.
#
# A HOST IS REQUIRED — set `entrypointHost` below, it is aliased into every
# rule. Host-less rules do NOT work with this controller even though the chart
# renders them: synapse's upstreams.yaml is keyed by host, and the operator
# skips any rule with an empty host (controllers/ingress_controller.go, "if
# host == \"\" || rule.HTTP == nil { continue }"). Such a rule produces an
# Ingress object that its own controller silently ignores, with no event and no
# log line.
#
# The dashboard needs this host to be the address people actually type:
# BETTER_AUTH_URL is derived from it (services.ui.urlFromIngress), and sign-in
# breaks otherwise.
#
# ROUTING IS BY PATH PREFIX, because one address serves every backend. The
# prefixes below are the real route roots, read off each service's router --
# they are not a naming convention and do not survive being guessed at.
#
# One overlap to keep in mind, resolved by longest-prefix matching:
# /v1/agents/events config-api serves this; data-api owns /v1/agents
# If a request lands on the wrong backend, that is the first thing to check.
#
# /v1/ids-rules goes to download-api, NOT the in-cluster ids-rules-api: in proxy
# mode IDS rules are relayed from the platform, and ids-rules-api serves a local
# ET ingest that this edition does not run.
# ============================================================================

# CUSTOMER-INPUT: the single address every rule below is published under.
entrypointHost: &entrypointHost gen0sec.internal

# CUSTOMER-INPUT: the scheme users actually reach that address on.
#
# Only needed when TLS terminates UPSTREAM of the Ingress -- a cloud load
# balancer, a CDN, a tunnel. The chart otherwise infers the scheme from the
# Ingress's own `tls:` block, which is absent in that setup, so it guesses http
# while the browser is on https. The dashboard hands this to Better Auth as its
# base URL and every sign-in is then rejected with "Invalid origin".
#
# Leave it unset when TLS terminates at the Ingress (i.e. you set ingress.tls).
externalScheme: &externalScheme https

Keeping your overrides

Put them in a file under version control, not in --set arguments.

helm upgrade g0s $B/charts/gen0sec-platform-*.tgz -n gen0sec \
-f $B/values/gen0sec-platform-values-onprem.yaml \
-f my-site/platform.yaml \
--set global.imageTag=$VERSION \
--timeout 20m

helm upgrade uses only what you pass it. Anything set with --set on a previous install and omitted now reverts to the chart default, silently. A file makes that impossible to forget.

Two things that are awkward to keep in a file, because they are per-release or per-secret:

Keep as --setWhy
global.imageTagChanges every release
downloadProxy.apiKeySecret.nameOr put it in your file. Just never omit it. See Data relay

What the kit contains

ls $KIT/examples/*/

Everything under examples/ is a starting point you are meant to read and edit, not a black box. Each file carries comments explaining which values are yours to set.