Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
26 changes: 26 additions & 0 deletions self-hosting/helm/.gitignore
Original file line number Diff line number Diff line change
@@ -0,0 +1,26 @@
# Helm chart values override files
values-*.yaml
custom-*.yaml
*.values.yaml

# Helm package files
*.tgz

# Temporary files
*.tmp
*.bak
*.swp

# IDE files
.vscode/
.idea/

# OS files
.DS_Store
Thumbs.db

# Secret files
secrets/
*.secret
*.key
*.pem
17 changes: 17 additions & 0 deletions self-hosting/helm/Chart.yaml
Original file line number Diff line number Diff line change
@@ -0,0 +1,17 @@
name: svix
description: A Helm chart for Svix webhook service
apiVersion: v2
version: 0.1.0
keywords:
- webhooks
- svix
- api
- kubernetes
home: https://www.svix.com
sources:
- https://github.com/svix/svix-webhooks
maintainers:
- name: Svix Team
email: [email protected]
icon: https://avatars.githubusercontent.com/u/80175132?s=200&v=4
appVersion: "1.0.0"
226 changes: 226 additions & 0 deletions self-hosting/helm/README.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,226 @@
# Svix Helm Chart

This Helm chart deploys the complete Svix webhook service stack on Kubernetes, including:

- **Svix Backend**: The main webhook service
- **PostgreSQL**: Database for storing webhook data
- **PgBouncer**: Connection pooler for PostgreSQL
- **Redis**: Cache and session storage

## Prerequisites

Before installing the Svix Helm chart, ensure you have the following components:

- **Kubernetes Cluster**: A running Kubernetes cluster (version 1.19 or later)
- **kubectl**: Kubernetes command-line tool installed and configured to communicate with your cluster
- **Helm**: Helm package manager installed (version 3.x)
- **Persistent Storage**: Access to a storage class for provisioning PersistentVolumeClaims
- **Ingress Controller**: (Optional but recommended) An ingress controller like NGINX for external access

## Installation

### 1. Clone the Repository

Since this is not an official Helm chart, you'll need to clone the Svix repository:

```bash
git clone https://github.com/svix/svix-webhooks.git
cd svix-webhooks/self-hosting/helm
```

### 2. Install the Chart

```bash
# Install with default values
helm install my-svix . --namespace default --create-namespace

# Install with custom values
helm install my-svix . -f custom-values.yaml --namespace default --create-namespace

# Install in a specific namespace
kubectl create namespace svix
helm install my-svix . --namespace svix
```

### 3. Access the Service

```bash
# Port forward to access the service
kubectl port-forward svc/my-svix-backend 8071:8071 --namespace default

# Access the Service at http://localhost:8071
```


## Production Deployment

For production deployments, consider the following:

### 1. Set Strong Secrets

```yaml
backend:
secrets:
jwtSecret: "your-production-jwt-secret-here"
mainSecret: "your-production-main-secret-here"
```

### 2. Configure Ingress with TLS

```yaml
ingress:
enabled: true
className: "nginx"
annotations:
kubernetes.io/ingress.class: nginx
cert-manager.io/cluster-issuer: "letsencrypt-prod"
nginx.ingress.kubernetes.io/ssl-redirect: "true"
hosts:
- host: svix.yourdomain.com
paths:
- path: /
pathType: Prefix
tls:
- secretName: svix-tls
hosts:
- svix.yourdomain.com
```

### 3. Enable Autoscaling

```yaml
backend:
autoscaling:
enabled: true
minReplicas: 2
maxReplicas: 10
targetCPUUtilizationPercentage: 70
```

### 4. Configure Resource Limits

```yaml
backend:
resources:
requests:
memory: "512Mi"
cpu: "500m"
limits:
memory: "1Gi"
cpu: "1000m"
```

### 5. Use External Databases (Optional)

If you want to use external PostgreSQL and Redis instances:

```yaml
postgres:
enabled: false

redis:
enabled: false

backend:
secrets:
dbDsn: "postgresql://user:password@your-external-postgresql-host:5432/database"
redisDsn: "redis://your-external-redis-host:6379"
```

### 6. Configure Persistence

```yaml
postgres:
persistence:
enabled: true
storageClass: "fast-ssd"
size: "50Gi"

redis:
persistence:
enabled: true
storageClass: "fast-ssd"
size: "20Gi"
```

## Monitoring and Health Checks

### Health Check Endpoints

The Svix backend provides health check endpoints:

```bash
# Check Svix health endpoint
kubectl exec -it deployment/my-svix-backend -- curl http://localhost:8071/api/v1/health

# Expected response: {"status":"ok"}
```

