Repository navigation
Quick Start
Get up and running with Timonel in minutes! This guide will walk you through creating your first Helm chart using Timonel.
Before you begin, make sure you have the following installed:
- Node.js 20+ and npm
- Kubernetes cluster (local or remote)
- Helm 3.x
- kubectl configured
npm install -g timonelnpm install timonel
npx tl --versionLet's create a simple web application chart step by step.
# Create a new chart
tl init my-first-chart
# Navigate to the chart directory
cd my-first-chartThis creates a new directory with the following structure:
my-first-chart/
├── chart.ts # Main chart definition
├── package.json # Dependencies
├── tsconfig.json # TypeScript configuration
└── README.md # Chart documentation
Edit chart.ts to define your application:
import { Rutter, helmInclude, createHelmExpression as helm } from 'timonel';
// Chart metadata
const chartMetadata = {
name: 'my-first-chart',
version: '1.0.0',
description: 'My first Timonel chart'
};
// Default values
const defaultValues = {
replicas: 3,
image: {
repository: 'nginx',
tag: 'latest'
},
service: {
type: 'ClusterIP',
port: 80
},
ingress: {
enabled: true,
host: 'myapp.local'
}
};
// Create Rutter instance
const rutter = new Rutter({
meta: chartMetadata,
defaultValues
});
// Add Deployment
rutter.addManifest({
apiVersion: 'apps/v1',
kind: 'Deployment',
metadata: {
name: helmInclude('chart.fullname', '.'),
labels: helmInclude('chart.labels', '.', { pipe: 'nindent 4' })
},
spec: {
replicas: helm('{{ .Values.replicas }}'),
selector: {
matchLabels: helmInclude('chart.selectorLabels', '.', { pipe: 'nindent 6' })
},
template: {
metadata: {
labels: helmInclude('chart.selectorLabels', '.', { pipe: 'nindent 8' })
},
spec: {
containers: [{
name: 'web',
image: helm('{{ .Values.image.repository }}:{{ .Values.image.tag }}'),
ports: [{
containerPort: helm('{{ .Values.service.port }}'),
name: 'http'
}],
resources: {
requests: {
memory: '64Mi',
cpu: '100m'
},
limits: {
memory: '128Mi',
cpu: '200m'
}
}
}]
}
}
}
}, 'web-deployment');
// Add Service
rutter.addManifest({
apiVersion: 'v1',
kind: 'Service',
metadata: {
name: helmInclude('chart.fullname', '.'),
labels: helmInclude('chart.labels', '.', { pipe: 'nindent 4' })
},
spec: {
type: helm('{{ .Values.service.type }}'),
ports: [{
port: helm('{{ .Values.service.port }}'),
targetPort: 'http',
protocol: 'TCP'
}],
selector: helmInclude('chart.selectorLabels', '.', { pipe: 'nindent 4' })
}
}, 'web-service');
// Add Ingress (conditional)
rutter.addConditionalManifest({
apiVersion: 'networking.k8s.io/v1',
kind: 'Ingress',
metadata: {
name: helmInclude('chart.fullname', '.'),
labels: helmInclude('chart.labels', '.', { pipe: 'nindent 4' }),
annotations: {
'kubernetes.io/ingress.class': 'nginx'
}
},
spec: {
rules: [{
host: helm('{{ .Values.ingress.host }}'),
http: {
paths: [{
path: '/',
pathType: 'Prefix',
backend: {
service: {
name: helmInclude('chart.fullname', '.'),
port: { number: helm('{{ .Values.service.port }}') }
}
}
}]
}
}]
}
}, '.Values.ingress.enabled', 'web-ingress');
// Generate the chart
rutter.write('./dist');# Compile TypeScript and generate Helm chart
tl synthThis creates a dist/ directory with your complete Helm chart:
dist/
├── Chart.yaml # Chart metadata
├── values.yaml # Default values
├── templates/
│ ├── _helpers.tpl # Helm template helpers
│ ├── web-deployment.yaml
│ ├── web-service.yaml
│ └── web-ingress.yaml
└── README.md
# Lint the generated chart
helm lint ./dist
# Template the chart (dry run)
helm template my-app ./dist
# Check what would be installed
helm template my-app ./dist --values ./dist/values.yaml# Install the chart
helm install my-app ./dist
# Check the installation
kubectl get all
# Check the status
helm status my-app# Get the service URL
kubectl get ingress
# Port forward for local testing
kubectl port-forward service/my-app 8080:80Visit http://localhost:8080 to see your application!
You can override values during installation:
# Install with custom values
helm install my-app ./dist --set replicas=5 --set image.tag=1.21
# Or use a values file
helm install my-app ./dist --values custom-values.yamlExtend your chart with additional Kubernetes resources:
// Add ConfigMap
rutter.addManifest({
apiVersion: 'v1',
kind: 'ConfigMap',
metadata: {
name: helm('{{ include "chart.fullname" . }}-config'),
labels: helmInclude('chart.labels', '.', { pipe: 'nindent 4' })
},
data: {
'app.properties': 'key=value\nanother=setting'
}
}, 'app-config');
// Add Secret
rutter.addManifest({
apiVersion: 'v1',
kind: 'Secret',
metadata: {
name: helm('{{ include "chart.fullname" . }}-secret'),
labels: helmInclude('chart.labels', '.', { pipe: 'nindent 4' })
},
type: 'Opaque',
data: {
'password': helm('{{ .Values.secret.password | b64enc }}')
}
}, 'app-secret');Define different values for different environments:
const rutter = new Rutter({
meta: chartMetadata,
defaultValues,
envValues: {
development: {
replicas: 1,
image: { tag: 'dev' }
},
production: {
replicas: 5,
image: { tag: 'stable' }
}
}
});1. TypeScript Compilation Errors
# Check TypeScript configuration
npx tsc --noEmit
# Install missing dependencies
npm install2. Helm Template Errors
# Validate template syntax
helm template my-app ./dist --debug
# Check for missing values
helm template my-app ./dist --values ./dist/values.yaml --debug3. Kubernetes Resource Errors
# Check resource status
kubectl describe deployment my-app
kubectl logs deployment/my-app
# Check events
kubectl get events --sort-by='.lastTimestamp'- Documentation: Check the API Reference
- Examples: See WordPress Example
- Issues: Report bugs on GitHub
Now that you have a basic understanding of Timonel, explore these advanced topics:
- AWS Integration - Add AWS-specific resources
- Umbrella Charts - Create complex multi-service applications
- Best Practices - Learn recommended patterns
- Custom Helpers - Create your own Helm template helpers
Happy charting! 🚀
Timonel documentation · Repository · npm · Issues