You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
A Helm chart to deploy Seqera Platform (also referred to as Tower) on Kubernetes.
Some basic familiarity with Helm is assumed. If you are new to Helm, please refer to the Helm documentation.
We recommend reading through the values.yaml file to understand the configuration options available for the chart. Each entry is documented with # -- comments describing its purpose and usage. Other annotations are used to automatically generate the README files and can be ignored:
# @section — groups related values under a heading in the generated README
# @default — documents a default value that is computed in the templates rather than set literally in values.yaml
Requirements and configuration
For an overview of the Seqera Platform architecture and its requirements, refer to the Seqera documentation.
The required values to set in order to have a working installation are:
The domain where Seqera Platform is accessible, set under .global.platformExternalDomain.
The .image section under the .backend, .frontend, .cron and .cron.dbMigrationInitContainer components to point to your container registry.
Container registry credentials under the .global.imageCredentials section (can be the credentials for cr.seqera.io or your private registry where you vendored the images to).
Alternatively, to avoid storing sensitive credentials in the values file, you can create a Kubernetes Secret containing the credentials and reference it in the .global.imageCredentialsSecrets value. Refer to the Kubernetes docs to create a Kubernetes Secret to store image pull credentials.
These credentials will be used by all the subcharts unless overridden in the specific subchart.
Multiple credentials can be specified to cover different registries or repositories within the same registry, e.g. you can set credentials for cr.seqera.io/enterprise (where Platform images are located) and cr.seqera.io/ai (where Seqera AI products are located).
Additional pull secrets can be defined in each .image section to extend the global credentials, if that image is located in a different registry.
Image pull secrets defined in the specific .image section will be added to the global ones, they won't replace them.
The database connection details for the Platform MySQL database under the .platformDatabase section.
The redis connection details under the .redis section.
The Seqera license key under the .platform.licenseString value, or the name of an existing Secret containing the license key under the .platform.licenseSecretName value.
Other sensitive values are automatically generated by the Helm chart if not provided (e.g. database encryption keys, initial access tokens), but we recommend setting them to known values to avoid losing access to the Platform installation in case of a Helm chart reinstallation.
When setting the Platform OIDC client registration token to an existing secret, make sure to set the same secret in the following subchart values .studios.proxy.oidcClientRegistrationTokenSecretName and .mcp.oidcToken.existingSecretName.
The Helm chart comes with several requirement checks that will validate the provided configuration before proceeding with the installation.
By default the chart selects the Platform application images defined in the appVersion field of the Chart.yaml file, currently set as v26.1.3.
Note
The Platform chart requires the unprivileged version of the Seqera Platform frontend image (shipped with -unprivileged suffix until Platform v25.3, without any suffix starting from v26.1).
When a sensitive value is required (e.g. the database password, the Seqera license key), you can either provide it directly in the values file or reference an existing Kubernetes Secret containing the value. The key names to use in the provided Secret are specified in the values file comments.
Sensitive values provided as plain text by the user are always stored in a Kubernetes Secret created by the chart. When an external Secret is used instead, the chart instructs the components to read the sensitive value from the external Secret directly, without further storing copies of the sensitive value in the chart-created Secret.
Refer to this example for a demonstration of how to create a Kubernetes Secret to store sensitive values.
Installing the chart
To install the chart:
Download the default values file:
helm show values oci://public.cr.seqera.io/charts/platform --version 0.35.0 > values.yaml
Edit values.yaml to match your environment. We recommend removing entries whose defaults you don't need to override — this keeps your configuration file focused and easier to maintain across upgrades.
Install the chart with the release name my-release:
Refer to the examples directory for different scenarios of installing the Platform chart.
The examples provided are showcasing possible configurations of the Helm chart, and are not representative of a full installation.
Please refer to the Seqera Platform documentation for complete installation instructions.
Upgrading the chart
When upgrading between versions, please refer to the CHANGELOG.md for breaking changes and migration instructions.
Domain where user-created Platform reports are exposed, to avoid Cross-Site Scripting (XSS) attacks. If unset, data is served through the main domain .global.platformExternalDomain. Evaluated as a template
Base URL for Studios connections: can be any value, since each session will use a unique subdomain under .global.studiosDomain anyway to connect. Evaluated as a template
Domain where the Portal Web frontend listens. Evaluated as a template
Global: Ingress
Key
Type
Default
Description
global.ingress.enabled
bool
false
Enable Ingress for the parent chart and every subchart that exposes one. Each chart's local ingress.enabled is OR'd with this — set this to true to turn on all Ingresses in one switch
global.ingress.path
string
"/"
Default path applied to ingress rules when a chart's local ingress.path is not set. AWS ALB users should override to /*.
global.ingress.defaultPathType
string
"Prefix"
Default path type applied to ingress rules when a chart's local ingress.defaultPathType is not set. Prefix works for nginx, traefik, AWS ALB, and most modern controllers. Override to ImplementationSpecific only if your controller requires it (e.g. older GKE).
global.ingress.ingressClassName
string
""
Default ingress class name applied to ingress rules when a chart's local ingress.ingressClassName is not set. Replaces the deprecated kubernetes.io/ingress.class annotation
global.ingress.annotations
object
{}
Annotations merged into every chart's Ingress (e.g. cert-manager issuer, NGINX proxy-body-size, ALB SSL config). Local ingress.annotations wins on key collision. Evaluated as a template
global.ingress.extraLabels
object
{}
Extra labels merged into every chart's Ingress. Local ingress.extraLabels wins on key collision. Evaluated as a template
global.ingress.tls
list
[]
TLS entries concatenated with each chart's local ingress.tls. Useful for a single wildcard cert that covers all services. Evaluated as a template
Global: Image Credentials
Key
Type
Default
Description
global.imageCredentials
list
[]
Optional credentials to log in and fetch images from a private registry. These credentials are shared with all the subcharts automatically
global.imageCredentialsSecrets
list
[]
Optional list of existing Secrets containing image pull credentials to use for pulling images from private registries. These Secrets are shared with all the subcharts automatically
Platform Database
Key
Type
Default
Description
platformDatabase.host
string
""
Platform MySQL database hostname
platformDatabase.port
int
3306
Platform MySQL database port
platformDatabase.name
string
""
Platform MySQL database name
platformDatabase.username
string
""
Platform MySQL database username
platformDatabase.password
string
""
Platform MySQL database password
platformDatabase.existingSecretName
string
""
Name of an existing Secret containing credentials for the Platform MySQL database, as an alternative to the password field. Note: the Secret must already exist in the same namespace at the time of deployment
platformDatabase.existingSecretKey
string
"TOWER_DB_PASSWORD"
Key in the existing Secret containing the password for the Platform MySQL database
platformDatabase.driver
string
"mariadb"
Database driver. Possible options: "mariadb" (or its alias "mysql")
platformDatabase.connectionOptions
object
{"mariadb":["permitMysqlScheme=true"]}
Connection options to compose in the driver URL according to the driver used. The only driver that can be set is 'mariadb'
JWT seed, defined as string, used to sign authentication tokens. Define the value as a String or a Secret, not both at the same time. If neither is defined, Helm generates a random 35-character string. WARNING: Always explicitly set this value or use an existing secret when using Kustomize. Auto-generated random values are incompatible with Kustomize. When upgrading releases via Kustomize, Helm cannot query the cluster to check if a secret already exists, causing it to regenerate a new random value on each upgrade
platform.jwtSeedSecretName
string
""
Name of an existing Secret containing the JWT seed, as an alternative to the string field. Note: the Secret must already exist in the same namespace at the time of deployment
platform.jwtSeedSecretKey
string
"TOWER_JWT_SECRET"
Key in the existing Secret containing the JWT seed
Platform: Crypto Seed
Key
Type
Default
Description
platform.cryptoSeedString
string
""
Crypto seed, defined as string, used to encrypt sensitive data in the database. Note: this needs to be a stable value that doesn't change between deployments, otherwise encrypted data in the database will become inaccessible. Either define the value as a String or a Secret, not both at the same time. If neither is defined, a random 35 characters long string will be generated by Helm WARNING: Always explicitly set this value or use an existing secret when using Kustomize. Auto-generated random values are incompatible with Kustomize. When upgrading releases via Kustomize, Helm cannot query the cluster to check if a secret already exists, causing it to regenerate a new random value on each upgrade
platform.cryptoSeedSecretName
string
""
Name of an existing Secret containing the crypto seed, as an alternative to the string field. Note: the Secret must already exist in the same namespace at the time of deployment
platform.cryptoSeedSecretKey
string
"TOWER_CRYPTO_SECRETKEY"
Key in the existing Secret containing the crypto seed
Platform license key. A license key is a long alphanumeric string provided by your Seqera account manager. Define the value as a String or a Secret, not both at the same time
platform.licenseSecretName
string
""
Name of an existing Secret containing the Platform license key, as an alternative to the string field. Note: the Secret must already exist in the same namespace at the time of deployment
platform.licenseSecretKey
string
"TOWER_LICENSE"
Key in the existing Secret containing the Platform license key
Platform: OIDC
Key
Type
Default
Description
platform.oidcPrivateKeyBase64
string
""
OIDC private key in PEM format, base64-encoded. Define the value as a String or a Secret, not both at the same time. If neither is defined, Helm generates a random private key. WARNING: Always explicitly set this value or use an existing secret when using Kustomize. Auto-generated random values are incompatible with Kustomize. When upgrading releases via Kustomize, Helm cannot query the cluster to check if a secret already exists, causing it to regenerate a new random value on each upgrade
platform.oidcPrivateKeySecretName
string
""
Name of an existing Secret containing the OIDC private key in PEM format, as an alternative to the base64-encoded string field. Note: the Secret must already exist in the same namespace at the time of deployment
platform.oidcPrivateKeySecretKey
string
"oidc.pem"
Key in the existing Secret containing the OIDC private key in PEM format
platform.oidcClientRegistrationToken
string
""
OIDC client registration token as a string. Used by Studios and MCP to dynamically register OAuth clients with Seqera Platform's OIDC provider. If neither this nor oidcClientRegistrationTokenSecretName is set, a random value is generated. WARNING: Always explicitly set this value or use an existing secret when using Kustomize. Auto-generated random values are incompatible with Kustomize. When upgrading releases via Kustomize, Helm cannot query the cluster to check if a secret already exists, causing it to regenerate a new random value on each upgrade
platform.oidcClientRegistrationTokenSecretName
string
""
Name of an existing Secret containing the OIDC client registration token, as an alternative to the string field. Note: the Secret must already exist in the same namespace at the time of deployment
platform.oidcClientRegistrationTokenSecretKey
string
"OIDC_CLIENT_REGISTRATION_TOKEN"
Key in the existing Secret containing the OIDC client registration token
Platform: SMTP
Key
Type
Default
Description
platform.smtp.host
string
""
SMTP server hostname to let users authenticate through email, and to send email notifications for events
platform.smtp.port
string
""
SMTP server port
platform.smtp.user
string
""
SMTP server username
platform.smtp.password
string
""
SMTP server password
platform.smtp.existingSecretName
string
""
Name of an existing secret containing the SMTP password
platform.smtp.existingSecretKey
string
"TOWER_SMTP_PASSWORD"
Key in the existing Secret containing the SMTP password
Platform: Wave & Data Explorer
Key
Type
Default
Description
platform.waveServerUrl
string
"https://wave.seqera.io"
URL of the Wave service Platform uses. Evaluated as a template. The Wave service provided by Seqera is https://wave.seqera.io
Image registry where Wave (defined at .platform.waveServerUrl) will push custom Studios images built for user sessions. Credentials to the registry/repository must be defined in each Platform Workspace. Example: myregistry.example.com
platform.studios.customImageRepository
string
""
Image repository where Wave (defined at .platform.waveServerUrl) will push custom Studios images built for user sessions. Example: myteam/studios-container-repo
Additional labels for the ConfigMap objects. Evaluated as a template
platform.secretLabels
object
{}
Additional labels for the Secret objects. Evaluated as a template
platform.serviceLabels
object
{}
Additional labels for the Service objects. Evaluated as a template
platform.configMapAnnotations
object
{}
Additional annotations for the ConfigMap objects. Evaluated as a template
platform.secretAnnotations
object
{}
Additional annotations for the Secret objects. Evaluated as a template
platform.serviceAnnotations
object
{}
Additional annotations for the Service objects. Evaluated as a template
Redis
Key
Type
Default
Description
redis.host
string
""
Redis hostname
redis.port
int
6379
Redis port
redis.password
string
""
Redis password if the installation requires it
redis.existingSecretName
string
""
Name of an existing Secret containing credentials for Redis, as an alternative to the password field. Note: the Secret must already exist in the same namespace at the time of deployment
redis.existingSecretKey
string
"TOWER_REDIS_PASSWORD"
Key in the existing Secret containing the password for Redis
redis.enableTls
bool
false
Enable TLS when connecting to Redis
Backend: Image
Key
Type
Default
Description
backend.image.registry
string
""
Backend container image registry
backend.image.repository
string
"enterprise/platform/backend"
Backend container image repository
backend.image.tag
string
"{{ .chart.AppVersion }}"
Backend container image tag
backend.image.digest
string
""
Backend container image digest in the format sha256:1234abcdef
List of Micronaut Environments to enable on the backend pod
Backend: Service
Key
Type
Default
Description
backend.service.type
string
"ClusterIP"
Backend Service type. Note: ingresses using AWS ALB require the service to be NodePort
backend.service.http.name
string
"http"
Service name to use
backend.service.http.targetPort
int
8080
Port on the pod/container that the Service forwards traffic to (can be a number or named port, distinct from the Service's external port). Platform v25.3+ only; previous versions were hardcoded to 8080
backend.service.http.nodePort
int
0
Service node port, only used when service.type is Nodeport or LoadBalancer Choose port between 30000-32767, unless the cluster was configured differently than default
Frontend Service type. Note: ingresses using AWS ALB require the service to be NodePort
frontend.service.http.name
string
"http"
Service name to use
frontend.service.http.port
int
80
Service port
frontend.service.http.targetPort
int
8083
Port on the pod/container that the Service forwards traffic to (can be a number or named port, distinct from the Service's external port)
frontend.service.http.nodePort
int
0
Service node port, only used when service.type is Nodeport or LoadBalancer Choose port between 30000-32767, unless the cluster was configured differently than default
Extra Service options to place under .spec (for example, clusterIP, loadBalancerIP, externalTrafficPolicy, externalIPs). Evaluated as a template
Frontend: Pod
Key
Type
Default
Description
frontend.initContainers
list
[]
Additional init containers for the frontend pod. Evaluated as a template
frontend.command
list
[]
Override default container command (useful when using custom images)
frontend.args
list
[]
Override default container args (useful when using custom images)
frontend.podLabels
object
{}
Additional labels for the frontend pod. Evaluated as a template
frontend.podAnnotations
object
{}
Additional annotations for the frontend pod. Evaluated as a template
frontend.extraOptionsSpec
object
{}
Extra options to place under .spec (e.g. revisionHistoryLimit, etc). Evaluated as a template. Note: the cron deployment can only run a single replica and use Recreate strategy
frontend.extraOptionsTemplateSpec
object
{}
Extra options to place under .spec.template.spec (for example, nodeSelector, affinity, restartPolicy). Evaluated as a template
frontend.extraEnvVars
list
[]
Extra environment variables to set on the frontend pod
frontend.extraEnvVarsCMs
list
[]
List of ConfigMaps containing extra env vars
frontend.extraEnvVarsSecrets
list
[]
List of Secrets containing extra env vars
frontend.extraVolumes
list
[]
Extra volumes to add to the deployment (evaluated as template). Requires setting extraVolumeMounts
frontend.extraVolumeMounts
list
[]
List of volume mounts to add to the container (evaluated as template). Normally used with extraVolumes
Frontend: Security Context
Key
Type
Default
Description
frontend.podSecurityContext.enabled
bool
true
Enable pod Security Context
frontend.podSecurityContext.fsGroup
int
101
GID that Kubernetes applies to mounted volumes and created files so processes in the pod can share group-owned access
frontend.containerSecurityContext.enabled
bool
true
Enable container Security Context
frontend.containerSecurityContext.runAsUser
int
101
UID the container processes run as (overrides container image default)
frontend.containerSecurityContext.runAsNonRoot
bool
true
Require the container to run as a non-root UID (prevents starting if UID 0)
List of Micronaut Environments to enable on the cron pod
cron.service.type
string
"ClusterIP"
Cron Service type. Note: ingresses using AWS ALB require the service to be NodePort
cron.service.http.name
string
"http"
Service name to use
cron.service.http.port
int
8080
Service port
cron.service.http.targetPort
int
8082
Port on the pod/container that the Service forwards traffic to (can be a number or named port, distinct from the Service's external port)
cron.service.http.nodePort
int
0
Service node port, only used when service.type is Nodeport or LoadBalancer Choose port between 30000-32767, unless the cluster was configured differently than default
Extra Service options to place under .spec (for example, clusterIP, loadBalancerIP, externalTrafficPolicy, externalIPs). Evaluated as a template
Cron: Pod
Key
Type
Default
Description
cron.initContainers
list
[]
Additional init containers for the cron pod. Evaluated as a template
cron.command
list
[]
Override default container command (useful when using custom images)
cron.args
list
[]
Override default container args (useful when using custom images)
cron.podLabels
object
{}
Additional labels for the cron pod. Evaluated as a template
cron.podAnnotations
object
{}
Additional annotations for the cron pod. Evaluated as a template
cron.extraOptionsSpec
object
{}
Extra options to place under .spec (for example, revisionHistoryLimit). Evaluated as a template Note that cron deployment needs to have a single replica with Recreate strategy
cron.extraOptionsTemplateSpec
object
{}
Extra options to place under .spec.template.spec (for example, nodeSelector, affinity, restartPolicy) Evaluated as a template
cron.extraEnvVars
list
[]
Extra environment variables to set on the cron pod
cron.extraEnvVarsCMs
list
[]
List of ConfigMaps containing extra env vars
cron.extraEnvVarsSecrets
list
[]
List of Secrets containing extra env vars
cron.extraVolumes
list
[]
Extra volumes to add to the deployment (evaluated as template). Requires setting extraVolumeMounts
cron.extraVolumeMounts
list
[]
List of volume mounts to add to the container (evaluated as template). Normally used with extraVolumes
Cron: Security Context
Key
Type
Default
Description
cron.podSecurityContext.enabled
bool
true
Enable pod Security Context
cron.podSecurityContext.fsGroup
int
101
GID that Kubernetes applies to mounted volumes and created files so processes in the pod can share group-owned access
cron.containerSecurityContext.enabled
bool
true
Enable container Security Context
cron.containerSecurityContext.runAsUser
int
101
UID the container processes run as (overrides container image default)
cron.containerSecurityContext.runAsNonRoot
bool
true
Require the container to run as a non-root UID (prevents starting if UID 0)
Fine-grained Linux kernel privileges to add or drop for the container
cron.dbMigrationInitContainer.resources
object
{}
Container requests and limits for different resources like CPU or memory
Init Container Dependencies
Key
Type
Default
Description
initContainerDependencies.enabled
bool
true
Enable init containers that coordinate startup dependencies between Platform components (for example, wait for database readiness before cron starts, wait for cron before backend starts, etc)
Init Container Dependencies: Wait For MySQL
Key
Type
Default
Description
initContainerDependencies.waitForMySQL.enabled
bool
true
Enable wait for MySQL init container before starting backend and cron
Additional environment variables for the init container. The special variable MYSQL_EXTRA_ARGS is appended verbatim to the mysql readiness check command, and can be used to pass TLS flags when connecting to managed MySQL services such as AWS RDS or Azure Database for MySQL that require certificate verification. Pair with extraVolumeMounts to mount the CA certificate into the container. Example (TLS with CA certificate mounted from a volume): extraEnvVars: - name: MYSQL_EXTRA_ARGS value: "--ssl-ca=/certs/ca.pem --ssl-mode=VERIFY_IDENTITY"
Additional volume mounts for the init container. Use this to mount CA certificates (e.g. from a Secret or ConfigMap populated by an extraInitContainer) so that MYSQL_EXTRA_ARGS can reference them.
Init Container Dependencies: Wait For Redis
Key
Type
Default
Description
initContainerDependencies.waitForRedis.enabled
bool
true
Enable wait for Redis init container before starting backend and cron
Additional volume mounts for the init container (e.g. to mount a CA certificate)
Service Account
Key
Type
Default
Description
serviceAccount.name
string
""
Name of an existing ServiceAccount. If not set, a new ServiceAccount is generated based on the release name
serviceAccount.annotations
object
{}
Additional annotations for the ServiceAccount to generate
serviceAccount.imagePullSecretNames
list
[]
Names of Secrets containing credentials to pull images from registries
serviceAccount.automountServiceAccountToken
bool
false
Automount service account token when the service account is generated
Ingress
Key
Type
Default
Description
ingress.enabled
bool
false
Enable ingress for Platform
ingress.path
string
""
Path for the main ingress rule. When empty, falls back to global.ingress.path
ingress.contentPath
string
""
Path for the content domain ingress rule. When empty, falls back to ingress.path
ingress.defaultPathType
string
""
Default path type for the Ingress. When empty, falls back to global.ingress.defaultPathType
ingress.defaultBackend
object
{}
Configure the default service for the ingress (evaluated as template) Important: make sure only one defaultBackend is defined across the k8s cluster: if the ingress doesn't reconcile successfully, 'describe ingress ' will report problems
ingress.extraHosts
list
[]
Additional hosts you want to include. Evaluated as a template
ingress.annotations
object
{}
Ingress annotations specific to your load balancer. Evaluated as a template
ingress.extraLabels
object
{}
Additional labels for the ingress object. Evaluated as a template
ingress.ingressClassName
string
""
Name of the ingress class (replaces the deprecated annotation kubernetes.io/ingress.class). When empty, falls back to global.ingress.ingressClassName
ingress.tls
list
[]
TLS configuration. Evaluated as a template
Common
Key
Type
Default
Description
extraDeploy
list
[]
Array of extra objects to deploy with the release
commonAnnotations
object
{}
Annotations to add to all deployed objects
commonLabels
object
{}
Labels to add to all deployed objects
Subcharts: Studios
Key
Type
Default
Description
studios.enabled
bool
true
Enable Studios feature. Refer to the subchart README for more details and the full list of configuration options
studios needs to pass a client registration token to the platform backend so that it can register studios clients to the platform OIDC provider. If the platform oidc registration token is coming from a separate secret, you need to update it here too. common.names.dependency.fullname is used (rather than common.names.fullname) because this value is tpl-evaluated inside the studios subchart context where .Chart.Name is studios, not platform; passing chartName: platform explicitly reproduces the parent's fullname. Name of the existing Secret containing the OIDC client registration token to share with the Studios proxy. Evaluated as a template
mcp needs to pass a client registration token to the platform backend so that it can register mcp clients to the platform OIDC provider. If the platform oidc registration token is coming from a separate secret, you need to update it here too. common.names.dependency.fullname is used (rather than common.names.fullname) because this value is tpl-evaluated inside the mcp subchart context where .Chart.Name is mcp, not platform; passing chartName: platform explicitly reproduces the parent's fullname. Name of the existing Secret containing the OIDC client registration token to share with MCP. Evaluated as a template
mcp.oidcToken.existingSecretKey
string
"OIDC_CLIENT_REGISTRATION_TOKEN"
Key in the existing Secret containing the OIDC client registration token
Subcharts: Agent Backend
Key
Type
Default
Description
agent-backend.enabled
bool
true
Enable agent backend feature used by seqera cli ai command. Refer to the subchart README for more details and the full list of configuration options
Subcharts: Portal Web
Key
Type
Default
Description
portal-web.enabled
bool
true
Enable portal web frontend. Refer to the subchart README for more details and the full list of configuration options
Licensing
Seqera® and Nextflow® are registered trademarks of Seqera Labs.
Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with the License. You may obtain a copy of the License at
Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the specific language governing permissions and limitations under the License.