Deploying Apicurio Registry using the Operator

Understanding Apicurio Registry Operator deployment

The Apicurio Registry Operator installs the ApicurioRegistry3 custom resource defintion (CRD). You use the ApicurioRegistry3 CR to deploy and manage Apicurio Registry instances on Kubernetes. The custom resource allows you to declaratively configure all aspects of your Apicurio Registry deployment, including storage, authentication, networking, and component-specific settings.

Additional ApicurioRegistry3 custom resource examples can be found in the Apicurio Registry upstream repository.

Custom resource structure

The ApicurioRegistry3 custom resource is organized into two main components:

  • spec.app - Configures the Apicurio Registry backend (REST API) component

  • spec.ui - Configures the Apicurio Registry web console component

Each component can be independently configured with its own settings for replicas, ingress, environment variables, and pod specifications.

Storage options

Apicurio Registry supports three storage options:

  • In-memory (default) - Stores data in memory. Suitable for development and testing only. Data is lost when the pod restarts.

  • PostgreSQL - Stores data in a PostgreSQL database. Suitable for production deployments.

  • MySQL - Stores data in a MySQL database. Suitable for production deployments.

  • KafkaSQL - Stores data in Apache Kafka topics with an in-memory cache. Suitable for production deployments when configured with persistent Kafka storage.

The default in-memory storage is not suitable for production environments.

Deploying Apicurio Registry with in-memory storage

This section shows how to deploy a basic Apicurio Registry instance using in-memory storage. This configuration is suitable for development and testing environments only.

Prerequisites
Procedure
  1. In the Kubernetes web console, log in using an account with cluster administrator privileges.

  2. Change to the namespace in which the Apicurio Registry Operator is installed. For example, from the Project drop-down, select my-project.

  3. Click Installed Operators > Apicurio Registry > ApicurioRegistry3 > Create ApicurioRegistry3.

  4. Paste in the following custom resource definition:

    apiVersion: registry.apicur.io/v1
    kind: ApicurioRegistry3
    metadata:
      name: example-registry
    spec:
      app:
        ingress:
          host: registry.example.com
      ui:
        ingress:
          host: registry-ui.example.com
    Replace the host values with appropriate hostnames for your environment. Currently, Apicurio Registry Operator only creates simple HTTP Ingresses. To enable TLS, you must create your own Ingress or Route resources with TLS configuration.
  5. Click Create and wait for the Apicurio Registry deployment to be created.

  6. Click Networking > Ingresses (or Routes) to access the route for the Apicurio Registry web console.

Verification
  • Access the Apicurio Registry web console using the configured hostname and verify that the UI loads successfully.

Deploying Apicurio Registry with PostgreSQL storage

This section explains how to deploy Apicurio Registry with PostgreSQL database storage. This configuration is suitable for production environments.

Prerequisites
  • You must have cluster administrator access to an Kubernetes cluster.

  • You must have already installed the Apicurio Registry Operator. See Installing Apicurio Registry on OpenShift.

  • You must have a PostgreSQL database available with a database created for Apicurio Registry.

  • You must have created a Kubernetes Secret containing the PostgreSQL database password.

Procedure
  1. Create a Secret containing the database password:

    apiVersion: v1
    kind: Secret
    metadata:
      name: postgresql-credentials
    type: Opaque
    stringData:
      password: your-database-password
  2. In the Kubernetes web console, click Installed Operators > Apicurio Registry > ApicurioRegistry3 > Create ApicurioRegistry3.

  3. Paste in the following custom resource definition, adjusting the values for your environment:

    apiVersion: registry.apicur.io/v1
    kind: ApicurioRegistry3
    metadata:
      name: example-registry-postgresql
    spec:
      app:
        storage:
          type: postgresql
          sql:
            dataSource:
              url: jdbc:postgresql://postgresql.my-project.svc:5432/registry
              username: registry_user
              password:
                name: postgresql-credentials
                key: password
        ingress:
          host: registry.example.com
      ui:
        ingress:
          host: registry-ui.example.com
    Update the url to match your PostgreSQL service name, namespace, port, and database name. Update the username to match your database user.
  4. Click Create and wait for the Apicurio Registry deployment to be created.

Verification
  • Access the Apicurio Registry web console and create a test artifact to verify that data is being persisted to the database.

  • Restart the Apicurio Registry pod and verify that the artifact still exists, confirming that data is persisted.

Additional resources

Deploying Apicurio Registry with MySQL storage

This section explains how to deploy Apicurio Registry with MySQL database storage. This configuration is suitable for production environments.

