include::{mod-loc}shared/all-attributes.adoc[]

// assembly-deploying-registry-operator
[id="deploying-registry-operator_{context}"]
:_mod-docs-content-type: ASSEMBLY
= Deploying {registry} using the Operator

[role="_abstract"]
Deploy and configure {registry} instances by using the {operator} on
{kubernetes}:

* xref:operator-overview_{context}[]
* xref:deploying-registry-inmemory_{context}[]
* xref:deploying-registry-postgresql_{context}[]
* xref:deploying-registry-mysql_{context}[]
* xref:deploying-registry-kafkasql_{context}[]
* xref:configuring-kafkasql-tls_{context}[]
* xref:configuring-kafkasql-sasl_{context}[]
* xref:deploying-registry-kubernetesops_{context}[]
* xref:configuring-registry-authentication_{context}[]
* xref:configuring-basic-auth-credentials_{context}[]
* xref:configuring-tls-oidc_{context}[]
* xref:configuring-ingress-hostname_{context}[]
* xref:disabling-operator-ingress_{context}[]
* xref:configuring-networkpolicy_{context}[]
* xref:enabling-resource-deletion_{context}[]
* xref:enabling-version-mutability_{context}[]
* xref:disabling-ui-component_{context}[]
* xref:configuring-ui-env-vars_{context}[]
* xref:configuring-replicas_{context}[]
* xref:configuring-poddisruptionbudget_{context}[]
* xref:configuring-env-vars_{context}[]
* xref:using-podtemplatespec_{context}[]
* xref:configuring-app-tls_{context}[]

**Prerequisites**

* {installing-the-registry-openshift}

//INCLUDES

// con-operator-overview
[id="operator-overview_{context}"]
:_mod-docs-content-type: CONCEPT
== Understanding {operator} deployment

[role="_abstract"]
The {operator} installs the `ApicurioRegistry3` custom resource definition (CRD). You use the `ApicurioRegistry3` CR to deploy and manage {registry} instances on {kubernetes}. The custom resource enables you to declaratively configure all aspects of your {registry} deployment,
including storage, authentication, networking, and component-specific settings.

NOTE: Additional `ApicurioRegistry3` custom resource examples can be found in the https://github.com/Apicurio/apicurio-registry/tree/{upstream-version-tag}/operator/controller/src/test/resources/k8s/examples[{registry} upstream repository].

The `ApicurioRegistry3` custom resource is organized into two main components:

* `spec.app` - Configures the {registry-app}
* `spec.ui` - Configures the {registry-ui}

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

// ref-operator-storage-options
[id="operator-storage-options_{context}"]
:_mod-docs-content-type: REFERENCE
== Storage options

[role="_abstract"]
{registry} supports the following storage options:

* *Embedded H2 database* (default) - When you do not specify a storage type, {registry} uses SQL storage with an embedded H2 database. Suitable for development and testing only. {registry} stores all data in memory and loses it 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 embedded H2 database as a local SQL store that {registry} rebuilds from the Kafka journal on each startup. Suitable for production deployments when you configure persistent Kafka storage.
* *KubernetesOps* - Read-only storage that loads registry data from Kubernetes ConfigMaps. Suitable for
Kubernetes-native and GitOps workflows. This is an experimental feature.

IMPORTANT: The default embedded H2 configuration is not suitable for production environments. Configure a storage type (`postgresql`, `mysql`, `kafkasql`, or `kubernetesops`) for production use.

// proc-deploying-registry-inmemory
[id="deploying-registry-inmemory_{context}"]
:_mod-docs-content-type: PROCEDURE
== Deploying {registry} with default configuration (embedded H2 database)

[role="_abstract"]
You can deploy a basic {registry} instance by using the default storage configuration (SQL with an embedded H2 database). You do not need to specify a storage type in the CR. When omitted, {registry} defaults to an embedded H2 database. This configuration is suitable for development and testing environments only.

.Prerequisites
* You must have cluster administrator access to an {kubernetes} cluster.
* You must have already installed the {operator}. See {installing-the-registry-openshift}.

.Procedure

. In the {kubernetes} web console, log in using an account with cluster administrator privileges.

. Change to the {kubernetes-namespace} in which the {operator} is installed. For example, from the
*Project* drop-down, select `my-project`.

. Click *Installed Operators* > *{registry}* > *ApicurioRegistry3* > *Create ApicurioRegistry3*.