```

## Security Considerations

1. **JWT Secret**: Always use a cryptographically secure JWT secret (minimum 64 characters)
2. **Database Passwords**: Use strong, unique passwords for database access
3. **Network Policies**: Implement network policies to restrict pod-to-pod communication:

```yaml
apiVersion: networking.k8s.io/v1
kind: NetworkPolicy
metadata:
name: svix-network-policy
spec:
podSelector:
matchLabels:
app.kubernetes.io/name: svix
policyTypes:
- Ingress
- Egress
ingress:
- from:
- namespaceSelector:
matchLabels:
name: ingress-nginx
```

4. **RBAC**: Review and adjust service account permissions as needed
5. **Secrets Management**: Use external secret management systems like:
- AWS Secrets Manager
- HashiCorp Vault
- Azure Key Vault
- Google Secret Manager

6. **Image Security**: Use specific image tags instead of `latest` and scan images for vulnerabilities


## Contributing

We welcome contributions to improve this Helm chart! Please:

1. Fork the repository
2. Create a feature branch
3. Make your changes
4. Add tests if applicable
5. Submit a pull request


# Validate against Kubernetes
```
helm template my-svix . | kubectl apply --dry-run=client -f -
```

## License

This Helm chart is released under the MIT License. See the [LICENSE](LICENSE) file for details.

The Svix software itself is licensed separately. Please refer to the [Svix repository](https://github.com/svix/svix-webhooks) for licensing information.

## Support

For issues and questions:

- **Documentation**: Check the [Svix documentation](https://docs.svix.com/)
- **GitHub Issues**: Report bugs in the [GitHub repository](https://github.com/svix/svix-webhooks/issues)
- **Community**: Join the [Svix Slack community](https://www.svix.com/slack/)
- **Support**: Contact Svix support at [email protected]

37 changes: 37 additions & 0 deletions self-hosting/helm/templates/NOTES.txt
Original file line number Diff line number Diff line change
@@ -0,0 +1,37 @@
1. Get the application URL by running these commands:
{{- if contains "NodePort" .Values.backend.service.type }}
export NODE_PORT=$(kubectl get --namespace {{ .Release.Namespace }} -o jsonpath="{.spec.ports[0].nodePort}" services {{ include "svix.fullname" . }}-{{ .Values.backend.name }})
export NODE_IP=$(kubectl get nodes --namespace {{ .Release.Namespace }} -o jsonpath="{.items[0].status.addresses[0].address}")
echo http://$NODE_IP:$NODE_PORT
{{- else if contains "LoadBalancer" .Values.backend.service.type }}
NOTE: It may take a few minutes for the LoadBalancer IP to be available.
You can watch the status of by running 'kubectl get --namespace {{ .Release.Namespace }} svc -w {{ include "svix.fullname" . }}-{{ .Values.backend.name }}'
export SERVICE_IP=$(kubectl get svc --namespace {{ .Release.Namespace }} {{ include "svix.fullname" . }}-{{ .Values.backend.name }} --template "{{"{{ range (index .status.loadBalancer.ingress 0) }}{{.}}{{ end }}"}}")
echo http://$SERVICE_IP:{{ .Values.backend.service.port | default 8071 }}
{{- else if contains "ClusterIP" .Values.backend.service.type }}
kubectl port-forward --namespace {{ .Release.Namespace }} svc/{{ include "svix.fullname" . }}-{{ .Values.backend.name }} {{ .Values.backend.service.port | default 8071 }}:{{ .Values.backend.service.port | default 8071 }}
echo "Visit http://127.0.0.1:{{ .Values.backend.service.port | default 8071 }} to use your application"
{{- end }}

2. Get the Svix API token:
kubectl get secret --namespace {{ .Release.Namespace }} {{ include "svix.fullname" . }}-jwt-secret -o jsonpath="{.data.jwt-secret}" | base64 -d

3. Check the status of your deployment:
kubectl get pods --namespace {{ .Release.Namespace }} -l app.kubernetes.io/component=backend

4. View the logs:
kubectl logs --namespace {{ .Release.Namespace }} -l app.kubernetes.io/component=backend

5. Access the database:
kubectl exec --namespace {{ .Release.Namespace }} -it deployment/{{ include "svix.fullname" . }}-{{ .Values.postgres.name }} -- psql -U postgres

6. Access Redis:
kubectl exec --namespace {{ .Release.Namespace }} -it deployment/{{ include "svix.fullname" . }}-{{ .Values.redis.name }} -- redis-cli

7. PostgreSQL is running on:
kubectl get svc --namespace {{ .Release.Namespace }} {{ include "svix.fullname" . }}-{{ .Values.postgres.name }}

8. Redis is running on:
kubectl get svc --namespace {{ .Release.Namespace }} {{ include "svix.fullname" . }}-{{ .Values.redis.name }}

For more information, visit: https://docs.svix.com/
51 changes: 51 additions & 0 deletions self-hosting/helm/templates/_helpers.tpl
Original file line number Diff line number Diff line change
@@ -0,0 +1,51 @@
{{/*
Expand the name of the chart.
*/}}
{{- define "svix.name" -}}
{{- default .Chart.Name .Values.nameOverride | trunc 63 | trimSuffix "-" }}
{{- end }}

{{/*
Create a default fully qualified app name.
We truncate at 63 chars because some Kubernetes name fields are limited to this (by the DNS naming spec).
If release name contains chart name it will be used as a full name.
*/}}
{{- define "svix.fullname" -}}
{{- if .Values.fullnameOverride }}
{{- .Values.fullnameOverride | trunc 63 | trimSuffix "-" }}
{{- else }}
{{- $name := default .Chart.Name .Values.nameOverride }}
{{- if contains $name .Release.Name }}
{{- .Release.Name | trunc 63 | trimSuffix "-" }}
{{- else }}
{{- printf "%s-%s" .Release.Name $name | trunc 63 | trimSuffix "-" }}
{{- end }}
{{- end }}
{{- end }}

{{/*
Create chart name and version as used by the chart label.
*/}}
{{- define "svix.chart" -}}
{{- printf "%s-%s" .Chart.Name .Chart.Version | replace "+" "_" | trunc 63 | trimSuffix "-" }}
{{- end }}

{{/*
Common labels
*/}}
{{- define "svix.labels" -}}
helm.sh/chart: {{ include "svix.chart" . }}
{{ include "svix.selectorLabels" . }}
{{- if .Chart.AppVersion }}
app.kubernetes.io/version: {{ .Chart.AppVersion | quote }}
{{- end }}
app.kubernetes.io/managed-by: {{ .Release.Service }}
{{- end }}

{{/*
Selector labels
*/}}
{{- define "svix.selectorLabels" -}}
app.kubernetes.io/name: {{ include "svix.name" . }}
app.kubernetes.io/instance: {{ .Release.Name }}
{{- end }}
Loading