Prerequisites
  • You must have cluster administrator access to an Kubernetes cluster.

  • You must have already installed the Apicurio Registry Operator. See Installing Apicurio Registry on OpenShift.

  • You must have a MySQL database available with a database created for Apicurio Registry.

  • You must have created a Kubernetes Secret containing the MySQL database password.

Procedure
  1. Create a Secret containing the database password:

    apiVersion: v1
    kind: Secret
    metadata:
      name: mysql-credentials
    type: Opaque
    stringData:
      password: your-database-password
  2. In the Kubernetes web console, click Installed Operators > Apicurio Registry > ApicurioRegistry3 > Create ApicurioRegistry3.

  3. Paste in the following custom resource definition, adjusting the values for your environment:

    apiVersion: registry.apicur.io/v1
    kind: ApicurioRegistry3
    metadata:
      name: example-registry-mysql
    spec:
      app:
        storage:
          type: mysql
          sql:
            dataSource:
              url: jdbc:mysql://mysql.my-project.svc:3306/registry
              username: registry_user
              password:
                name: mysql-credentials
                key: password
        ingress:
          host: registry.example.com
      ui:
        ingress:
          host: registry-ui.example.com
    Update the url to match your MySQL service name, namespace, port, and database name. Update the username to match your database user.
  4. Click Create and wait for the Apicurio Registry deployment to be created.

Verification
  • Access the Apicurio Registry web console and create a test artifact to verify that data is being persisted to the database.

  • Restart the Apicurio Registry pod and verify that the artifact still exists, confirming that data is persisted.

Deploying Apicurio Registry with KafkaSQL storage

This section explains how to deploy Apicurio Registry with KafkaSQL storage. KafkaSQL uses Apache Kafka as the primary data store with an in-memory H2 database for caching. This configuration is suitable for production environments when using persistent Kafka storage.

Prerequisites
Procedure
  1. Obtain the Kafka bootstrap servers address from your Kafka cluster. For example, with Strimzi: my-cluster-kafka-bootstrap.my-project.svc:9092

  2. In the Kubernetes web console, click Installed Operators > Apicurio Registry > ApicurioRegistry3 > Create ApicurioRegistry3.

  3. Paste in the following custom resource definition, adjusting the bootstrapServers value:

    apiVersion: registry.apicur.io/v1
    kind: ApicurioRegistry3
    metadata:
      name: example-registry-kafkasql
    spec:
      app:
        storage:
          type: kafkasql
          kafkasql:
            bootstrapServers: my-cluster-kafka-bootstrap.my-project.svc:9092
        ingress:
          host: registry.example.com
      ui:
        ingress:
          host: registry-ui.example.com
  4. Click Create and wait for the Apicurio Registry deployment to be created.

  5. If using Strimzi, configure the Kafka topic that Apicurio Registry uses (named kafkasql-journal by default) with delete cleanup policy and infinite retention:

    apiVersion: kafka.strimzi.io/v1beta2
    kind: KafkaTopic
    metadata:
      name: kafkasql-journal
      labels:
        strimzi.io/cluster: my-cluster
    spec:
      partitions: 3
      replicas: 3
      config:
        cleanup.policy: delete
        retention.ms: -1
        retention.bytes: -1
    You must configure the Kafka topic used by Apicurio Registry with cleanup.policy: delete and infinite retention (retention.ms: -1 and retention.bytes: -1), otherwise data loss might occur.
Verification
  • Access the Apicurio Registry web console and create a test artifact to verify that data is being persisted to Kafka.

  • Restart the Apicurio Registry pod and verify that the artifact still exists after the cache is rebuilt from Kafka.

Configuring KafkaSQL with TLS

When your Kafka cluster requires TLS encryption, you can configure Apicurio Registry to connect securely:

apiVersion: registry.apicur.io/v1
kind: ApicurioRegistry3
metadata:
  name: example-registry-kafkasql-tls
spec:
  app:
    storage:
      type: kafkasql
      kafkasql:
        bootstrapServers: my-cluster-kafka-bootstrap.my-project.svc:9093
        tls:
          truststoreSecretRef:
            name: kafka-cluster-ca-cert
            key: ca.p12
          truststorePasswordSecretRef:
            name: kafka-cluster-ca-cert
            key: ca.password
    ingress:
      host: registry.example.com
The Secret containing the Kafka cluster CA certificate must be in PKCS12 format.

Configuring KafkaSQL with SASL authentication

When your Kafka cluster requires SASL authentication (such as SCRAM-SHA-512), you can configure Apicurio Registry accordingly:

