Deploy to Kubernetes

This page covers installing Enterprise Studio with Helm, configuring values, managing secrets, and setting up TLS.

Prerequisites

  • helm (v3.8+): Install Helm

  • kubectl: Install kubectl

  • Access to a Kubernetes enviroment (cloud, on-prem, or local with a LoadBalancer resource implementation).

Configure Helm

Add the Enterprise Studio Helm chart repository.

helm repo add \
  enterprise-studio https://dist.neo4j.org/enterprise-studio/helm

Update repository

helm repo update enterprise-studio

Check available versions of Enterprise Studio Helm charts

helm search repo enterprise-studio/ --versions

Export a values template to use as a starting point:

helm show values \
  enterprise-studio/neo4j-enterprise-studio \
  --version '<VERSION>' > values.yaml

Configure values

Edit values.yaml with your deployment settings. At a minimum, you need to configure:

  • Asset storage connection (URI, database name, credentials)

  • At least one Neo4j deployment for users to connect to

See Reference for the full list of available settings.

Minimal example

Replace <ASSET-STORAGE-HOST>, <DEPLOYMENT-HOST>, <NEO4J-SERVICE-ACCOUNT>, <NEO4J-SERVICE-ACCOUNT-PASSWORD>, and <NEO4J-USER> with values from your environment, and provide your Enterprise Studio license.

secrets:
  licenseKey: |          (1)
    <contents of your nes.license file>
  assetStorageCredentials:
    username: "<NEO4J-SERVICE-ACCOUNT>"
    password: "<NEO4J-SERVICE-ACCOUNT-PASSWORD>"

assetStorage:
  uri: "neo4j://<ASSET-STORAGE-HOST>:7687"
  database: tools-storage

neo4jDeployments:                 (2)
  minexample:
    name: "Minimal Example"
    uri: "http://<DEPLOYMENT-HOST>:7474"
    authorization:
      roleMapping:
        - role: studioAdmin
          members:
            - kind: databaseUser
              name: <NEO4J-USER>
            - kind: databaseRole
              name: admin
1 A valid license is required to start. The chart writes this into a Secret and mounts it at license.path (default /app/nes.license). To reference an existing Secret instead, use secretsFromSecrets.licenseKey.
2 neo4jDeployments is a map keyed by deployment id (letters and digits only). Each entry needs at least name and uri. See Configuration → Neo4j deployments for the full schema. <DEPLOYMENT-HOST> — hostname or IP of the Neo4j deployment Studio users connect to (HTTP port 7474). <NEO4J-USER> — Neo4j database user for databaseUser in role mappings.
  • <ASSET-STORAGE-HOST> — Hostname or IP of the Neo4j instance used for asset storage (Bolt port 7687).

  • <DEPLOYMENT-HOST> — Hostname or IP of the Neo4j deployment that Studio users connect to (HTTP port 7474).

  • <NEO4J-SERVICE-ACCOUNT> — Service account username for the asset storage connection.

  • <NEO4J-SERVICE-ACCOUNT-PASSWORD> — Password for the Neo4j service account used for the asset storage connection.

  • <NEO4J-USER> — Neo4j database user for databaseUser in role mappings.

After you install with the example release name my-enterprise-studio, you can reach Enterprise Studio from your machine in a local setup (without a load balancer or ingress) by port-forwarding the HTTP service and opening the app in your browser:

kubectl port-forward svc/my-enterprise-studio-http 8080:80

Open http://localhost:8080 in your browser while the port-forward command is running.

Install

helm install my-enterprise-studio \
  enterprise-studio/neo4j-enterprise-studio \
  --version '<VERSION>' \
  --values values.yaml

Verify the release is running:

kubectl get pods -l app.kubernetes.io/instance=my-enterprise-studio

Ensure the service my-enterprise-studio-http on port 80 is reachable from outside the cluster.

Upgrade

To upgrade to a new version or apply configuration changes:

helm upgrade my-enterprise-studio \
  enterprise-studio/neo4j-enterprise-studio \
  --version '<VERSION>' \
  --values values.yaml

To roll back to the previous release:

helm rollback my-enterprise-studio

Uninstall

helm uninstall my-enterprise-studio

This removes all Kubernetes resources created by the chart. It does not delete the asset storage database or any data in Neo4j.

Managing secrets

For production, do not store credentials in values.yaml. Use pre-created Kubernetes Secrets and reference them via secretsFromSecrets.

Using external Secrets

Reference existing Secrets by name:

secretsFromSecrets:
  assetStorageCredentials: "nes-storage"  (1)
  tlsSecretName: "nes-tls"               (2)
1 Name of a kubernetes.io/basic-auth Secret containing username and password keys.
2 Name of a kubernetes.io/tls Secret (e.g. from cert-manager) containing tls.crt and tls.key.

Chart behavior with external Secrets

  • Asset storage: When secretsFromSecrets.assetStorageCredentials is set, the chart does not create its own credentials Secret; the Deployment references your Secret directly.

  • TLS: When secretsFromSecrets.tlsSecretName is set, the chart uses that existing TLS Secret for Ingress or in-pod HTTPS (depending on your TLS configuration). The inline secrets.ingressTlsCert/secrets.ingressTlsKey values are ignored.

Install-time alternatives

If Helm lookup is disabled in your environment, inject secrets at install time:

helm install my-enterprise-studio \
  enterprise-studio/neo4j-enterprise-studio \
  --version '<VERSION>' \
  --values values.yaml \
  --set secrets.assetStorageCredentials.password="$(kubectl get secret nes-storage -o jsonpath='{.data.password}' | base64 -d)" \
  --set-file secrets.ingressTlsCert=./certs/tls.crt \
  --set-file secrets.ingressTlsKey=./certs/tls.key

