diff --git a/charts/budibase/README.md b/charts/budibase/README.md
index d8191026ce..342011bdb1 100644
--- a/charts/budibase/README.md
+++ b/charts/budibase/README.md
@@ -157,6 +157,17 @@ $ helm install --create-namespace --namespace budibase budibase . -f values.yaml
| services.apps.replicaCount | int | `1` | The number of apps replicas to run. |
| services.apps.resources | object | `{}` | The resources to use for apps pods. See for more information on how to set these. |
| services.apps.startupProbe | object | HTTP health checks. | Startup probe configuration for apps pods. You shouldn't need to change this, but if you want to you can find more information here: |
+| services.automationWorkers.autoscaling.enabled | bool | `false` | Whether to enable horizontal pod autoscaling for the apps service. |
+| services.automationWorkers.autoscaling.maxReplicas | int | `10` | |
+| services.automationWorkers.autoscaling.minReplicas | int | `1` | |
+| services.automationWorkers.autoscaling.targetCPUUtilizationPercentage | int | `80` | Target CPU utilization percentage for the automation worker service. Note that for autoscaling to work, you will need to have metrics-server configured, and resources set for the automation worker pods. |
+| services.automationWorkers.enabled | bool | `true` | Whether or not to enable the automation worker service. If you disable this, automations will be processed by the apps service. |
+| services.automationWorkers.livenessProbe | object | HTTP health checks. | Liveness probe configuration for automation worker pods. You shouldn't need to change this, but if you want to you can find more information here: |
+| services.automationWorkers.logLevel | string | `"info"` | The log level for the automation worker service. |
+| services.automationWorkers.readinessProbe | object | HTTP health checks. | Readiness probe configuration for automation worker pods. You shouldn't need to change this, but if you want to you can find more information here: |
+| services.automationWorkers.replicaCount | int | `1` | The number of automation worker replicas to run. |
+| services.automationWorkers.resources | object | `{}` | The resources to use for automation worker pods. See for more information on how to set these. |
+| services.automationWorkers.startupProbe | object | HTTP health checks. | Startup probe configuration for automation worker pods. You shouldn't need to change this, but if you want to you can find more information here: |
| services.couchdb.backup.enabled | bool | `false` | Whether or not to enable periodic CouchDB backups. This works by replicating to another CouchDB instance. |
| services.couchdb.backup.interval | string | `""` | Backup interval in seconds |
| services.couchdb.backup.resources | object | `{}` | The resources to use for CouchDB backup pods. See for more information on how to set these. |
diff --git a/charts/budibase/templates/app-service-deployment.yaml b/charts/budibase/templates/app-service-deployment.yaml
index 7358e474ca..495d11aadc 100644
--- a/charts/budibase/templates/app-service-deployment.yaml
+++ b/charts/budibase/templates/app-service-deployment.yaml
@@ -192,7 +192,10 @@ spec:
- name: NODE_TLS_REJECT_UNAUTHORIZED
value: {{ .Values.services.tlsRejectUnauthorized }}
{{ end }}
-
+ {{- if .Values.services.automationWorkers.enabled }}
+ - name: APP_FEATURES
+ value: "api"
+ {{- end }}
image: budibase/apps:{{ .Values.globals.appVersion | default .Chart.AppVersion }}
imagePullPolicy: Always
{{- if .Values.services.apps.startupProbe }}
diff --git a/charts/budibase/templates/automation-worker-service-deployment.yaml b/charts/budibase/templates/automation-worker-service-deployment.yaml
new file mode 100644
index 0000000000..4c41be3393
--- /dev/null
+++ b/charts/budibase/templates/automation-worker-service-deployment.yaml
@@ -0,0 +1,244 @@
+{{- if .Values.services.automationWorkers.enabled }}
+apiVersion: apps/v1
+kind: Deployment
+metadata:
+ annotations:
+{{ if .Values.services.automationWorkers.deploymentAnnotations }}
+{{- toYaml .Values.services.automationWorkers.deploymentAnnotations | indent 4 -}}
+{{ end }}
+ labels:
+ io.kompose.service: automation-worker-service
+{{ if .Values.services.automationWorkers.deploymentLabels }}
+{{- toYaml .Values.services.automationWorkers.deploymentLabels | indent 4 -}}
+{{ end }}
+ name: automation-worker-service
+spec:
+ replicas: {{ .Values.services.automationWorkers.replicaCount }}
+ selector:
+ matchLabels:
+ io.kompose.service: automation-worker-service
+ strategy:
+ type: RollingUpdate
+ template:
+ metadata:
+ annotations:
+{{ if .Values.services.automationWorkers.templateAnnotations }}
+{{- toYaml .Values.services.automationWorkers.templateAnnotations | indent 8 -}}
+{{ end }}
+ labels:
+ io.kompose.service: automation-worker-service
+{{ if .Values.services.automationWorkers.templateLabels }}
+{{- toYaml .Values.services.automationWorkers.templateLabels | indent 8 -}}
+{{ end }}
+ spec:
+ containers:
+ - env:
+ - name: BUDIBASE_ENVIRONMENT
+ value: {{ .Values.globals.budibaseEnv }}
+ - name: DEPLOYMENT_ENVIRONMENT
+ value: "kubernetes"
+ - name: COUCH_DB_URL
+ {{ if .Values.services.couchdb.url }}
+ value: {{ .Values.services.couchdb.url }}
+ {{ else }}
+ value: http://{{ .Release.Name }}-svc-couchdb:{{ .Values.services.couchdb.port }}
+ {{ end }}
+ {{ if .Values.services.couchdb.enabled }}
+ - name: COUCH_DB_USER
+ valueFrom:
+ secretKeyRef:
+ name: {{ template "couchdb.fullname" . }}
+ key: adminUsername
+ - name: COUCH_DB_PASSWORD
+ valueFrom:
+ secretKeyRef:
+ name: {{ template "couchdb.fullname" . }}
+ key: adminPassword
+ {{ end }}
+ - name: ENABLE_ANALYTICS
+ value: {{ .Values.globals.enableAnalytics | quote }}
+ - name: API_ENCRYPTION_KEY
+ value: {{ .Values.globals.apiEncryptionKey | quote }}
+ - name: HTTP_LOGGING
+ value: {{ .Values.services.automationWorkers.httpLogging | quote }}
+ - name: INTERNAL_API_KEY
+ valueFrom:
+ secretKeyRef:
+ name: {{ template "budibase.fullname" . }}
+ key: internalApiKey
+ - name: INTERNAL_API_KEY_FALLBACK
+ value: {{ .Values.globals.internalApiKeyFallback | quote }}
+ - name: JWT_SECRET
+ valueFrom:
+ secretKeyRef:
+ name: {{ template "budibase.fullname" . }}
+ key: jwtSecret
+ - name: JWT_SECRET_FALLBACK
+ value: {{ .Values.globals.jwtSecretFallback | quote }}
+ {{ if .Values.services.objectStore.region }}
+ - name: AWS_REGION
+ value: {{ .Values.services.objectStore.region }}
+ {{ end }}
+ - name: MINIO_ENABLED
+ value: {{ .Values.services.objectStore.minio | quote }}
+ - name: MINIO_ACCESS_KEY
+ valueFrom:
+ secretKeyRef:
+ name: {{ template "budibase.fullname" . }}
+ key: objectStoreAccess
+ - name: MINIO_SECRET_KEY
+ valueFrom:
+ secretKeyRef:
+ name: {{ template "budibase.fullname" . }}
+ key: objectStoreSecret
+ - name: CLOUDFRONT_CDN
+ value: {{ .Values.services.objectStore.cloudfront.cdn | quote }}
+ - name: CLOUDFRONT_PUBLIC_KEY_ID
+ value: {{ .Values.services.objectStore.cloudfront.publicKeyId | quote }}
+ - name: CLOUDFRONT_PRIVATE_KEY_64
+ value: {{ .Values.services.objectStore.cloudfront.privateKey64 | quote }}
+ - name: MINIO_URL
+ value: {{ .Values.services.objectStore.url }}
+ - name: PLUGIN_BUCKET_NAME
+ value: {{ .Values.services.objectStore.pluginBucketName | quote }}
+ - name: APPS_BUCKET_NAME
+ value: {{ .Values.services.objectStore.appsBucketName | quote }}
+ - name: GLOBAL_BUCKET_NAME
+ value: {{ .Values.services.objectStore.globalBucketName | quote }}
+ - name: BACKUPS_BUCKET_NAME
+ value: {{ .Values.services.objectStore.backupsBucketName | quote }}
+ - name: PORT
+ value: {{ .Values.services.automationWorkers.port | quote }}
+ {{ if .Values.services.worker.publicApiRateLimitPerSecond }}
+ - name: API_REQ_LIMIT_PER_SEC
+ value: {{ .Values.globals.automationWorkers.publicApiRateLimitPerSecond | quote }}
+ {{ end }}
+ - name: MULTI_TENANCY
+ value: {{ .Values.globals.multiTenancy | quote }}
+ - name: OFFLINE_MODE
+ value: {{ .Values.globals.offlineMode | quote }}
+ - name: LOG_LEVEL
+ value: {{ .Values.services.automationWorkers.logLevel | quote }}
+ - name: REDIS_PASSWORD
+ value: {{ .Values.services.redis.password }}
+ - name: REDIS_URL
+ {{ if .Values.services.redis.url }}
+ value: {{ .Values.services.redis.url }}
+ {{ else }}
+ value: redis-service:{{ .Values.services.redis.port }}
+ {{ end }}
+ - name: SELF_HOSTED
+ value: {{ .Values.globals.selfHosted | quote }}
+ - name: POSTHOG_TOKEN
+ value: {{ .Values.globals.posthogToken | quote }}
+ - name: WORKER_URL
+ value: http://worker-service:{{ .Values.services.worker.port }}
+ - name: PLATFORM_URL
+ value: {{ .Values.globals.platformUrl | quote }}
+ - name: ACCOUNT_PORTAL_URL
+ value: {{ .Values.globals.accountPortalUrl | quote }}
+ - name: ACCOUNT_PORTAL_API_KEY
+ value: {{ .Values.globals.accountPortalApiKey | quote }}
+ - name: COOKIE_DOMAIN
+ value: {{ .Values.globals.cookieDomain | quote }}
+ - name: HTTP_MIGRATIONS
+ value: {{ .Values.globals.httpMigrations | quote }}
+ - name: GOOGLE_CLIENT_ID
+ value: {{ .Values.globals.google.clientId | quote }}
+ - name: GOOGLE_CLIENT_SECRET
+ value: {{ .Values.globals.google.secret | quote }}
+ - name: AUTOMATION_MAX_ITERATIONS
+ value: {{ .Values.globals.automationMaxIterations | quote }}
+ - name: TENANT_FEATURE_FLAGS
+ value: {{ .Values.globals.tenantFeatureFlags | quote }}
+ - name: ENCRYPTION_KEY
+ value: {{ .Values.globals.bbEncryptionKey | quote }}
+ {{ if .Values.globals.bbAdminUserEmail }}
+ - name: BB_ADMIN_USER_EMAIL
+ value: {{ .Values.globals.bbAdminUserEmail | quote }}
+ {{ end }}
+ {{ if .Values.globals.bbAdminUserPassword }}
+ - name: BB_ADMIN_USER_PASSWORD
+ value: {{ .Values.globals.bbAdminUserPassword | quote }}
+ {{ end }}
+ {{ if .Values.globals.pluginsDir }}
+ - name: PLUGINS_DIR
+ value: {{ .Values.globals.pluginsDir | quote }}
+ {{ end }}
+ {{ if .Values.services.automationWorkers.nodeDebug }}
+ - name: NODE_DEBUG
+ value: {{ .Values.services.automationWorkers.nodeDebug | quote }}
+ {{ end }}
+ {{ if .Values.globals.datadogApmEnabled }}
+ - name: DD_LOGS_INJECTION
+ value: {{ .Values.globals.datadogApmEnabled | quote }}
+ - name: DD_APM_ENABLED
+ value: {{ .Values.globals.datadogApmEnabled | quote }}
+ - name: DD_APM_DD_URL
+ value: https://trace.agent.datadoghq.eu
+ {{ end }}
+ {{ if .Values.globals.globalAgentHttpProxy }}
+ - name: GLOBAL_AGENT_HTTP_PROXY
+ value: {{ .Values.globals.globalAgentHttpProxy | quote }}
+ {{ end }}
+ {{ if .Values.globals.globalAgentHttpsProxy }}
+ - name: GLOBAL_AGENT_HTTPS_PROXY
+ value: {{ .Values.globals.globalAgentHttpsProxy | quote }}
+ {{ end }}
+ {{ if .Values.globals.globalAgentNoProxy }}
+ - name: GLOBAL_AGENT_NO_PROXY
+ value: {{ .Values.globals.globalAgentNoProxy | quote }}
+ {{ end }}
+ {{ if .Values.services.tlsRejectUnauthorized }}
+ - name: NODE_TLS_REJECT_UNAUTHORIZED
+ value: {{ .Values.services.tlsRejectUnauthorized }}
+ {{ end }}
+ - name: APP_FEATURES
+ value: "automations"
+
+ image: budibase/apps:{{ .Values.globals.appVersion | default .Chart.AppVersion }}
+ imagePullPolicy: Always
+ {{- if .Values.services.automationWorkers.startupProbe }}
+ {{- with .Values.services.automationWorkers.startupProbe }}
+ startupProbe:
+ {{- toYaml . | nindent 10 }}
+ {{- end }}
+ {{- end }}
+ {{- if .Values.services.automationWorkers.livenessProbe }}
+ {{- with .Values.services.automationWorkers.livenessProbe }}
+ livenessProbe:
+ {{- toYaml . | nindent 10 }}
+ {{- end }}
+ {{- end }}
+ {{- if .Values.services.automationWorkers.readinessProbe }}
+ {{- with .Values.services.automationWorkers.readinessProbe }}
+ readinessProbe:
+ {{- toYaml . | nindent 10 }}
+ {{- end }}
+ {{- end }}
+ name: bbautomationworker
+ ports:
+ - containerPort: {{ .Values.services.automationWorkers.port }}
+ {{ with .Values.services.automationWorkers.resources }}
+ resources:
+ {{- toYaml . | nindent 10 }}
+ {{ end }}
+ {{- with .Values.affinity }}
+ affinity:
+ {{- toYaml . | nindent 8 }}
+ {{- end }}
+ {{- with .Values.tolerations }}
+ tolerations:
+ {{- toYaml . | nindent 8 }}
+ {{- end }}
+ {{ if .Values.schedulerName }}
+ schedulerName: {{ .Values.schedulerName | quote }}
+ {{ end }}
+ {{ if .Values.imagePullSecrets }}
+ imagePullSecrets:
+ {{- toYaml .Values.imagePullSecrets | nindent 6 }}
+ {{ end }}
+ restartPolicy: Always
+ serviceAccountName: ""
+status: {}
+{{- end }}
\ No newline at end of file
diff --git a/charts/budibase/templates/automation-worker-service-hpa.yaml b/charts/budibase/templates/automation-worker-service-hpa.yaml
new file mode 100644
index 0000000000..f29223b61b
--- /dev/null
+++ b/charts/budibase/templates/automation-worker-service-hpa.yaml
@@ -0,0 +1,32 @@
+{{- if .Values.services.automationWorkers.autoscaling.enabled }}
+apiVersion: {{ ternary "autoscaling/v2" "autoscaling/v2beta2" (.Capabilities.APIVersions.Has "autoscaling/v2") }}
+kind: HorizontalPodAutoscaler
+metadata:
+ name: {{ include "budibase.fullname" . }}-apps
+ labels:
+ {{- include "budibase.labels" . | nindent 4 }}
+spec:
+ scaleTargetRef:
+ apiVersion: apps/v1
+ kind: Deployment
+ name: automation-worker-service
+ minReplicas: {{ .Values.services.automationWorkers.autoscaling.minReplicas }}
+ maxReplicas: {{ .Values.services.automationWorkers.autoscaling.maxReplicas }}
+ metrics:
+ {{- if .Values.services.automationWorkers.autoscaling.targetCPUUtilizationPercentage }}
+ - type: Resource
+ resource:
+ name: cpu
+ target:
+ type: Utilization
+ averageUtilization: {{ .Values.services.automationWorkers.autoscaling.targetCPUUtilizationPercentage }}
+ {{- end }}
+ {{- if .Values.services.automationWorkers.autoscaling.targetMemoryUtilizationPercentage }}
+ - type: Resource
+ resource:
+ name: memory
+ target:
+ type: Utilization
+ averageUtilization: {{ .Values.services.automationWorkers.autoscaling.targetMemoryUtilizationPercentage }}
+ {{- end }}
+{{- end }}
diff --git a/charts/budibase/values.yaml b/charts/budibase/values.yaml
index 13054e75fc..6dbcc20242 100644
--- a/charts/budibase/values.yaml
+++ b/charts/budibase/values.yaml
@@ -272,6 +272,75 @@ services:
# and resources set for the apps pods.
targetCPUUtilizationPercentage: 80
+ automationWorkers:
+ # -- Whether or not to enable the automation worker service. If you disable this,
+ # automations will be processed by the apps service.
+ enabled: true
+ # @ignore (you shouldn't need to change this)
+ port: 4002
+ # -- The number of automation worker replicas to run.
+ replicaCount: 1
+ # -- The log level for the automation worker service.
+ logLevel: info
+ # -- The resources to use for automation worker pods. See
+ #
+ # for more information on how to set these.
+ resources: {}
+ # -- Startup probe configuration for automation worker pods. You shouldn't
+ # need to change this, but if you want to you can find more information
+ # here:
+ #
+ # @default -- HTTP health checks.
+ startupProbe:
+ # @ignore
+ httpGet:
+ path: /health
+ port: 4002
+ scheme: HTTP
+ # @ignore
+ failureThreshold: 30
+ # @ignore
+ periodSeconds: 3
+ # -- Readiness probe configuration for automation worker pods. You shouldn't
+ # need to change this, but if you want to you can find more information
+ # here:
+ #
+ # @default -- HTTP health checks.
+ readinessProbe:
+ # @ignore
+ httpGet:
+ path: /health
+ port: 4002
+ scheme: HTTP
+ # @ignore
+ periodSeconds: 3
+ # @ignore
+ failureThreshold: 1
+ # -- Liveness probe configuration for automation worker pods. You shouldn't
+ # need to change this, but if you want to you can find more information
+ # here:
+ #
+ # @default -- HTTP health checks.
+ livenessProbe:
+ # @ignore
+ httpGet:
+ path: /health
+ port: 4002
+ scheme: HTTP
+ # @ignore
+ failureThreshold: 3
+ # @ignore
+ periodSeconds: 30
+ autoscaling:
+ # -- Whether to enable horizontal pod autoscaling for the apps service.
+ enabled: false
+ minReplicas: 1
+ maxReplicas: 10
+ # -- Target CPU utilization percentage for the automation worker service.
+ # Note that for autoscaling to work, you will need to have metrics-server
+ # configured, and resources set for the automation worker pods.
+ targetCPUUtilizationPercentage: 80
+
worker:
# @ignore (you shouldn't need to change this)
port: 4003
diff --git a/packages/backend-core/src/queue/inMemoryQueue.ts b/packages/backend-core/src/queue/inMemoryQueue.ts
index a8add7ecb6..ac7cdf550b 100644
--- a/packages/backend-core/src/queue/inMemoryQueue.ts
+++ b/packages/backend-core/src/queue/inMemoryQueue.ts
@@ -68,6 +68,10 @@ class InMemoryQueue {
})
}
+ async isReady() {
+ return true
+ }
+
// simply puts a message to the queue and emits to the queue for processing
/**
* Simple function to replicate the add message functionality of Bull, putting
diff --git a/packages/server/src/api/index.ts b/packages/server/src/api/index.ts
index 56c61ce85a..ad3d8307da 100644
--- a/packages/server/src/api/index.ts
+++ b/packages/server/src/api/index.ts
@@ -4,15 +4,24 @@ import currentApp from "../middleware/currentapp"
import zlib from "zlib"
import { mainRoutes, staticRoutes, publicRoutes } from "./routes"
import { middleware as pro } from "@budibase/pro"
-import { apiEnabled } from "../features"
+import { apiEnabled, automationsEnabled } from "../features"
import migrations from "../middleware/appMigrations"
+import { automationQueue } from "../automations"
export { shutdown } from "./routes/public"
const compress = require("koa-compress")
export const router: Router = new Router()
-router.get("/health", ctx => (ctx.status = 200))
+router.get("/health", async ctx => {
+ if (automationsEnabled()) {
+ if (!(await automationQueue.isReady())) {
+ ctx.status = 503
+ return
+ }
+ }
+ ctx.status = 200
+})
router.get("/version", ctx => (ctx.body = envCore.VERSION))
router.use(middleware.errorHandling)