apiVersion: registry.apicur.io/v1
kind: ApicurioRegistry3
metadata:
  name: example-registry-kafkasql-sasl
spec:
  app:
    storage:
      type: kafkasql
      kafkasql:
        bootstrapServers: my-cluster-kafka-bootstrap.my-project.svc:9093
        auth:
          mechanism: SCRAM-SHA-512
          usernameSecretRef:
            name: kafka-credentials
            key: username
          passwordSecretRef:
            name: kafka-credentials
            key: password
    ingress:
      host: registry.example.com
Additional resources

Configuring authentication and authorization

This section explains how to configure Apicurio Registry with OIDC authentication and role-based authorization using an identity provider such as Keycloak.

Prerequisites
  • You must have cluster administrator access to an Kubernetes cluster.

  • You must have already deployed Apicurio Registry. See Deploying Apicurio Registry with in-memory storage.

  • You must have an OIDC identity provider configured with appropriate clients for Apicurio Registry.

Procedure
  1. Configure two clients in your identity provider:

    • Backend API client (e.g., registry-client-api) - Used by the Apicurio Registry backend (REST API) component.

    • UI client (e.g., registry-client-ui) - Used by the Apicurio Registry web console component.

  2. Update your ApicurioRegistry3 custom resource to enable authentication:

    apiVersion: registry.apicur.io/v1
    kind: ApicurioRegistry3
    metadata:
      name: example-registry
    spec:
      app:
        auth:
          enabled: true
          appClientId: registry-client-api
          uiClientId: registry-client-ui
          authServerUrl: https://keycloak.example.com/realms/registry
          redirectUri: https://registry-ui.example.com
          logoutUrl: https://registry-ui.example.com
        ingress:
          host: registry.example.com
      ui:
        ingress:
          host: registry-ui.example.com
  3. To enable role-based authorization, add the authz configuration:

    spec:
      app:
        auth:
          enabled: true
          appClientId: registry-client-api
          uiClientId: registry-client-ui
          authServerUrl: https://keycloak.example.com/realms/registry
          redirectUri: https://registry-ui.example.com
          logoutUrl: https://registry-ui.example.com
          authz:
            enabled: true
            ownerOnlyEnabled: true
            roles:
              source: token
              admin: sr-admin
              developer: sr-developer
              readOnly: sr-readonly
        ingress:
          host: registry.example.com
  4. To enable admin override functionality:

    spec:
      app:
        auth:
          authz:
            enabled: true
            ownerOnlyEnabled: true
            adminOverride:
              enabled: true
              from: token
              type: role
              role: sr-admin
  5. To allow anonymous read-only access:

    spec:
      app:
        auth:
          enabled: true
          anonymousReadsEnabled: true
          appClientId: registry-client-api
          # ... other auth settings
Verification
  • Access the Apicurio Registry web console and verify that you are redirected to the identity provider login page.

  • Log in with different users having different roles and verify that authorization is enforced correctly.

Configuring basic authentication for client credentials

To enable HTTP basic authentication for client credentials flow (useful for service accounts):

spec:
  app:
    auth:
      enabled: true
      appClientId: registry-client-api
      authServerUrl: https://keycloak.example.com/realms/registry
      basicAuth:
        enabled: true
        cacheExpiration: 25m

Configuring TLS for OIDC connections

When your identity provider uses custom certificates, configure TLS verification:

spec:
  app:
    auth:
      enabled: true
      appClientId: registry-client-api
      authServerUrl: https://keycloak.example.com/realms/registry
      tls:
        tlsVerificationType: all
        truststoreSecretRef:
          name: keycloak-ca-cert
          key: ca.p12
        truststorePasswordSecretRef:
          name: keycloak-ca-cert
          key: ca.password
Set tlsVerificationType to none to disable TLS verification (not recommended for production).
Additional resources

Configuring Ingress and networking

This section explains how to configure Ingress resources and networking for Apicurio Registry components.

Configuring Ingress hostname and class

You can specify the Ingress hostname and IngressClass for each component:

apiVersion: registry.apicur.io/v1
kind: ApicurioRegistry3
metadata:
  name: example-registry
spec:
  app:
    ingress:
      host: registry-api.example.com
      ingressClassName: nginx
      annotations:
        nginx.org/proxy-connect-timeout: "30s"
  ui:
    ingress:
      host: registry-ui.example.com
      ingressClassName: nginx
      annotations:
        nginx.org/proxy-connect-timeout: "30s"

Disabling operator-managed Ingress

