> ## Documentation Index
> Fetch the complete documentation index at: https://www.activepieces.com/docs/llms.txt
> Use this file to discover all available pages before exploring further.

# Kubernetes Installation

> Deploy Activepieces on Kubernetes using the official Helm chart

This guide walks you through deploying Activepieces on Kubernetes using the official Helm chart.

## Prerequisites

* Kubernetes cluster (v1.19+)
* Helm 3.x installed
* kubectl configured to access your cluster

When `helm install` or `helm upgrade` talks to a cluster without [Argo Rollouts](https://argoproj.github.io/rollouts/), the chart deploys a `StatefulSet`; otherwise it deploys an Argo `Rollout`. A release that already runs as a `Rollout` stays one. Rendering without a cluster (`helm template`, Kustomize) produces a `Rollout`, so set `workloadType: statefulset` there, or pass the cluster's API versions as Argo CD does. The StatefulSet volume uses the cluster's default StorageClass unless you set `persistence.storageClassName`. On a cluster without a default class (`kubectl get storageclass` shows none marked `(default)`), set it, or the pod stays `Pending`. Choose it before the first install: a StatefulSet's volume class cannot change afterwards.

## Database and Redis

The chart reads PostgreSQL and Redis settings from the secrets listed under `activepiecesEnvVariables` in `values.yaml`. Create them before installing:

Put the settings in env files, so passwords stay out of your shell history and process list. Run `umask 077` first so only you can read them:

```bash title="db.env" theme={null}
AP_POSTGRES_HOST=your-postgres-host.example.com
AP_POSTGRES_PORT=5432
AP_POSTGRES_DATABASE=activepieces
AP_POSTGRES_USERNAME=postgres
AP_POSTGRES_PASSWORD=your-password
```

```bash title="redis.env" theme={null}
AP_REDIS_HOST=your-redis-host.example.com
AP_REDIS_PORT=6379
AP_REDIS_PASSWORD=your-password
```

```bash theme={null}
kubectl create secret generic activepieces-db-secrets --from-env-file=db.env
kubectl create secret generic activepieces-redis-secrets --from-env-file=redis.env
rm db.env redis.env
```

To run PostgreSQL and Redis inside the cluster instead, set `postgresql.enabled: true` / `redis.enabled: true`. The hosts are `<release>-postgresql` and `<release>-redis-master`.

`AP_JWT_SECRET` and `AP_ENCRYPTION_KEY` are generated on first install. To bring your own, put them in `activepieces-auth-secrets`; that secret takes precedence.

## Quick Start

### 1. Clone the Repository

```bash theme={null}
git clone https://github.com/activepieces/activepieces.git
cd activepieces
```

### 2. Install Dependencies

```bash theme={null}
helm repo add mittwald https://helm.mittwald.de
helm repo add bitnami https://charts.bitnami.com/bitnami
helm dependency build deploy/activepieces-helm
```

### 3. Create a Values File

Create a `my-values.yaml` file with your configuration. You can use the [example values file](https://github.com/activepieces/activepieces/blob/main/deploy/activepieces-helm/values.yaml) as a reference.
The Helm chart has sensible defaults for required values while leaving the optional ones empty, but you should customize these core values for production.

Set the core settings in the `activepieces-config-secrets` secret the chart already reads. `AP_EDITION` and `AP_EXECUTION_MODE` let you activate a [license key](https://www.activepieces.com/docs/install/configure-operate/enterprise-license.md) later:

```bash theme={null}
kubectl create secret generic activepieces-config-secrets \
  --from-literal=AP_FRONTEND_URL=https://activepieces.yourdomain.com \
  --from-literal=AP_EDITION=ee \
  --from-literal=AP_EXECUTION_MODE=SANDBOX_CODE_ONLY
```

`AP_FRONTEND_URL` is required, and it must also be reachable from inside the pod: the worker downloads pieces through it.

```yaml theme={null}
persistence:
  storageClassName: "your-storage-class"  # see `kubectl get storageclass`
```

> [!WARNING]
>
> Set `AP_EDITION` and `AP_EXECUTION_MODE` together: `AP_EDITION=ee` with the default execution mode is rejected at startup and the app will not boot.
>
> Set each variable in **one place only**. A name that is both in `activepiecesConfig` and in an `activepiecesEnvVariables` list is rendered twice, which Helm 4 rejects (`duplicate entries for key`).

### 4. Install Activepieces

```bash theme={null}
helm install activepieces deploy/activepieces-helm -f my-values.yaml
```

### 5. Verify Installation

```bash theme={null}
# Check deployment status
kubectl get pods
kubectl get services

```

## Production Checklist

* [ ] Set `AP_FRONTEND_URL` to your actual domain
* [ ] Set strong passwords for PostgreSQL and Redis (or keep auto-generated)
* [ ] Configure proper ingress with TLS
* [ ] Set appropriate resource limits
* [ ] Configure persistent storage
* [ ] Choose appropriate [execution mode](https://www.activepieces.com/docs/install/architecture/sandboxing.md) for your security requirements
* [ ] Review [environment variables](https://www.activepieces.com/docs/install/reference/environment-variables.md) for advanced configuration
* [ ] Consider using a [separate workers](https://www.activepieces.com/docs/install/configure-operate/separate-workers.md) setup for better availability and security

## Upgrading

```bash theme={null}
# Update dependencies
helm dependency build deploy/activepieces-helm

# Upgrade release
helm upgrade activepieces deploy/activepieces-helm -f my-values.yaml

# Check upgrade status (StatefulSet)
kubectl rollout status statefulset/activepieces
# Check upgrade status (Argo Rollout)
kubectl wait --for=jsonpath='{.status.phase}'=Healthy rollout/activepieces --timeout=10m
```

With Helm 4 and `workloadType: rollout`, add `--force-conflicts` to `helm upgrade`. Argo Rollouts owns the Service selectors, and Helm 4's server-side apply stops on that conflict otherwise.

The bundled secret generator creates cluster-wide RBAC named after the release, so give each release in a cluster its own name. A second release can also set `kubernetes-secret-generator.enabled: false`, because the first release's generator already serves every namespace.

## Migrating from chart 0.3.x

Chart 0.4.0 replaced the `activepieces:` block and keys such as `postgresql.host` and `redis.host` with the secrets listed under `activepiecesEnvVariables`. `helm install` and `helm upgrade` print a warning that names every old key they ignore. Run these steps before upgrading, with `RELEASE` set to your release name.

**1. Keep your database.** Chart 0.3.x ran PostgreSQL and Redis inside the cluster by default. If you used them, keep them enabled in your values:

```yaml theme={null}
postgresql:
  enabled: true
  image:
    repository: bitnamilegacy/postgresql
redis:
  enabled: true
  image:
    repository: bitnamilegacy/redis
```

Then copy the database and Redis settings your running app uses today, so custom names, users and hosts carry over. This works the same for bundled and external databases:

```bash theme={null}
umask 077
FULLNAME=$(kubectl get secret -l app.kubernetes.io/instance="$RELEASE" -o name | sed -n 's|^secret/\(.*\)-jwt-secret$|\1|p')
kubectl exec "deploy/$FULLNAME" -- printenv > app.env
grep '^AP_POSTGRES_' app.env | grep -v '^AP_POSTGRES_SSL_CA=' > db.env
grep '^AP_REDIS_' app.env | grep -v '^AP_REDIS_TYPE=DEFAULT$' > redis.env
kubectl create secret generic activepieces-db-secrets --from-env-file=db.env
kubectl create secret generic activepieces-redis-secrets --from-env-file=redis.env
if kubectl exec "deploy/$FULLNAME" -- printenv AP_POSTGRES_SSL_CA > ca.pem; then
  kubectl patch secret activepieces-db-secrets -p "{\"data\":{\"AP_POSTGRES_SSL_CA\":\"$(base64 < ca.pem | tr -d '\n')\"}}"
fi
rm app.env db.env redis.env ca.pem
```

If a variable in those files is not listed under `activepiecesEnvVariables` (for example `AP_POSTGRES_URL` or `AP_REDIS_SENTINEL_HOSTS`), add it to that list in your values.

**2. Move your settings.** Each `activepieces.<name>` value becomes an `AP_*` variable in the `activepieces-config-secrets` secret, for example `frontendUrl` → `AP_FRONTEND_URL`, `edition` → `AP_EDITION` and `executionMode` → `AP_EXECUTION_MODE`. Set `persistence.storageClassName` to a StorageClass your cluster has (`kubectl get storageclass`); chart 0.3.x used the cluster default, and `persistence.storageClass` is no longer read.

```bash theme={null}
kubectl create secret generic activepieces-config-secrets \
  --from-literal=AP_FRONTEND_URL=https://activepieces.yourdomain.com
```

**3. Keep your keys.** Your encryption key and JWT secret are carried over automatically. If you deploy with `helm template`, Argo CD or Kustomize, the chart cannot see them, so copy the ones your running app uses into `activepieces-auth-secrets` first:

```bash theme={null}
umask 077
FULLNAME=$(kubectl get secret -l app.kubernetes.io/instance="$RELEASE" -o name | sed -n 's|^secret/\(.*\)-jwt-secret$|\1|p')
kubectl exec "deploy/$FULLNAME" -- printenv | grep -E '^AP_(ENCRYPTION_KEY|JWT_SECRET)=' > auth.env
kubectl create secret generic activepieces-auth-secrets --from-env-file=auth.env
rm auth.env
```

**4. Upgrade.** Pin `image.tag` to the version you run today, upgrade the chart, then move to a newer image in a separate step. The app now runs as a StatefulSet (or an Argo `Rollout`) instead of a Deployment, and its piece cache volume is recreated.

If you already upgraded with the old values and the new pod is stuck in `Pending` (for example `storageclass "local-path" not found`), Kubernetes will not let the chart change the volume. Delete the StatefulSet and its empty cache volume, then upgrade again. The pod never started, so nothing is lost:

```bash theme={null}
FULLNAME=$(kubectl get secret -l app.kubernetes.io/instance="$RELEASE" -o name | sed -n 's|^secret/\(.*\)-jwt-secret$|\1|p')
kubectl delete statefulset "$FULLNAME"
kubectl delete pvc "cache-$FULLNAME-0"
```

## OpenShift

The base chart runs as root on port 80, which OpenShift's default `restricted-v2` SCC rejects with `listen EACCES :::80`. Add the OpenShift overlay on top of your own values:

```bash theme={null}
helm install activepieces deploy/activepieces-helm \
  -f deploy/activepieces-helm/values.yaml \
  -f deploy/activepieces-helm/values-openshift.yaml \
  -f my-values.yaml
```

The overlay runs the pod as non-root on port 8080, drops all capabilities and uses the cluster's default StorageClass. It sets no user or group ID, so OpenShift assigns both from the project's range.

Set `AP_EXECUTION_MODE` to `SANDBOX_CODE_ONLY` in the `activepieces-config-secrets` secret, as in step 3. `SANDBOX_PROCESS` and `SANDBOX_CODE_AND_PROCESS` need `CAP_SYS_ADMIN`, which `restricted-v2` never grants. In `SANDBOX_CODE_ONLY`, code steps that import npm packages fail; see [Sandboxing](https://www.activepieces.com/docs/install/architecture/sandboxing.md).

The bundled PostgreSQL and Redis subcharts hardcode user ID 1001, which `restricted-v2` rejects. The overlay turns off their security contexts and OpenShift assigns the IDs instead, so `postgresql.enabled` and `redis.enabled` need no extra settings.

The chart does not create an OpenShift `Route`. Create one pointing at the `activepieces` service on port 80, or use the `Ingress` under `ingress.*`.

To use the overlay on another cluster that enforces the Kubernetes `restricted` Pod Security profile, also set a non-root `runAsUser` and `fsGroup` (for example `1001`) under `podSecurityContext`: the image runs as root, and `runAsNonRoot` refuses to start it without one. Use external PostgreSQL and Redis there: with the overlay, the bundled database pods have no security context, which that profile rejects.

## Troubleshooting

### Common Issues

1. **Pod won't start**: Check logs with `kubectl logs -l app.kubernetes.io/instance=activepieces,app.kubernetes.io/name=activepieces`
2. **Database connection**: Verify PostgreSQL credentials and connectivity
3. **Frontend URL**: Ensure `AP_FRONTEND_URL` is accessible from external sources
4. **Webhooks not working**: Check ingress configuration and DNS resolution

### Useful Commands

```bash theme={null}
# View logs
kubectl logs -l app.kubernetes.io/instance=activepieces,app.kubernetes.io/name=activepieces -f

# Port forward for testing
kubectl port-forward svc/activepieces 4200:80 --namespace default

# Get all resources
kubectl get all --namespace default
```

## Environment Variables

For a complete list of configuration options, see the [Environment Variables](https://www.activepieces.com/docs/install/reference/environment-variables.md) documentation. Most environment variables can be configured through the Helm values file, either as plain values under `activepiecesConfig` or injected from your own secrets under `activepiecesEnvVariables`.

## Execution Modes

Understanding execution modes is crucial for security and performance. See the [Sandboxing](https://www.activepieces.com/docs/install/architecture/sandboxing.md) guide to choose the right mode for your deployment.

## Uninstalling

```bash theme={null}
helm uninstall activepieces

# Clean up persistent volumes (optional)
kubectl delete pvc -l app.kubernetes.io/instance=activepieces
```


This documentation is built and hosted on [Mintlify](https://mintlify.com), a developer documentation platform.