--- title: Deploy on Kubernetes description: Deploy OpenPanel on Kubernetes using Helm --- import { Step, Steps } from 'fumadocs-ui/components/steps'; import { Callout } from 'fumadocs-ui/components/callout'; OpenPanel can be deployed on Kubernetes using the community-maintained Helm chart. This allows you to run OpenPanel in a scalable, production-ready Kubernetes environment. The Helm chart is maintained by the community and available on [Artifact Hub](https://artifacthub.io/packages/helm/openpanel/openpanel). ## Prerequisites - Kubernetes 1.19+ - Helm 3.0+ - `kubectl` configured to access your cluster - At least 2GB RAM per node (4GB+ recommended) - Persistent volume support (if using self-hosted databases) ## Quick Start ### Add the Helm Repository Add the OpenPanel Helm repository: ```bash helm repo add openpanel https://yashGoyal40.github.io/openpanel helm repo update ``` ### Download Default Values Download the default values file to customize your configuration: ```bash helm show values openpanel/openpanel > my-values.yaml ``` ⚠️ **IMPORTANT**: Before installing, you **MUST** configure the required values in `values.yaml`. The chart includes placeholder values (marked with `<>`) that will cause the installation to fail if not properly configured. ### Configure Required Values Edit `my-values.yaml` and configure the following **required** values: 1. **Ingress Configuration**: ```yaml ingress: enabled: true type: standard # or "httpproxy" for Contour fqdn: your-domain.com # Replace with your actual domain standard: tlsSecretName: openpanel-tls ``` 2. **Application URLs**: ```yaml config: apiUrl: "https://your-domain.com/api" dashboardUrl: "https://your-domain.com" googleRedirectUri: "https://your-domain.com/api/oauth/google/callback" ``` 3. **Cookie Secret** (generate with `openssl rand -base64 32`): ```yaml secrets: cookieSecret: "YOUR_GENERATED_SECRET_HERE" ``` 4. **PostgreSQL Configuration** (choose one): - **Option A**: External PostgreSQL (recommended for production) ```yaml postgresql: enabled: false externalPostgresql: host: "postgres.example.com" port: 5432 user: "openpanel" password: "your-secure-password" database: "openpanel" schema: public ``` - **Option B**: Self-hosted PostgreSQL ```yaml postgresql: enabled: true user: postgres password: "your-secure-password" database: postgres persistence: size: 20Gi ``` ### Install OpenPanel Install OpenPanel with your configured values: ```bash helm install my-openpanel openpanel/openpanel \ --version 0.1.0 \ --namespace openpanel \ --create-namespace \ -f my-values.yaml ``` Or override specific values directly: ```bash helm install my-openpanel openpanel/openpanel \ --version 0.1.0 \ --namespace openpanel \ --create-namespace \ --set ingress.fqdn=your-domain.com \ --set config.apiUrl=https://your-domain.com/api \ --set secrets.cookieSecret=$(openssl rand -base64 32) ``` ### Verify Installation Check that all pods are running: ```bash kubectl get pods -n openpanel ``` You should see pods for: - API server (`op-api`) - Dashboard (`op-dashboard`) - Worker (`op-worker`) - PostgreSQL (if using self-hosted) - Redis (if using self-hosted) - ClickHouse (if using self-hosted) Check the status: ```bash kubectl get all -n openpanel ``` ### Access Your Dashboard Once all pods are running, access OpenPanel at your configured domain. The ingress will route traffic to the dashboard service. If you need to test locally, you can port-forward: ```bash kubectl port-forward svc/op-dashboard 3000:80 -n openpanel ``` Then access OpenPanel at `http://localhost:3000`. ## Configuration ### Required Configuration The following values **MUST** be configured before installation: | Configuration | Required | Placeholder | Description | |--------------|----------|-------------|-------------| | `ingress.fqdn` | ✅ Yes | `` | Your domain name | | `ingress.*.tlsSecretName` | ✅ Yes | `` | TLS certificate secret name | | `config.apiUrl` | ✅ Yes | `` | Full API URL | | `config.dashboardUrl` | ✅ Yes | `` | Full Dashboard URL | | `config.googleRedirectUri` | ✅ Yes | `` | OAuth callback URL | | `secrets.cookieSecret` | ✅ Yes | `CHANGE_ME_...` | Session encryption key | | `externalPostgresql.*` | ⚠️ If external | `` | PostgreSQL connection details | ### Complete Example Configuration Here's a minimal example configuration file (`my-values.yaml`) with all required values: ```yaml title="my-values.yaml" # Ingress Configuration ingress: enabled: true type: standard # or "httpproxy" for Contour fqdn: analytics.example.com standard: tlsSecretName: openpanel-tls # Application URLs config: apiUrl: "https://analytics.example.com/api" dashboardUrl: "https://analytics.example.com" googleRedirectUri: "https://analytics.example.com/api/oauth/google/callback" # Cookie Secret (generate with: openssl rand -base64 32) secrets: cookieSecret: "YOUR_GENERATED_SECRET_HERE" # PostgreSQL - Using External Database postgresql: enabled: false externalPostgresql: host: "postgres.example.com" port: 5432 user: "openpanel" password: "your-secure-password" database: "openpanel" schema: public ``` ### Optional Configuration The Helm chart maps environment variables to Helm values. For a complete reference of all available environment variables and their descriptions, see the [Environment Variables documentation](/docs/self-hosting/environment-variables). #### Email Configuration Enable email functionality (password resets, invitations, etc.): ```yaml secrets: resendApiKey: "re_xxxxxxxxxxxxx" # Your Resend API key emailSender: "noreply@your-domain.com" # Verified sender email ``` Get your Resend API key from [resend.com](https://resend.com). Make sure to verify your sender email domain. #### AI Features Enable AI-powered features: ```yaml config: aiModel: "gpt-4o-mini" # Options: gpt-4o, gpt-4o-mini, claude-3-5 secrets: openaiApiKey: "sk-xxxxxxxxxxxxx" # For OpenAI models anthropicApiKey: "" # For Claude models (leave empty if not using) geminiApiKey: "" # For Gemini models (leave empty if not using) ``` You only need to configure the API key for the model you choose. Leave other API keys as empty strings (`""`) if not using them. #### Google OAuth Enable Google OAuth login: ```yaml secrets: googleClientId: "xxxxx.apps.googleusercontent.com" googleClientSecret: "GOCSPX-xxxxxxxxxxxxx" ``` Set up Google OAuth in [Google Cloud Console](https://console.cloud.google.com). Add authorized redirect URI: `https://your-domain.com/api/oauth/google/callback` #### Redis Configuration Redis is enabled by default and deployed within Kubernetes. To use an external Redis instance: ```yaml redis: enabled: false externalRedis: host: "redis.example.com" port: 6379 ``` #### ClickHouse Configuration ClickHouse is enabled by default and deployed within Kubernetes. To use an external ClickHouse instance: ```yaml clickhouse: enabled: false externalClickhouse: host: "clickhouse.example.com" port: 8123 database: openpanel ``` #### Application Components Enable/disable individual components: ```yaml api: enabled: true replicas: 1 dashboard: enabled: true replicas: 1 worker: enabled: true replicas: 1 ``` #### Resource Limits Adjust resource requests and limits: ```yaml api: resources: requests: memory: "512Mi" cpu: "250m" limits: memory: "2Gi" cpu: "2000m" ``` ## Updating OpenPanel To upgrade to a newer version: ```bash helm repo update helm upgrade my-openpanel openpanel/openpanel \ --version \ --namespace openpanel \ -f my-values.yaml ``` Replace `` with the desired version number (e.g., `0.1.1`). ## Managing Your Deployment ### View Logs View logs from specific deployments: ```bash # API logs kubectl logs -f deployment/op-api -n openpanel # Dashboard logs kubectl logs -f deployment/op-dashboard -n openpanel # Worker logs kubectl logs -f deployment/op-worker -n openpanel ``` ### Restart Services Restart a specific deployment: ```bash kubectl rollout restart deployment/op-api -n openpanel kubectl rollout restart deployment/op-dashboard -n openpanel kubectl rollout restart deployment/op-worker -n openpanel ``` ### Scale Services Scale services on the fly: ```bash kubectl scale deployment/op-worker --replicas=3 -n openpanel ``` Or update your values file and upgrade: ```yaml worker: replicas: 3 ``` ```bash helm upgrade my-openpanel openpanel/openpanel -f my-values.yaml -n openpanel ``` ### Check Services View all services: ```bash kubectl get svc -n openpanel ``` ### Check ConfigMap and Secrets Verify configuration: ```bash kubectl get configmap openpanel-config -n openpanel -o yaml kubectl get secret openpanel-secrets -n openpanel -o yaml ``` ## Ingress Configuration ### Standard Ingress (NGINX/Traefik) ```yaml ingress: enabled: true type: standard fqdn: openpanel.your-domain.com standard: tlsSecretName: openpanel-tls annotations: cert-manager.io/cluster-issuer: "letsencrypt-prod" nginx.ingress.kubernetes.io/ssl-redirect: "true" ``` ### HTTPProxy (Contour) ```yaml ingress: enabled: true type: httpproxy fqdn: openpanel.your-domain.com httpproxy: tlsSecretName: openpanel-tls ``` ## Troubleshooting ### Pods Not Starting 1. Check pod status: ```bash kubectl describe pod -n openpanel ``` 2. Check events: ```bash kubectl get events --sort-by='.lastTimestamp' -n openpanel ``` 3. Check logs: ```bash kubectl logs -n openpanel ``` ### Database Connection Issues 1. Verify database pods are running (if using self-hosted): ```bash kubectl get pods -n openpanel | grep postgres ``` 2. Check database service: ```bash kubectl get svc -n openpanel | grep postgres ``` 3. Test database connection: ```bash kubectl exec -it deployment/op-api -n openpanel -- env | grep DATABASE_URL ``` ### Configuration Issues If pods are failing due to configuration: 1. Verify all required values are set: ```bash helm get values my-openpanel -n openpanel ``` 2. Check for placeholder values: ```bash helm get values my-openpanel -n openpanel | grep "<" ``` 3. Ensure secrets are properly set: ```bash kubectl get secret openpanel-secrets -n openpanel -o yaml ``` ### Ingress Not Working 1. Check ingress status: ```bash kubectl get ingress -n openpanel kubectl describe ingress -n openpanel ``` 2. Verify ingress controller is running: ```bash kubectl get pods -n ingress-nginx # For NGINX # or kubectl get pods -n projectcontour # For Contour ``` 3. Check DNS configuration ## Backup and Restore ### Backup PostgreSQL If using self-hosted PostgreSQL: ```bash kubectl exec -it -n openpanel -- \ pg_dump -U postgres openpanel > backup.sql ``` Or use a Kubernetes CronJob for automated backups. ### Restore PostgreSQL Restore from backup: ```bash kubectl exec -i -n openpanel -- \ psql -U postgres openpanel < backup.sql ``` ## Uninstalling To uninstall OpenPanel: ```bash helm uninstall my-openpanel --namespace openpanel ``` ⚠️ **Warning**: This will delete all resources including persistent volumes. Make sure to backup your data before uninstalling! To keep persistent volumes: ```bash # Delete the release but keep PVCs helm uninstall my-openpanel --namespace openpanel # Manually delete PVCs if needed kubectl delete pvc -l app.kubernetes.io/name=openpanel -n openpanel ``` ## Next Steps - [Configure email settings](/docs/self-hosting/self-hosting#e-mail) for password resets and invitations - [Set up AI integration](/docs/self-hosting/self-hosting#ai-integration) for the analytics assistant - [Configure SDK](/docs/self-hosting/self-hosting#always-use-correct-api-url) to track events from your applications ## Additional Resources - [Helm Chart on Artifact Hub](https://artifacthub.io/packages/helm/openpanel/openpanel) - [Kubernetes Documentation](https://kubernetes.io/docs/) - [Helm Documentation](https://helm.sh/docs/)