Skip to content

Latest commit

 

History

History
150 lines (125 loc) · 4.4 KB

File metadata and controls

150 lines (125 loc) · 4.4 KB
title Deploy with Helm
description How to deploy the ToolHive Registry Server in Kubernetes using the official Helm chart

:::info

For alternative deployment approaches, see Deploy with the ToolHive Operator or Deploy manually.

:::

Prerequisites

  • A Kubernetes cluster (current and two previous minor versions are supported)
  • Permissions to create resources in the cluster
  • kubectl configured to communicate with your cluster
  • Helm v3.10 or later (v3.14+ is recommended)
  • PostgreSQL 14 or later

Overview

The official Helm chart in the toolhive-registry-server repository deploys a standalone Registry Server. Use this method when you want to manage the Registry Server like any other Helm release without installing the ToolHive Operator.

Install the chart

Install the chart from its OCI registry into the toolhive-system namespace:

helm upgrade --install registry-server \
  oci://ghcr.io/stacklok/toolhive-registry-server \
  -n toolhive-system --create-namespace \
  -f values.yaml

Configure the Registry Server

The chart's config block maps directly to the Registry Server's configuration file. Any valid configuration field can be set under config in your values file:

config:
  sources:
    - name: toolhive
      git:
        repository: https://github.com/stacklok/toolhive-catalog.git
        branch: main
        path: pkg/catalog/toolhive/data/registry-upstream.json
      syncPolicy:
        interval: '30m'
  registries:
    - name: default
      sources: ['toolhive']
  auth:
    mode: anonymous
  database:
    host: postgres
    port: 5432
    user: registry
    database: registry
    sslMode: require

Provide database credentials

Database credentials use the pgpass file pattern. Create a Kubernetes Secret with a pgpass-formatted entry under the key .pgpass, then point the chart at it with an init container that prepares the file and a PGPASSFILE environment variable that tells libpq where to find it.

The chart's main container runs with readOnlyRootFilesystem: true as the non-root UID 65535, so the init container copies the Secret into an emptyDir volume and applies 0600 permissions (libpq rejects pgpass files with wider permissions):

extraEnv:
  - name: PGPASSFILE
    value: /pgpass-prepared/.pgpass

extraVolumes:
  - name: pgpass-secret
    secret:
      secretName: registry-pgpass
      defaultMode: 0600
  - name: pgpass-prepared
    emptyDir: {}

extraVolumeMounts:
  - name: pgpass-prepared
    mountPath: /pgpass-prepared
    readOnly: true

initContainers:
  - name: pgpass-init
    image: cgr.dev/chainguard/busybox:latest
    command:
      - sh
      - -c
      - cp /pgpass-secret/.pgpass /pgpass-prepared/.pgpass && chmod 600
        /pgpass-prepared/.pgpass
    securityContext:
      allowPrivilegeEscalation: false
      capabilities:
        drop: [ALL]
      readOnlyRootFilesystem: true
      runAsNonRoot: true
      runAsUser: 65535
    volumeMounts:
      - name: pgpass-secret
        mountPath: /pgpass-secret
        readOnly: true
      - name: pgpass-prepared
        mountPath: /pgpass-prepared

The init container runs as the same UID as the main container, so the copied file is already owned by 65535 and the Registry Server can read it without a separate chown step. This matches the commented pgpass example in the chart's own values.yaml.

Next steps

Related information