. Paste in the following custom resource definition:
+
[source,yaml]
----
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
----
+
NOTE: Replace the `host` values with appropriate hostnames for your environment. Currently, {operator} only creates simple HTTP Ingresses. To enable TLS, you must create your own Ingress or Route resources with TLS configuration.

. Click *Create* and wait for the {registry} deployment to be created.

. Click *Networking* > *Ingresses* (or *Routes*) to access the route for the {registry} web console.

.Verification

* Access the {registry} web console using the configured hostname and verify that the UI loads successfully.

// proc-deploying-registry-postgresql
[id="deploying-registry-postgresql_{context}"]
:_mod-docs-content-type: PROCEDURE
== Deploying {registry} with PostgreSQL storage

[role="_abstract"]
Deploy {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 {operator}. See {installing-the-registry-openshift}.
* You must have a PostgreSQL database available with a database created for {registry}.
* You must have created a Kubernetes Secret containing the PostgreSQL database password.

.Procedure

. Create a Secret containing the database password:
+
[source,yaml]
----
apiVersion: v1
kind: Secret
metadata:
  name: postgresql-credentials
type: Opaque
stringData:
  password: your-database-password
----

. In the {kubernetes} web console, click *Installed Operators* > *{registry}* > *ApicurioRegistry3* >
*Create ApicurioRegistry3*.

. Paste in the following custom resource definition, adjusting the values for your environment:
+
[source,yaml]
----
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
----
+
NOTE: Update the `url` to match your PostgreSQL service name, namespace, port, and database name. Update the
`username` to match your database user.

. Click *Create* and wait for the {registry} deployment to be created.

.Verification

* Access the {registry} web console and create a test artifact to verify that data is being persisted to
the database.
* Restart the {registry} pod and verify that the artifact still exists, confirming that data is persisted.

[role="_additional-resources"]
.Additional resources

* xref:getting-started/assembly-installing-registry-storage-openshift.adoc#installing-postgresql-operatorhub_{context}[Installing a PostgreSQL database from the OpenShift OperatorHub]

// proc-deploying-registry-mysql
[id="deploying-registry-mysql_{context}"]
:_mod-docs-content-type: PROCEDURE
== Deploying {registry} with MySQL storage

[role="_abstract"]
Deploy {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 {operator}. See {installing-the-registry-openshift}.
* You must have a MySQL database available with a database created for {registry}.
* You must have created a Kubernetes Secret containing the MySQL database password.

.Procedure

. Create a Secret containing the database password:
+
[source,yaml]
----
apiVersion: v1
kind: Secret
metadata:
  name: mysql-credentials
type: Opaque
stringData:
  password: your-database-password
----

. In the {kubernetes} web console, click *Installed Operators* > *{registry}* > *ApicurioRegistry3* >
*Create ApicurioRegistry3*.

. Paste in the following custom resource definition, adjusting the values for your environment:
+
[source,yaml]
----
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
----
+
NOTE: Update the `url` to match your MySQL service name, namespace, port, and database name. Update the
`username` to match your database user.

. Click *Create* and wait for the {registry} deployment to be created.

.Verification

* Access the {registry} web console and create a test artifact to verify that data is being persisted to
the database.
* Restart the {registry} pod and verify that the artifact still exists, confirming that data is persisted.

// proc-deploying-registry-kafkasql
[id="deploying-registry-kafkasql_{context}"]
:_mod-docs-content-type: PROCEDURE
== Deploying {registry} with KafkaSQL storage

[role="_abstract"]
You can deploy {registry} with KafkaSQL storage. KafkaSQL uses Apache Kafka as the primary
data store, with an embedded H2 database as a local SQL store that {registry} rebuilds from the Kafka journal on each startup. This configuration is suitable for production environments
when you configure persistent Kafka storage.

.Prerequisites
* You must have cluster administrator access to an {kubernetes} cluster.
* You must have already installed the {operator}. See {installing-the-registry-openshift}.
* You must have a Kafka cluster available. For OpenShift, see {installing-the-registry-storage-openshift}.

.Procedure

. Obtain the Kafka bootstrap servers address from your Kafka cluster. For example, with {kafka-streams}:
`my-cluster-kafka-bootstrap.my-project.svc:9092`

. In the {kubernetes} web console, click *Installed Operators* > *{registry}* > *ApicurioRegistry3* >
*Create ApicurioRegistry3*.

. Paste in the following custom resource definition, adjusting the `bootstrapServers` value:
+
[source,yaml]
----
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
----

. Click *Create* and wait for the {registry} deployment to be created.

. If using {kafka-streams}, configure the Kafka topic that {registry} uses (named `kafkasql-journal` by default)
with delete cleanup policy and infinite retention:
+
[source,yaml]
----
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
----
+
WARNING: You must configure the Kafka topic used by {registry} with `cleanup.policy: delete` and infinite retention
(`retention.ms: -1` and `retention.bytes: -1`), otherwise data loss might occur.

.Verification

* Access the {registry} web console and create a test artifact to verify that data is being persisted to Kafka.
* Restart the {registry} pod and verify that the artifact still exists after the cache is rebuilt from Kafka.

[role="_additional-resources"]
.Additional resources

* xref:getting-started/assembly-installing-registry-storage-openshift.adoc#setting-up-kafka-streams-storage_{context}[Configuring {registry} with Kafka storage on OpenShift]

// ref-configuring-kafkasql-tls
[id="configuring-kafkasql-tls_{context}"]
:_mod-docs-content-type: REFERENCE
== KafkaSQL TLS configuration

[role="_abstract"]
When your Kafka cluster requires TLS encryption, you can configure {registry} to connect securely.

[source,yaml]
----
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
----

NOTE: The Secret containing the Kafka cluster CA certificate must be in PKCS12 format.

// ref-configuring-kafkasql-sasl
[id="configuring-kafkasql-sasl_{context}"]
:_mod-docs-content-type: REFERENCE
== KafkaSQL SASL authentication configuration

[role="_abstract"]
When your Kafka cluster requires SASL authentication (such as SCRAM-SHA-512), the recommended approach is to use
the Strimzi Kafka Access Operator (available starting with {registry} version 3.2.0), which automatically provides
all connection details in a single Kubernetes Secret.

[source,yaml]
----
apiVersion: registry.apicur.io/v1
kind: ApicurioRegistry3
metadata:
  name: example-registry-kafkasql-sasl
spec:
  app:
    storage:
      type: kafkasql
      kafkasql:
        kafkaAccessSecretName: my-kafka-access
    ingress:
      host: registry.example.com
----

For OAuth (OAUTHBEARER) authentication, use the `auth` section instead:

[source,yaml]
----
apiVersion: registry.apicur.io/v1
kind: ApicurioRegistry3
metadata:
  name: example-registry-kafkasql-oauth
spec:
  app:
    storage:
      type: kafkasql
      kafkasql:
        bootstrapServers: my-cluster-kafka-bootstrap.my-project.svc:9093
        tls:
          truststoreSecretRef:
            name: kafka-cluster-ca-cert
          truststorePasswordSecretRef:
            name: kafka-cluster-ca-cert
        auth:
          enabled: true
          mechanism: OAUTHBEARER
          clientIdRef:
            name: kafka-oauth-credentials
            key: clientId
          clientSecretRef:
            name: kafka-oauth-credentials
            key: clientSecret
          tokenEndpoint: https://identity-server.example.com/token
          loginHandlerClass: io.strimzi.kafka.oauth.client.JaasClientOauthLoginCallbackHandler
    ingress:
      host: registry.example.com
----

// proc-deploying-registry-kubernetesops
[id="deploying-registry-kubernetesops_{context}"]
:_mod-docs-content-type: PROCEDURE
== Deploying {registry} with KubernetesOps storage

[role="_abstract"]
Deploy {registry} with KubernetesOps storage. KubernetesOps is a read-only storage
variant that loads registry data from Kubernetes ConfigMaps, enabling Kubernetes-native and GitOps workflows for
managing schemas and APIs.

IMPORTANT: KubernetesOps storage is an *experimental* feature. You must enable the experimental features gate to use it.

.Prerequisites
* You must have cluster administrator access to an {kubernetes} cluster.
* You must have already installed the {operator}. See {installing-the-registry-openshift}.
* You must have access to create ConfigMaps and RBAC resources in your cluster.

.Procedure

. In the {kubernetes} web console, click *Installed Operators* > *{registry}* > *ApicurioRegistry3* >
*Create ApicurioRegistry3*.

. Paste in the following custom resource definition, adjusting the values for your environment:
+
[source,yaml]
----
apiVersion: registry.apicur.io/v1
kind: ApicurioRegistry3
metadata:
  name: example-registry-kubernetesops
spec:
  app:
    storage:
      type: kubernetesops
      kubernetesops:
        registryId: my-registry
        namespace: apicurio
    ingress:
      host: registry.example.com
  ui:
    ingress:
      host: registry-ui.example.com
----
+
NOTE: Replace `registryId` with a unique identifier for your registry instance, and
`namespace` with the namespace containing your ConfigMaps. The operator automatically enables
the experimental features gate required by KubernetesOps storage.

. Create the required RBAC resources (ServiceAccount, Role, RoleBinding) to grant the registry read access
to ConfigMaps. See xref:getting-started/assembly-configuring-kubernetesops-storage.adoc#kubernetesops-rbac-requirements_{context}[RBAC requirements] for details.

. Create ConfigMaps containing your registry data. See
xref:getting-started/assembly-configuring-kubernetesops-storage.adoc#kubernetesops-configmap-format_{context}[ConfigMap data format] for the required format.

. Click *Create* and wait for the {registry} deployment to be created.

.Verification

* Access the {registry} web console and verify that artifacts from your ConfigMaps are visible.
* Note that KubernetesOps storage is read-only. You cannot create, update, or delete artifacts through the
REST API or web console.

[role="_additional-resources"]
.Additional resources

* xref:getting-started/assembly-configuring-kubernetesops-storage.adoc[]

// proc-configuring-registry-authentication
[id="configuring-registry-authentication_{context}"]
:_mod-docs-content-type: PROCEDURE
== Configuring authentication and authorization

[role="_abstract"]
Configure {registry} with OIDC authentication and role-based authorization by using
an identity provider such as {keycloak}.

.Prerequisites
* You must have cluster administrator access to an {kubernetes} cluster.
* You must have already deployed {registry}. See xref:deploying-registry-inmemory_{context}[].
* You must have an OIDC identity provider configured with appropriate clients for {registry}.

.Procedure

. Configure two clients in your identity provider:
** Backend API client (for example, `registry-client-api`) - Used by the {registry-app}.
** UI client (for example, `registry-client-ui`) - Used by the {registry-ui}.

. Update your `ApicurioRegistry3` custom resource to enable authentication:
+
[source,yaml]
----
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
----

. To enable role-based authorization, add the `authz` configuration:
+
[source,yaml]
----
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
----

. To enable admin override functionality:
+
[source,yaml]
----
spec:
  app:
    auth:
      authz:
        enabled: true
        ownerOnlyEnabled: true
        adminOverride:
          enabled: true
          from: token
          type: role
          role: sr-admin
----

. To allow anonymous read-only access:
+
[source,yaml]
----
spec:
  app:
    auth:
      enabled: true
      anonymousReadsEnabled: true
      appClientId: registry-client-api
      # ... other auth settings
----

.Verification

* Access the {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.

[role="_additional-resources"]
.Additional resources

* xref:getting-started/assembly-configuring-registry-security.adoc[]

// ref-configuring-basic-auth-credentials
[id="configuring-basic-auth-credentials_{context}"]
:_mod-docs-content-type: REFERENCE
== Basic authentication for client credentials

[role="_abstract"]
To enable HTTP basic authentication for client credentials flow (useful for service accounts), add the `basicAuth` configuration to your `ApicurioRegistry3` custom resource.

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

// ref-configuring-tls-oidc
[id="configuring-tls-oidc_{context}"]
:_mod-docs-content-type: REFERENCE
== TLS configuration for OIDC connections

[role="_abstract"]
When your identity provider uses custom certificates, configure TLS verification in your `ApicurioRegistry3` custom resource.

[source,yaml]
----
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
----

NOTE: Set `tlsVerificationType` to `none` to disable TLS verification (not recommended for production).

// ref-configuring-ingress-hostname
[id="configuring-ingress-hostname_{context}"]
:_mod-docs-content-type: REFERENCE
== Ingress hostname and class configuration

[role="_abstract"]
You can specify the Ingress hostname and IngressClass for each component.

[source,yaml]
----
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"
----

// ref-disabling-operator-ingress
[id="disabling-operator-ingress_{context}"]
:_mod-docs-content-type: REFERENCE
== Disabling operator-managed Ingress

[role="_abstract"]
To manage Ingress resources manually, disable the operator-managed Ingress.

[source,yaml]
----
spec:
  app:
    ingress:
      enabled: false
  ui:
    ingress:
      enabled: false
----

NOTE: When Ingress is disabled, you must create your own Ingress or Route resources to expose the {registry}
services.

// ref-configuring-networkpolicy
[id="configuring-networkpolicy_{context}"]
:_mod-docs-content-type: REFERENCE
== NetworkPolicy configuration

[role="_abstract"]
The operator creates NetworkPolicy resources by default. To manage NetworkPolicy manually, disable the operator-managed NetworkPolicy.

[source,yaml]
----
spec:
  app:
    networkPolicy:
      enabled: false
  ui:
    networkPolicy:
      enabled: false
----

// ref-enabling-resource-deletion
[id="enabling-resource-deletion_{context}"]
:_mod-docs-content-type: REFERENCE
== Resource deletion configuration

[role="_abstract"]
By default, artifacts and groups in {registry} are immutable and cannot be deleted. To enable deletion, set the `resourceDeleteEnabled` feature flag.

[source,yaml]
----
apiVersion: registry.apicur.io/v1
kind: ApicurioRegistry3
metadata:
  name: example-registry
spec:
  app:
    features:
      resourceDeleteEnabled: true
----

// ref-enabling-version-mutability
[id="enabling-version-mutability_{context}"]
:_mod-docs-content-type: REFERENCE
== Artifact version mutability configuration

[role="_abstract"]
By default, artifact versions are immutable once created. To allow draft versions to be mutable, set the `versionMutabilityEnabled` feature flag.

[source,yaml]
----
spec:
  app:
    features:
      versionMutabilityEnabled: true
----

NOTE: Enabling version mutability also unlocks Studio functionality in the {registry} UI.

// ref-disabling-ui-component
[id="disabling-ui-component_{context}"]
:_mod-docs-content-type: REFERENCE
== Disabling the UI component

[role="_abstract"]
If you only need the REST API and do not want to deploy the UI, disable the UI component.

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

// ref-configuring-ui-env-vars
[id="configuring-ui-env-vars_{context}"]
:_mod-docs-content-type: REFERENCE
== UI environment variable configuration

[role="_abstract"]
You can configure the UI with environment variables in the `ApicurioRegistry3` custom resource.

[source,yaml]
----
spec:
  ui:
    env:
      - name: REGISTRY_API_URL
        value: https://registry.example.com/apis/registry/v3
    ingress:
      host: registry-ui.example.com
----

// ref-configuring-replicas
[id="configuring-replicas_{context}"]
:_mod-docs-content-type: REFERENCE
== Replica configuration

[role="_abstract"]
You can configure the number of replicas for each component.

[source,yaml]
----
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
----

// ref-configuring-poddisruptionbudget
[id="configuring-poddisruptionbudget_{context}"]
:_mod-docs-content-type: REFERENCE
== PodDisruptionBudget configuration

[role="_abstract"]
The operator creates PodDisruptionBudget resources by default. To manage PodDisruptionBudget manually, disable the operator-managed PodDisruptionBudget.

[source,yaml]
----
spec:
  app:
    podDisruptionBudget:
      enabled: false
  ui:
    podDisruptionBudget:
      enabled: false
----

// ref-configuring-env-vars
[id="configuring-env-vars_{context}"]
:_mod-docs-content-type: REFERENCE
== Environment variable configuration

[role="_abstract"]
You can add custom environment variables to {registry} components.

[source,yaml]
----
spec:
  app:
    env:
      - name: QUARKUS_LOG_LEVEL
        value: DEBUG
      - name: CUSTOM_CONFIG
        valueFrom:
          configMapKeyRef:
            name: my-config
            key: custom.value
----

IMPORTANT: *Order of evaluation:* The environment variables defined in the `env` field override any environment variables set by the operator. This enables you to customize configuration and provide workarounds while still benefiting from operator-managed settings. Do not use the custom PodTemplateSpec method to set environment variables.

// ref-using-podtemplatespec
[id="using-podtemplatespec_{context}"]
:_mod-docs-content-type: REFERENCE
== PodTemplateSpec advanced customization

[role="_abstract"]
For advanced pod configuration, you can provide a custom PodTemplateSpec.

[source,yaml]
----
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 {registry-app}.
* `apicurio-registry-ui` for the {registry-ui}.

You can also add additional containers to the pod if needed.

IMPORTANT: *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.

// ref-configuring-app-tls
[id="configuring-app-tls_{context}"]
:_mod-docs-content-type: REFERENCE
== Application TLS configuration

[role="_abstract"]
To configure TLS certificates for the {registry} application, provide keystore references in the `ApicurioRegistry3` custom resource.

[source,yaml]
----
spec:
  app:
    tls:
      keystoreSecretRef:
        name: registry-tls
        key: keystore.p12
      keystorePasswordSecretRef:
        name: registry-tls
        key: keystore.password
----

[role="_additional-resources"]
.Additional resources

* xref:getting-started/assembly-operator-config-reference.adoc[]
* {registry-overview}
