Skip to content

Quick Start

Franklin G. Mendoza edited this page Nov 26, 2025 · 15 revisions

Quick Start Guide

Get up and running with Timonel in minutes! This guide will walk you through creating your first Helm chart using Timonel.

Prerequisites

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

Installation

Option 1: Global Installation (Recommended)

npm install -g timonel

Option 2: Local Installation

npm install timonel
npx tl --version

Your First Chart

Let's create a simple web application chart step by step.

Step 1: Initialize a New Chart

# Create a new chart
tl init my-first-chart

# Navigate to the chart directory
cd my-first-chart

This 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

Step 2: Define Your Application

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');

Step 3: Synthesize the Chart

# Compile TypeScript and generate Helm chart
tl synth

This 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

Step 4: Validate Your Chart

# 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

Step 5: Install Your Chart

# Install the chart
helm install my-app ./dist

# Check the installation
kubectl get all

# Check the status
helm status my-app

Step 6: Access Your Application

# Get the service URL
kubectl get ingress

# Port forward for local testing
kubectl port-forward service/my-app 8080:80

Visit http://localhost:8080 to see your application!

Next Steps

Customize Values

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.yaml

Add More Resources

Extend 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');

Environment-Specific Values

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' }
    }
  }
});

Troubleshooting

Common Issues

1. TypeScript Compilation Errors

# Check TypeScript configuration
npx tsc --noEmit

# Install missing dependencies
npm install

2. 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 --debug

3. Kubernetes Resource Errors

# Check resource status
kubectl describe deployment my-app
kubectl logs deployment/my-app

# Check events
kubectl get events --sort-by='.lastTimestamp'

Getting Help

What's Next?

Now that you have a basic understanding of Timonel, explore these advanced topics:

Happy charting! 🚀

Clone this wiki locally