c6f11d8adb
## Summary - Migrates `LogicFunctionModule`, `CodeInterpreterModule`, and `CaptchaModule` from the `forRootAsync` + injection token pattern to the `DriverFactoryBase` lazy-loading pattern (matching `EmailModule` and `FileStorageModule`) - Fixes #18724 where `LOGIC_FUNCTION_TYPE` was not respected in worker processes because the driver was created at module boot time before the DB config cache was loaded - Removes `isEnvOnly` from `LOGIC_FUNCTION_TYPE`, `CODE_INTERPRETER_TYPE`, `CAPTCHA_DRIVER`, `IS_MULTIWORKSPACE_ENABLED`, and `FRONTEND_URL` — these can now be safely configured via the database at runtime ## How it works Each migrated module now uses a `DriverFactory` (extending `DriverFactoryBase`) instead of a module-level async factory + Symbol injection token: 1. **Lazy creation**: `getCurrentDriver()` creates the driver on first call, after `DatabaseConfigDriver.onModuleInit()` has loaded the DB cache 2. **Auto-recreation**: If config changes in the DB, the next `getCurrentDriver()` call detects the key mismatch and creates a new driver instance 3. **Unified config**: Both server and worker read from the same database — driver config only needs to be set once ### Files deleted (old pattern) - `logic-function-module.factory.ts`, `logic-function-drivers.module.ts`, `logic-function-driver.constants.ts` - `code-interpreter-module.factory.ts` - `captcha.module-factory.ts`, `captcha-driver.constants.ts` ### Files created (new pattern) - `logic-function-driver.factory.ts` - `code-interpreter-driver.factory.ts` - `captcha-driver.factory.ts` Net: **-150 lines** ## Test plan - [x] `npx nx typecheck twenty-server` passes - [x] `npx nx lint:diff-with-main twenty-server` passes - [ ] Integration tests pass (`npx nx run twenty-server:test:integration:with-db-reset`) - [ ] Verify logic functions execute in workflow runs (the original bug) - [ ] Verify code interpreter works in workflow code steps - [ ] Verify captcha validation works on sign-up (when captcha is configured) Made with [Cursor](https://cursor.com)
Twenty Helm Chart
Deploy Twenty CRM on Kubernetes with server, worker, PostgreSQL, and Redis components.
Features
- Server and worker deployments with full env exposure via
values.yaml. - Internal PostgreSQL (Spilo) and Redis deployments included.
- PVC-based persistence using dynamic storage classes (no static PV manifests).
- Ingress with configurable annotations, hosts, and TLS.
- Database readiness and migrations handled by server/worker init containers by default. – Standard Kubernetes Jobs for DB creation/user and migrations have been removed to simplify installs. Readiness and migrations run in init containers.
Quick Start
See QUICKSTART.md for a simple 2-line install with your domain.
Installing
Prerequisites: Kubernetes 1.21+, Helm 3.8+, default StorageClass
Internal DB + Redis (default):
helm install my-twenty ./packages/twenty-docker/helm/twenty \
--namespace twentycrm --create-namespace
External DB/Redis:
helm install my-twenty ./packages/twenty-docker/helm/twenty \
--namespace twentycrm --create-namespace \
--set db.enabled=false \
--set db.external.host=db.example.com \
--set redisInternal.enabled=false
Key Values
See values.yaml for a comprehensive list.
Notes
- Database URL and Redis URL are composed automatically from chart settings
- Database
twentyand schemacoreare created automatically by server init container - No optional jobs: the chart no longer provides separate Jobs for DB or migrations.
- Access token auto-generated (32 chars) if not provided; reuses existing secret if present
- For production, provide a strong
secrets.tokens.accessTokenvalue via a secure values file; the auto-generated token is a convenience fallback.
- For production, provide a strong
- TLS enabled by default via cert-manager (
acme: true) - Requires default StorageClass for PVC provisioning
Testing
helm lint ./packages/twenty-docker/helm/twenty
helm template my-twenty ./packages/twenty-docker/helm/twenty
helm plugin install https://github.com/quintush/helm-unittest
helm unittest ./packages/twenty-docker/helm/twenty
Storage
Local (default): Uses PVCs for persistence
S3: Set storage.type=s3 and provide credentials using a values file. You can either pass credentials directly or reference an existing Kubernetes Secret.
# values-secrets.yaml (do not commit)
# storage:
# type: s3
# s3:
# bucket: my-bucket
# region: us-east-1
# # Option A: direct values
# accessKeyId: AKIA...
# secretAccessKey: ...
# # Option B: reference a Secret
# # secretName: my-s3-creds
# # accessKeyIdKey: accessKeyId
# # secretAccessKeyKey: secretAccessKey
helm install my-twenty ./packages/twenty-docker/helm/twenty -f values-secrets.yaml
Production Tips
- Image versioning: The chart defaults to
Chart.yaml'sappVersion(currently v1.14.0). Override viaimage.tagin values to pin a different version or uselatestfor rolling updates. - Keep secrets secure: Avoid
--setfor sensitive values; use-f values-secrets.yamlor reference existing Kubernetes Secrets viaserver.extraEnvFrom.- S3 credentials can be referenced via
storage.s3.secretName + accessKeyIdKey/secretAccessKeyKeyto avoid embedding them in pod specs.
- S3 credentials can be referenced via