Ingress and inbound TLS

Enterprise Studio supports two inbound TLS termination models (browser → Enterprise Studio):

  • Ingress-terminated TLS: the Ingress controller handles TLS; the pod serves plain HTTP.

  • In-pod TLS (SSL passthrough): the pod terminates TLS; the Ingress just forwards encrypted traffic.

These configure Enterprise Studio as an HTTPS server only (server.https.enabled, server.https.certificates.*). They do not affect outbound trust when Enterprise Studio calls Neo4j. See Outbound TLS trust (private CAs) for private CA trust to Neo4j backends.

Ingress-terminated TLS

The Ingress controller handles TLS decryption. The pod serves HTTP on server.port (default 8080). Set ingress.httpHostName to the hostname clients use to reach Enterprise Studio.

ingress:
  enabled: true
  sslPassthrough: false
  ingressClassName: nginx
  httpHostName: studio.example.com
  annotations: {}

server:
  https:
    enabled: false

# Provide cert inline or via secretsFromSecrets
secrets:
  ingressTlsCert: '<PEM certificate>'
  ingressTlsKey: '<PEM private key>'

For cert-manager, set secretsFromSecrets.ingressTlsCert.secretName to your kubernetes.io/tls Secret instead of inline PEM strings.

Use ingress.annotations to customize the Ingress controller (for example, nginx-specific settings like proxy timeouts or body size limits).

In-pod TLS (SSL passthrough)

The pod terminates TLS directly. Use this with a LoadBalancer Service, port-forwarding, or an Ingress with SSL passthrough.

server:
  https:
    enabled: true
    certificates:
      baseDirectory: certificates/https
      privateKey: private.key
      publicCertificate: public.crt

ingress:
  enabled: true
  sslPassthrough: true
  ingressClassName: nginx
  httpHostName: studio.example.com

secrets:
  httpsTlsCert: '<PEM certificate>'
  httpsTlsKey: '<unencrypted PKCS#8 private key>'

The nginx Ingress controller requires SSL passthrough to be enabled on the controller (e.g. controller.extraArgs.enable-ssl-passthrough).

In-pod TLS without Ingress (LoadBalancer)

If you do not need Ingress and want to expose Enterprise Studio directly via a LoadBalancer:

server:
  https:
    enabled: true
    certificates:
      baseDirectory: certificates/https
      privateKey: private.key
      publicCertificate: public.crt

secrets:
  httpsTlsCert: '<PEM certificate>'
  httpsTlsKey: '<unencrypted PKCS#8 private key>'

ingress:
  enabled: false

service:
  http:
    type: LoadBalancer

The chart mounts the certificate and key at /app/certificates/https as public.crt and private.key.

For certificate format and key requirements, see Security → TLS encryption.

Outbound TLS trust (private CAs)

When Enterprise Studio connects to Neo4j over HTTPS or Bolt+TLS, it uses the system trust store inside the pod (/etc/ssl/certs). There is no Enterprise Studio configuration setting for outbound TLS trust — install upstream CAs in the pod where Enterprise Studio runs. Host OS trust does not apply inside Kubernetes pods.

Use this when:

  • deployments.*.uri uses https:// with a private or self-signed CA

  • assetStorage.uri uses neo4j+s:// with a private CA

Outbound pod trust is independent of inbound TLS. If TLS terminates at Ingress and Enterprise Studio serves HTTP in-pod, outbound trust is still required for HTTPS Neo4j backends and neo4j+s:// asset storage.

The Helm chart (0.2.1 and later) mounts a trusted upstream CA at /etc/ssl/certs/ca.crt in the Enterprise Studio pod when either value below is set.

Helm value Description

secrets.trustedCaCert

PEM-encoded upstream CA; the chart creates an Opaque Secret and mounts it in the pod

secretsFromSecrets.trustedCaCert

Reference an existing Secret (secretName and key; default key ca.crt)

Inline CA at install time

Pass the CA file when installing or upgrading:

helm upgrade --install my-enterprise-studio \
  enterprise-studio/neo4j-enterprise-studio \
  --version '<VERSION>' \
  --values values.yaml \
  --set-file secrets.trustedCaCert=./ca.crt

Or embed the PEM in values.yaml:

secrets:
  trustedCaCert: |
    -----BEGIN CERTIFICATE-----
    ...
    -----END CERTIFICATE-----

Reference an existing Secret

For production, create the CA Secret separately and reference it by name:

secretsFromSecrets:
  trustedCaCert:
    secretName: neo4j-ca
    key: ca.crt

See Security → TLS encryption for the trust model. See Docker deployment for the equivalent procedure with docker run.

Setting up a new Neo4j instance for asset storage

If you don’t have an existing Neo4j instance for asset storage, you can deploy one alongside Enterprise Studio:

helm install nes-asset-storage neo4j/neo4j \
  --set neo4j.name=nes-asset-storage \
  --set neo4j.password=changeme \
  --set neo4j.edition=enterprise \
  --set neo4j.acceptLicenseAgreement=yes \
  --set volumes.data.mode=defaultStorageClass

Find the cluster IP:

kubectl get svc nes-asset-storage

Then use that IP in your values.yaml:

assetStorage:
  uri: "neo4j://<CLUSTER-IP>:7687"
  database: tools-storage

Health probes

Enterprise Studio exposes a GET /health endpoint that returns 200 OK when the server is running. It does not verify backend connectivity (for example to the asset storage database).

Running multiple replicas

Enterprise Studio is stateless (see Architecture → Scalability and high availability). The Helm chart supports horizontal pod autoscaling. To configure it, set the hpa values in your values.yaml:

hpa:
  spec:
    targetCPUUtilizationPercentage: 70
    maxReplicas: 2