Overview of the Deployment Process

  1. Install kubectl and helm on your local machine
  2. Select required subdomains
  3. Deploy the Cert-Manager Helm chart
  4. Deploy the Multiwoven Helm Chart
  5. Deploy additional (required) Nginx Ingress resources
  6. Obtain the public IP address associated with your Nginx Ingress Controller
  7. Create A records in your DNS record set that resolve to the public IP address of your Nginx Ingress Controller.
  8. Wait for cert-manager to issue an invalid staging certificate to your K8s cluster
  9. Switch letsencrypt-staging to letsencrypt-prod and upgrade Multiwoven again, this time obtaining a valid TLS certificate

Installing Multiwoven via Helm

Below is a shell script that can be used to deploy Multiwoven and its dependencies.

Chart Dependencies


Cert-Manager is used to automatically request, implement and rotate TLS certificates for your deployment. Enabling TLS is required.


Nginx-Ingress resources are added to provide the Multiwoven Ingress Controller with a external IP address.

Install Multiwoven

Environment Variables:

  1. tls-admin-email-address -> the email address that will receive email notifications about pending automatic TLS certificate rotations

  2. api-host -> api.your_domain (ex.

  3. ui-host -> app.your_domain (ex.

Temporal - Please read the Notes section below
  1. temporal-ui-host -> temporal.your_domain (ex.

  2. temporalHost -> your Temporal Cloud host name (ex.

  3. temporalNamespace -> your Temporal Namespace, verify within your Temporal Cloud account (ex. my.personal)


  • Deploying with the default In-cluster Temporal (recommended for Development workloads):
    1. Only temporal-ui-host is required. You should leave multiwovenConfig.temporalHost, temporal.enabled and multiwovenConfig.temporalNamespace commented out. You should also leave the temporal-cloud secret commented out as well.
  • Deploying with Temporal Cloud (HIGHLY recommended for Production workloads):
    1. comment out or remove the flag setting multiwovenConfig.temporalUiHost
    2. Uncomment the flags setting multiwovenConfig.temporalHost, temporal.enabled and multiwovenConfig.temporalNamespace. Also uncomment the temporal-cloud secret.
    3. Before running this script, you need to make sure that your Temporal Namespace authentication certificate key and pem files are in the same directory as the script. We recommend renaming these files to temporal.key and temporal.pem for simplicity.
  • Notice that for tlsCertIssuer, the value letsencrypt-staging is present. When the intial installation is done and cert-manager has successfully issued an invalid certificate for your 3 subdomains, you will switch this value to letsencrypt-prod to obtain a valid certificate. It is very important that you follow the steps written out here as LetsEncrypt’s production server only allows 5 attempts per week to obtain a valid certificate. This switch should be done LAST after you have verified that everything is already working as expected.
#### Pull and deploy the cert-manager Helm chart
cd charts/multiwoven
echo "installing cert-manager"
helm repo add jetstack --force-update
helm repo update
helm install cert-manager jetstack/cert-manager --namespace cert-manager --create-namespace --version v1.14.5 --set installCRDs=true

#### Pull and deploy the Multiwoven Helm chart
echo "installing Multiwoven"
helm repo add multiwoven
helm upgrade -i multiwoven multiwoven/multiwoven \
  --set multiwovenConfig.tlsAdminEmail=<tls-admin-email-address> \
  --set multiwovenConfig.tlsCertIssuer=letsencrypt-staging \
  --set multiwovenConfig.apiHost=<api-host> \
  --set multiwovenConfig.uiHost=<ui-host> \
  --set multiwovenWorker.multiwovenWorker.args={./app/temporal/cli/worker} \
  --set multiwovenConfig.temporalUiHost=<temporal-ui-host>
  # --set temporal.enabled=false \
  # --set multiwovenConfig.temporalHost=<temporal-host> \
  # --set multiwovenConfig.temporalNamespace=<temporal-namespace>

# kubectl create secret generic temporal-cloud -n multiwoven \
#     --from-file=temporal-root-cert=./temporal.pem \
#     --from-file=temporal-client-key=./temporal.key

# Install additional required Nginx ingress resources
echo "installing ingress-nginx resources"
kubectl apply -f

Post Installation Steps

  1. Run the following command to find the external IP address of your Ingress Controller. Note that it may take a minute or two for this value to become available post installation.
kubectl get svc -n ingress-nginx
  1. Once you have this IP address, go to your DNS record set and use that IP address to create three A records, one for each subdomain. Below are a list of Cloud Service Provider DNS tools but please refer to the documentation of your specific provider if not listed below.
  1. Run the following command, repeatedly, until an invalid LetsEncrypt staging certificate has been issued for your Ingress Controller.
kubectl describe certificate -n multiwoven mw-tls-cert

When the certificate has been issued, you will see the following output from the command above.

We also encourage you to further verify by navigating to your subdomain, app.your_domain, and check the certificate received by the browser. You should see something similar to the image below:

Once the invalid certificate has been successfully issued, you are ready for the final steps.

  1. Edit the shell script above by changing the tlsCertIssuer value from letsencrypt-staging to letsencrypt-prod and run the script again. Do not worry when you see Installation Failed for cert-manager, you are seeing this because it was installed on the intial run.

  2. Repeat Post Installation Step 3 until a valid certificate has been issued. Once issued, your deployment is complete and you can navigate to app.your_domain to get started using Mutliwoven!

Happy Helming!

Helm Chart Environment Values

Multiwoven Helm Configuration

General Configuration

  • kubernetesClusterDomain: The domain used within the Kubernetes cluster.
    • Default: cluster.local
  • kubernetesNamespace: The Kubernetes namespace for deployment.
    • Default: multiwoven

Multiwoven Configuration

multiwovenConfig.apiHostHostname for the API
multiwovenConfig.dbHostHostname for the PostgreSQL database service.multiwoven-postgresql
multiwovenConfig.dbPasswordPassword for the database user.password
multiwovenConfig.dbPortPort on which the database service is running.5432
multiwovenConfig.dbUsernameUsername for the database.multiwoven
multiwovenConfig.newRelicKeyNew Relic License Key.yourkey
multiwovenConfig.railsEnvRails environment setting.development
multiwovenConfig.smtpAddressSMTP server
multiwovenConfig.smtpHostSMTP server
multiwovenConfig.smtpPasswordSMTP server password.yourpassword
multiwovenConfig.smtpPortSMTP server port.587
multiwovenConfig.smtpUsernameSMTP server username.yourusername
multiwovenConfig.snowflakeDriverPathPath to the Snowflake ODBC driver./usr/lib/snowflake/odbc/lib/
multiwovenConfig.syncExtractorBatchSizeBatch size for the sync extractor.1000
multiwovenConfig.syncExtractorThreadPoolSizeThread pool size for the sync extractor.10
multiwovenConfig.syncLoaderBatchSizeBatch size for the sync loader.1000
multiwovenConfig.syncLoaderThreadPoolSizeThread pool size for the sync loader.10
multiwovenConfig.temporalActivityThreadPoolSizeThread pool size for Temporal activities.20
multiwovenConfig.temporalClientChainPath to Temporal client chain certificate./certs/temporal.chain.pem
multiwovenConfig.temporalClientKeyPath to Temporal client key./certs/temporal.key
multiwovenConfig.temporalHostHostname for Temporal service.multiwoven-temporal
multiwovenConfig.temporalNamespaceNamespace for Temporal service.multiwoven-dev
multiwovenConfig.temporalPortPort for Temporal service.7233
multiwovenConfig.temporalPostgresDefaultPortDefault port for Temporal’s PostgreSQL database.5432
multiwovenConfig.temporalPostgresPasswordPassword for Temporal’s PostgreSQL database.password
multiwovenConfig.temporalPostgresUserUsername for Temporal’s PostgreSQL database.multiwoven
multiwovenConfig.temporalPostgresqlVersionPostgreSQL version for Temporal.13
multiwovenConfig.temporalRootCertPath to Temporal root certificate./certs/temporal.pem
multiwovenConfig.temporalTaskQueueTask queue for Temporal workflows.sync-dev
multiwovenConfig.temporalUiVersionVersion of Temporal UI.2.23.2
multiwovenConfig.temporalVersionVersion of Temporal service.1.22.4
multiwovenConfig.temporalWorkflowThreadPoolSizeThread pool size for Temporal workflows.10
multiwovenConfig.uiHostUI host for the application

Multiwoven PostgreSQL Configuration

multiwovenPostgresql.enabledWhether or not to deploy PostgreSQL.true
multiwovenPostgresql.image.repositoryDocker image repository for PostgreSQL.postgres
multiwovenPostgresql.image.tagDocker image tag for PostgreSQL.13
multiwovenPostgresql.resources.limits.cpuCPU resource limits for PostgreSQL pod.1
multiwovenPostgresql.resources.limits.memoryMemory resource limits for PostgreSQL pod.2Gi
multiwovenPostgresql.resources.requests.cpuCPU resource requests for PostgreSQL pod.500m
multiwovenPostgresql.resources.requests.memoryMemory resource requests for PostgreSQL pod.1Gi
multiwovenPostgresql.ports.namePort name for PostgreSQL service.postgres
multiwovenPostgresql.ports.portPort number for PostgreSQL service.5432
multiwovenPostgresql.ports.targetPortTarget port for PostgreSQL service within the pod.5432
multiwovenPostgresql.replicasNumber of PostgreSQL pod replicas.1
multiwovenPostgresql.typeService type for PostgreSQL.ClusterIP

Multiwoven Server Configuration

multiwovenServer.image.repositoryDocker image repository for Multiwoven server.multiwoven/multiwoven-server
multiwovenServer.image.tagDocker image tag for Multiwoven server.latest
multiwovenServer.resources.limits.cpuCPU resource limits for Multiwoven server pod.2
multiwovenServer.resources.limits.memoryMemory resource limits for Multiwoven server pod.2Gi
multiwovenServer.resources.requests.cpuCPU resource requests for Multiwoven server pod.1
multiwovenServer.resources.requests.memoryMemory resource requests for Multiwoven server pod.1Gi
multiwovenServer.ports.namePort name for Multiwoven server service.3000
multiwovenServer.ports.portPort number for Multiwoven server service.3000
multiwovenServer.ports.targetPortTarget port for Multiwoven server service within the pod.3000
multiwovenServer.replicasNumber of Multiwoven server pod replicas.1
multiwovenServer.typeService type for Multiwoven server.ClusterIP

Multiwoven Worker Configuration

multiwovenWorker.argsCommand arguments for the Multiwoven worker.See value
multiwovenWorker.healthPortThe port in which the health check endpoint is exposed.4567
multiwovenWorker.image.repositoryDocker image repository for Multiwoven worker.multiwoven/multiwoven-server
multiwovenWorker.image.tagDocker image tag for Multiwoven worker.latest
multiwovenWorker.resources.limits.cpuCPU resource limits for Multiwoven worker pod.1
multiwovenWorker.resources.limits.memoryMemory resource limits for Multiwoven worker pod.1Gi
multiwovenWorker.resources.requests.cpuCPU resource requests for Multiwoven worker pod.500m
multiwovenWorker.resources.requests.memoryMemory resource requests for Multiwoven worker pod.512Mi
multiwovenWorker.replicasNumber of Multiwoven worker pod replicas.1

Persistent Volume Claim (PVC)

pvc.storageRequestStorage request size for the PVC.100Mi

Temporal Configuration

temporal.enabledWhether or not to deploy Temporal and Temporal UI service.true
temporal.ports.namePort name for Temporal service.7233
temporal.ports.portPort number for Temporal service.7233
temporal.ports.targetPortTarget port for Temporal service within the pod.7233
temporal.replicasNumber of Temporal service pod replicas.1
temporal.temporal.env.dbDatabase type for Temporal.postgresql
temporal.temporal.image.repositoryDocker image repository for Temporal.temporalio/auto-setup
temporal.temporal.image.tagDocker image tag for Temporal.1.22.4
temporal.temporal.resources.limits.cpuCPU resource limits for Temporal pod.1
temporal.temporal.resources.limits.memoryMemory resource limits for Temporal pod.2Gi
temporal.temporal.resources.requests.cpuCPU resource requests for Temporal pod.500m
temporal.temporal.resources.requests.memoryMemory resource requests for Temporal pod.1Gi
temporal.typeService type for Temporal.ClusterIP

Temporal UI Configuration

temporalUi.ports.namePort name for Temporal UI service.8080
temporalUi.ports.portPort number for Temporal UI service.8080
temporalUi.ports.targetPortTarget port for Temporal UI service within the pod.8080
temporalUi.replicasNumber of Temporal UI service pod replicas.1
temporalUi.temporalUi.env.temporalAddressTemporal service address for UI.multiwoven-temporal:7233
temporalUi.temporalUi.env.temporalAuthCallbackUrlAuthentication/authorization callback URL.
temporalUi.temporalUi.env.temporalAuthClientIdAuthentication/authorization client ID.
temporalUi.temporalUi.env.temporalAuthClientSecretAuthentication/authorization client secret.
temporalUi.temporalUi.env.temporalAuthEnabledEnable or disable authentication/authorization for Temporal UI.false
temporalUi.temporalUi.env.temporalAuthProviderUrlAuthentication/authorization OIDC provider URL.
temporalUi.temporalUi.env.temporalCorsOriginsAllowed CORS origins for Temporal UI.http://localhost:3000
temporalUi.temporalUi.env.temporalUiPortPort for Temporal UI service.8080
temporalUi.temporalUi.image.repositoryDocker image repository for Temporal UI.temporalio/ui
temporalUi.temporalUi.image.tagDocker image tag for Temporal UI.2.22.3
temporalUi.typeService type for Temporal UI.ClusterIP