Deployment
Render your infrastructure. Include operators when you want them.
GitHub Actions
Render TSX to YAML in CI. Use --include-operators to fetch and include operator manifests. Commit the output — your GitOps tool applies everything.
How It Works
1. Push→Push r8s.tsx to main
2. Render→CI renders TSX → YAML
3. Commit→Rendered YAML committed back to repo
4. Apply→GitOps tool applies YAML to cluster
GitHub Actions Workflow
name: Render & Deploy
on:
push:
branches: [main]
paths:
- 'k8s/**'
jobs:
render:
runs-on: ubuntu-latest
permissions:
contents: write
steps:
- uses: actions/checkout@v4
- uses: actions/setup-node@v4
with:
node-version: '20'
cache: 'npm'
- run: npm ci
- run: npx r8s render --entry k8s/r8s.tsx --out k8s/rendered/ --include-operators
- name: Commit rendered manifests
run: |
git config --local user.email "action@github.com"
git config --local user.name "GitHub Action"
git add k8s/rendered/
git diff --quiet && git diff --staged --quiet || \
(git commit -m "chore: render manifests [skip ci]" && git push)Including Operators
By default, r8s renders only your resources. Use --include-operators to fetch and include operator manifests in the output. This is useful when each team manages their own operators, or when you want a self-contained deployment.
# Render with operators included
npx r8s render --include-operators
# Render only operators (for platform teams)
npx r8s operators --out operators.yaml
# Render without operators (default)
npx r8s render# Operator: cnpg v1.22.5
apiVersion: v1
kind: Namespace
metadata:
name: cnpg-system
---
# Operator: cert-manager v1.14.0
apiVersion: v1
kind: Namespace
metadata:
name: cert-manager
---
# Your resources
apiVersion: apps/v1
kind: Deployment
metadata:
name: api
# ...Project Structure
Your repository only needs TSX source files:
my-project/
├── k8s/
│ └── r8s.tsx # Your entire infrastructure
├── .github/
│ └── workflows/
│ └── deploy.yaml # Optional: GitHub Actions
└── package.jsonYour Infrastructure
Define everything in k8s/r8s.tsx:
// k8s/r8s.tsx
import { App } from '@r8s/recipes';
export default (
<App
name="api"
image="myapp/api:v1.2.3"
host="api.example.com"
replicas={3}
database={{ name: "app-db", storage: "10Gi" }}
tls={{ issuer: "letsencrypt" }}
/>
);Multi-Environment
Use overlays for different environments:
// k8s/overlays/staging/r8s.tsx
import { App } from '@r8s/recipes';
export default (
<App
name="myapp-staging"
image="myapp/api:latest"
host="staging.example.com"
replicas={1}
database={{ name: "staging-db", storage: "5Gi" }}
/>
);
// k8s/overlays/production/r8s.tsx
import { App } from '@r8s/recipes';
export default (
<App
name="myapp"
image="myapp/api:v1.2.3"
host="api.example.com"
replicas={3}
database={{ name: "app-db", storage: "20Gi" }}
tls={{ issuer: "letsencrypt" }}
/>
);