Getting Started
From zero to production-ready in 5 steps
Your First App
One component. Three resources. Deployment, Service, and Ingress — all wired together.
import { App } from '@r8s/recipes';
export default () => (
<App
name="myapp"
image="nginx:latest"
host="myapp.example.com"
/>
);# 3 resources created:
# - Deployment (myapp)
# - Service (myapp)
# - Ingress (myapp-endpoint)Run npx r8s render to see the full YAML output.
Add a Database
Add a PostgreSQL database with one line. CNPG creates the cluster, manages credentials, and auto-wires the connection string to your app.
import { App, Database } from '@r8s/recipes';
export default () => (
<>
<Database name="myapp-db" storage="10Gi" />
<App
name="myapp"
image="myapp:v1"
host="myapp.example.com"
/>
</>
);# 5 resources created:
# - Cluster (myapp-db) — CNPG PostgreSQL
# - Deployment (myapp)
# - Service (myapp)
# - Ingress (myapp-endpoint)
# - Secret (myapp-db-app) — auto-generated credentialsThe DATABASE_URL environment variable is automatically set in your Deployment.
Add Monitoring
Prometheus scraping with one component. The operator is declared automatically.
import { App, Database, Monitoring } from '@r8s/recipes';
export default () => (
<>
<Database name="myapp-db" storage="10Gi" />
<App
name="myapp"
image="myapp:v1"
host="myapp.example.com"
/>
<Monitoring
name="myapp-monitor"
selector={{ app: 'myapp' }}
/>
</>
);# 7 resources created:
# - Cluster (myapp-db)
# - Deployment (myapp)
# - Service (myapp)
# - Ingress (myapp-endpoint)
# - Secret (myapp-db-app)
# - ServiceMonitor (myapp-monitor) — Prometheus scraping
# - Prometheus Operator — declared as dependencyAdd Providers
Wrap your app in providers for secrets, DNS, and routing. Each provider declares its required operators.
import { SecretProvider, DnsProvider, EndpointProvider, App, Database, Monitoring } from '@r8s/recipes';
export default () => (
<SecretProvider provider="openbao">
<DnsProvider provider="external-dns">
<EndpointProvider provider="nginx">
<Database name="myapp-db" storage="10Gi" />
<App
name="myapp"
image="myapp:v1"
host="myapp.example.com"
/>
<Monitoring
name="myapp-monitor"
selector={{ app: 'myapp' }}
/>
</EndpointProvider>
</DnsProvider>
</SecretProvider>
);# 9 resources created:
# - Cluster (myapp-db)
# - Deployment (myapp)
# - Service (myapp)
# - Ingress (myapp-endpoint)
# - OpenBaoStaticSecret (myapp-db-app) — synced from OpenBao
# - ServiceMonitor (myapp-monitor)
# - DNSEndpoint (myapp-endpoint-dns) — automatic DNS record
# - Prometheus Operator
# - ExternalDNS Operator
# - Vault Secrets OperatorNow your secrets come from OpenBao, DNS records are created automatically, and routing uses nginx with TLS.
Production Ready
Full production setup: Keycloak for auth, Redis for cache, Loki for logs, TSIG for DNS, and TLS everywhere. All operators declared, all secrets managed.
import { SecretProvider, OpenBao, DnsProvider, ExternalDns, EndpointProvider, Nginx, App, Database, Monitoring, Auth } from '@r8s/recipes';
export default () => (
<SecretProvider provider={<OpenBao mount="secret" path="myapp" />}>
<DnsProvider provider={<ExternalDns server="ns1.example.com" tsig={{ path: 'dns/tsig', key: 'secret' }} />}>
<EndpointProvider provider={<Nginx tls={{ clusterIssuer: 'letsencrypt-prod' }} />}>
<Database name="myapp-db" storage="20Gi" />
<Auth name="auth" host="auth.example.com" />
<App
name="myapp"
image="myapp:v1"
host="myapp.example.com"
replicas={3}
cache
/>
<Monitoring
name="myapp-monitor"
selector={{ app: 'myapp' }}
logs
/>
</EndpointProvider>
</DnsProvider>
</SecretProvider>
);# 15+ resources created:
# - Cluster (myapp-db) — CNPG PostgreSQL
# - Keycloak (auth) — Identity provider
# - Cluster (auth-db) — Keycloak's database
# - RedisCluster (myapp-cache) — Session store
# - Deployment (myapp) — 3 replicas
# - Service (myapp)
# - Ingress (myapp-endpoint) — TLS via cert-manager
# - Ingress (auth-endpoint) — TLS via cert-manager
# - OpenBaoStaticSecret (myapp-db-app)
# - OpenBaoStaticSecret (auth-db-app)
# - OpenBaoStaticSecret (external-dns-tsig) — TSIG for DNS updates
# - ServiceMonitor (myapp-monitor)
# - LokiStack (myapp-monitor-loki) — Log aggregation
# - Logging (myapp-monitor-logging)
# - Flow (myapp-monitor-flow)
# - Output (myapp-monitor-loki-output)
# - DNSEndpoint (myapp-endpoint-dns)
# - DNSEndpoint (auth-endpoint-dns)
# - All operators declared automaticallyThis is a complete production stack — auth, database, cache, monitoring, logging, DNS, and TLS — in ~30 lines of TypeScript.
What's next?
- Browse all recipes — Auth, Backup, Monitoring, and more
- Core concepts — Providers, context, and composition
- Deployment — FluxCD, GitHub Actions, and GitOps