Overview
ToolJet is an open-source, low-code platform for building internal tools: a visual app builder with 50+ datasource connectors, workflows, and the built-in ToolJet Database. This template deploys the ToolJet server — UI and API on port3000, with PostgREST and a fallback Redis bundled inside the image — backed by a bundled PostgreSQL that holds both the application database and the ToolJet Database. The default is a single replica; tooljet.replicas scales out once the optional Redis is enabled.
What Gets Created
Prerequisites
ToolJet reads its three root-of-trust keys from a dictionary secret that you create before installing. The key values never pass through Helm values.Create the key secret
secrets.name to this name. Secrets are org-level, so no GVC flag is involved.Back the keys up outside Control Plane
SECRET_KEY_BASE and LOCKBOX_MASTER_KEY are write-once: rotating LOCKBOX_MASTER_KEY makes every datasource credential ToolJet has stored undecryptable. Keep a copy of all three values somewhere safe.- Authenticated SMTP — a dictionary secret holding
SMTP_USERNAMEandSMTP_PASSWORD, and a decision made before installing, because ToolJet only picks up mail settings on its first boot. See Email. - Scheduled database backups — a bucket and cloud account for the bundled PostgreSQL. See Backing Up.
Installation
Once your key secret exists, install from the marketplace registry, pointingsecrets.name at it and replacing the bundled database password:
postgres.config.credentialsSecretName to a name no other release uses — secret names are org-wide. If you want email invitations, add the smtp.* values to this first install as well (see Email).
Other ways to install and manage the template:
UI
CLI
Terraform
Pulumi
Configuration
ToolJet Server
tooljet.host only when you serve ToolJet on a custom domain; leave it empty and ToolJet derives its public URL from the workload’s canonical endpoint.
Key Secret
smtp.auth.secretName to its name. The ToolJet identity is granted reveal on exactly that secret.
Access
publicAccess.enabled: false there is no public endpoint; external requests are refused and only workloads allowed by internalAccess reach ToolJet (plus your own machine through a tunnel — see Connecting).
Bundled PostgreSQL
postgres.credentials.password seeds the database on first boot and is not updated by later value edits — set it before you install. It is bundled plumbing, so the chart creates the credentials secret for you; it is not a prerequisite. Scheduled backups of this database are configured under Backing Up.
Bundled Redis
redis.enabled: true deploys the redis template and points ToolJet at it; it is required for more than one ToolJet replica (see Scaling and Availability). With redis.redis.auth.password.enabled: true the password is stored in the chart-created RELEASE_NAME-redis-auth-password secret, which the ToolJet identity is granted reveal on.
Connecting
publicAccess.enabled: false there is no public endpoint; reach the UI from your machine through a tunnel instead and open http://localhost:3000:
First Run
ToolJet ships no default account. The first person to open the endpoint completes the Super Admin onboarding and creates the initial workspace — and with the defaultpublicAccess.enabled: true that form is reachable by anyone who finds the endpoint, so claim it as soon as the workload reports ready.
Wait for the ToolJet workload to report ready
Open the endpoint and complete the Super Admin form
Invite your team
Operations
Backing Up
The bundled PostgreSQL is the postgres template, so its scheduled backup is available here under thepostgres key — nothing extra to install. It is off by default. Enabling it adds the cron workload RELEASE_NAME-postgres-backup, which uploads a gzipped SQL dump of the whole instance (all three databases) to your bucket under the configured prefix.
gcp / minio value blocks are on the postgres template page under Backup Prerequisites; use the same keys here, nested under postgres.backup.
The dump does not cover your three keys — they live in the secret you created, so back that up separately. The PostgreSQL volume set RELEASE_NAME-pg-vs also takes a final volume set snapshot when the release is uninstalled, retained for 7 days.
Restoring a Backup
Each backup is a gzipped plain-SQL dump of the whole PostgreSQL instance. Restoring means replaying that SQL into the bundled PostgreSQL, following the restore procedure on the postgres template page againstRELEASE_NAME-postgres.GVC_NAME.cpln.local with the credentials from your postgres.config.credentialsSecretName secret. From a client without network access to the GVC, the one transport that carries a dump into the container intact is cpln workload exec with --stdin and a base64 wrapper on both ends — raw binary piped through exec is corrupted:
CREATE ROLE and CREATE DATABASE statements, so a straight replay collides with the databases ToolJet already created and migrated on first boot; and no ToolJet replica may be connected while you drop and recreate those databases before the replay.
Upgrading from 1.0.0
Version 1.1.0 adopted thepostgres 3.4.1 template, which stopped taking database credentials as values. ToolJet absorbed that change rather than passing it on — the chart now creates the credentials secret itself — so there is no new prerequisite, only a rename of three keys:
config.username was REMOVED in postgres 3.4.0 — which tells you to create a dictionary secret yourself; ignore that advice here, this template creates it. Then continue with the section below.
Upgrading from 1.1.0
Version 1.2.0 changes no values. The ToolJet container now starts through a chart-provided script that waits until PostgreSQL actually accepts connections before running the image’s own entrypoint, which removes a failed first attempt that earlier versions logged on a fresh install. Upgrade in place.helm upgrade after an install can restart the bundled PostgreSQL even when nothing about it changed, which interrupts ToolJet briefly; later upgrades of the same release do not.Scaling and Availability
tooljet.replicas sets how many ToolJet replicas run. With more than one replica, all replicas must share one Redis for the job queue and for multiplayer coordination in the app editor, so redis.enabled must be true — the single-instance Redis bundled in the image cannot be shared. Sessions are valid on every replica, so no sticky routing is needed.
tooljet.replicas of 2 or more while redis.enabled is false. The database tier is a single PostgreSQL instance by design; the Redis tier is pinned to one data node and one monitor-only Sentinel because ToolJet’s Redis client is not Sentinel-aware.
Troubleshooting
Deployment never becomes ready and the logs are empty
Deployment never becomes ready and the logs are empty
cpln helm install reported success, cpln logs returns nothing, and cpln workload get-deployments RELEASE_NAME-tooljet --gvc GVC_NAME -o yaml shows The secret KEYS_SECRET_NAME no longer exists. Workload updates are paused until the secret is added or the reference to the secret removed. under status.versions[].message.Cause: The key secret named by secrets.name does not exist. The same applies to an smtp.auth.secretName that was set but never created.Fix: Create it (see Prerequisites). The deployment recovers on its own once the secret exists; cpln workload force-redeployment RELEASE_NAME-tooljet --gvc GVC_NAME skips the wait.Container restarts with exit code 137 and never finishes migrating
Container restarts with exit code 137 and never finishes migrating
cpln workload get-deployments RELEASE_NAME-tooljet --gvc GVC_NAME -o yaml shows an exit code of 137, and the logs end partway through the schema migrations.Cause: tooljet.resources.maxMemory was set below 4Gi. The image bakes a 4096 MB Node heap and the first-boot migrations exceed smaller limits, so the container is killed for running out of memory.Fix: Restore tooljet.resources.maxMemory: 4Gi and upgrade. The migrations complete on the next boot.Render fails because replicas above 1 require Redis
Render fails because replicas above 1 require Redis
tooljet: tooljet.replicas >= 2 requires redis.enabled=true — multiple replicas must share an external Redis for job-queue and multiplayer coordination (the in-image Redis is single-instance-only).Cause: tooljet.replicas is 2 or more while redis.enabled is false.Fix: Set redis.enabled: true (see Scaling and Availability), or keep a single replica.Render fails because the Redis replica counts must stay 1
Render fails because the Redis replica counts must stay 1
tooljet: redis.redis.replicas must stay 1 — ToolJet is not Sentinel-aware ... or tooljet: redis.sentinel.replicas must stay 1 — with a single data node there is no failover target ....Cause: redis.redis.replicas or redis.sentinel.replicas was changed from 1.Fix: Set both back to 1. ToolJet connects to the Redis service name directly, so extra data nodes would receive writes they cannot accept.Second install refused as managed by a different release
Second install refused as managed by a different release
cannot be updated because it is being managed by a different release and creates nothing.Cause: Both releases use the same postgres.config.credentialsSecretName. Secret names are org-wide, and the first release owns that one. Nothing is shared, overwritten, or deleted.Fix: Set postgres.config.credentialsSecretName to a distinct name for the second release and install again.SMTP was enabled through an upgrade but no email is sent
SMTP was enabled through an upgrade but no email is sent
smtp.enabled: true was applied with helm upgrade, the SMTP_* variables are on the workload, yet invitations and password resets send nothing and the instance still reports mail as disabled.Cause: ToolJet seeds its mail settings from the environment during a first-boot migration only. Values added later reach the container but are never applied.Fix: SMTP has to be part of the initial install (see Email). Enabling it on an existing instance through values is not supported by this template.Upgrade from 1.0.0 fails asking you to create a dictionary secret
Upgrade from 1.0.0 fails asking you to create a dictionary secret
config.username was REMOVED in postgres 3.4.0 and advice about a prerequisite dictionary secret.Cause: Your values file still carries postgres.config.username, postgres.config.password, or postgres.config.database.Fix: Rename them to postgres.credentials.* as described in Upgrading from 1.0.0. Do not create a secret yourself — this template creates it.Logs repeat Invalid License Key and the health check reports an invalid license
Logs repeat Invalid License Key and the health check reports an invalid license
Invalid License Key:Parse error, and /api/health reports the license as invalid or expired.Cause: The image is ToolJet’s LTS build, which includes the licensed edition’s code but runs the free tier without a license key. The license check logs this on every pass.Fix: None needed — this is the free tier working as intended. The same applies to npm warn using --force lines from the image’s entrypoint.Important Notes
- Create the key secret before installing —
secrets.namemust name an existing dictionary secret withSECRET_KEY_BASE,LOCKBOX_MASTER_KEY, andPGRST_JWT_SECRET. A missing secret wedges the deployment silently. SECRET_KEY_BASEandLOCKBOX_MASTER_KEYare write-once — rotatingLOCKBOX_MASTER_KEYmakes every stored datasource credential undecryptable. Back the keys up outside Control Plane.- Do not lower
tooljet.resources.maxMemorybelow4Gi— the first boot’s migrations run out of memory below it and the workload never becomes ready. - Claim the Super Admin account right after install — the first visitor to complete onboarding owns the instance, and the endpoint is public by default.
- Configure SMTP at the initial install — enabling it through a later upgrade does nothing.
tooljet.replicasof2or more requiresredis.enabled: true, and both the Redis data node and the Sentinel must stay at one replica.- Change
postgres.credentials.passwordbefore installing — it seeds the database on first boot and is not updated by later value edits. - Give each release its own
postgres.config.credentialsSecretName— secret names are org-wide, and a second release on the same name is refused at install. - Uninstalling deletes the PostgreSQL volume set and every app, user, and ToolJet Database table in it; your key secret is yours and survives.
- ToolJet is licensed under the AGPL — the deployed image is the LTS build and runs the free tier without a license key.