If you want to manage Ingress resources manually:

spec:
  app:
    ingress:
      enabled: false
  ui:
    ingress:
      enabled: false
When Ingress is disabled, you must create your own Ingress or Route resources to expose the Apicurio Registry services.

Configuring NetworkPolicy

The operator creates NetworkPolicy resources by default. To manage NetworkPolicy manually:

spec:
  app:
    networkPolicy:
      enabled: false
  ui:
    networkPolicy:
      enabled: false

Configuring Apicurio Registry features

This section explains how to enable optional features in Apicurio Registry.

Enabling resource deletion

By default, artifacts and groups in Apicurio Registry are immutable and cannot be deleted. To enable deletion:

apiVersion: registry.apicur.io/v1
kind: ApicurioRegistry3
metadata:
  name: example-registry
spec:
  app:
    features:
      resourceDeleteEnabled: true

Enabling artifact version mutability

By default, artifact versions are immutable once created. To allow draft versions to be mutable:

spec:
  app:
    features:
      versionMutabilityEnabled: true
Enabling version mutability also unlocks Studio functionality in the Apicurio Registry UI.

Configuring the UI component

This section explains how to configure the Apicurio Registry web console component.

Disabling the UI component

If you only need the REST API and don’t want to deploy the UI:

apiVersion: registry.apicur.io/v1
kind: ApicurioRegistry3
metadata:
  name: example-registry
spec:
  app:
    ingress:
      host: registry.example.com
  ui:
    enabled: false

Configuring UI environment variables

You can configure the UI with environment variables:

spec:
  ui:
    env:
      - name: REGISTRY_API_URL
        value: https://registry.example.com/apis/registry/v3
    ingress:
      host: registry-ui.example.com

Advanced configuration

This section covers advanced configuration options for Apicurio Registry.

Configuring replicas

You can configure the number of replicas for each component:

apiVersion: registry.apicur.io/v1
kind: ApicurioRegistry3
metadata:
  name: example-registry
spec:
  app:
    replicas: 3
    ingress:
      host: registry.example.com
  ui:
    replicas: 2
    ingress:
      host: registry-ui.example.com

Configuring PodDisruptionBudget

The operator creates PodDisruptionBudget resources by default. To manage PodDisruptionBudget manually:

spec:
  app:
    podDisruptionBudget:
      enabled: false
  ui:
    podDisruptionBudget:
      enabled: false

Configuring environment variables

You can add custom environment variables to Apicurio Registry components:

spec:
  app:
    env:
      - name: QUARKUS_LOG_LEVEL
        value: DEBUG
      - name: CUSTOM_CONFIG
        valueFrom:
          configMapKeyRef:
            name: my-config
            key: custom.value
Order of evaluation: The environment variables defined in the env field override any environment variables set by the operator. This allows you to customize configuration and provide workarounds in case of bugs while still benefiting from operator-managed settings. You should not use the custom PodTemplateSpec method described below to set environment variables.

Using PodTemplateSpec for advanced customization

For advanced pod configuration, you can provide a custom PodTemplateSpec:

spec:
  app:
    podTemplateSpec:
      metadata:
        labels:
          custom-label: custom-value
        annotations:
          custom-annotation: custom-value
      spec:
        containers:
          - name: apicurio-registry-app
            resources:
              requests:
                memory: "512Mi"
                cpu: "500m"
              limits:
                memory: "1Gi"
                cpu: "1000m"
        affinity:
          podAntiAffinity:
            preferredDuringSchedulingIgnoredDuringExecution:
              - weight: 100
                podAffinityTerm:
                  labelSelector:
                    matchExpressions:
                      - key: app
                        operator: In
                        values:
                          - apicurio-registry
                  topologyKey: kubernetes.io/hostname

To customize the component container (for example, to set resource requests/limits), you must specify the container name as follows:

  • apicurio-registry-app for the Apicurio Registry backend (REST API) component.

  • apicurio-registry-ui for the Apicurio Registry web console component.

However, you can also add additional containers to the pod if needed.

Order of evaluation: The operator first extends the provided PodTemplateSpec with default values and then applies additional configuration based on other fields in the ApicurioRegistry3 CR. Therefore, other configuration fields might override settings in the PodTemplateSpec.

Configuring TLS for the application

To configure TLS certificates for the Apicurio Registry application:

spec:
  app:
    tls:
      keystoreSecretRef:
        name: registry-tls
        key: keystore.p12
      keystorePasswordSecretRef:
        name: registry-tls
        key: keystore.password
Additional resources