<a id="gateway-deploy-docker"></a>

# Configure and Deploy Confluent Cloud Gateway

This guide provides instructions for configuring and deploying Confluent Cloud Gateway
(Confluent Gateway) using Docker.

Confluent Gateway runs as a stateless service, often as a set of containerized
instances within the target environment (for example, Confluent for Kubernetes, VM clusters, or
cloud-native platforms).

A separate guide is provided for the security-related tasks. See
[Configure Security for Confluent Cloud Gateway](gateway-security.md#gateway-security):

* Configure secret stores
* Configure TLS/SSL
* Configure passwords
* Configure authentication swapping

Confluent Gateway supports deployment on-premises, in private cloud VPCs, or in hybrid
environments.

The high-level steps to deploy Confluent Gateway are:

1. [Configure Confluent Gateway](#gateway-config-using-docker) to connect
   to Kafka clusters.

   Additionally, [Configure security](gateway-security.md#gateway-security-docker) for the
   Confluent Gateway to specify authentication, routing policies, and security policies
   according to your organizational needs.
2. [Provision the Confluent Gateway service](#gateway-install-with-docker)
   using the configuration settings from the previous step.
3. Reconfigure clients to communicate with the Confluent Gateway endpoint.

   This simplifies credential management and strengthens overall
   security posture.

<a id="gateway-config-using-docker"></a>

## Configure Confluent Gateway using Docker Compose

Provide the following configuration settings in a Docker Compose YAML
file. `docker-compose.yaml` is used as an example in this guide.

The top-level layout for the Confluent Gateway configuration file is as follows:

```yaml
gateway:
  image:                  --- [1]
  name:                   --- [2]
  streamingDomains: []    --- [3]
  secretStores: []        --- [4]
  routes: []              --- [5]
  admin: {}               --- [6]
  advanced: {}            --- [7]
```

* [1] The Gateway Docker image in the pattern:
  `confluentinc/confluent-gateway-for-cloud:<version-tag>`. `<version-tag>`
  is the Confluent Gateway version. For example, set to
  `confluentinc/confluent-gateway-for-cloud:1.1.0` to install version 1.1.0 of
  the Confluent Gateway.
* [2] The Gateway instance identifier.
* [3] A list of streaming domains that represent Kafka clusters. For details,
  see [Streaming domains configuration](#gateway-config-streaming-domains-docker).
* [4] A list of credential stores. Required for authentication swapping.
  For details, see [Secret store configuration](gateway-security.md#gateway-secret-stores-docker).
* [5] A list of client routing rules. For details, see
  [Routes configuration](#gateway-config-routes-docker).
* [6] Admin and metrics configuration. For details, see
  [Administration and metrics configuration](#gateway-config-admin-metrics-docker).
* [7] Advanced settings.

<a id="gateway-config-streaming-domains-docker"></a>

### Streaming domains configuration

Streaming domains are logical representations of your Kafka clusters in
Confluent Gateway.

```yaml
gateway:
  streamingDomains:
    - name:               --- [1]
      type:               --- [2]
      kafkaCluster:       --- [3]
        name:             --- [4]
        bootstrapServers: --- [5]
          - id:           --- [6]
            endpoint:     --- [7]
            ssl:          --- [8]
        nodeIdRanges:     --- [9]
          - name:         --- [10]
            start:        --- [11]
            end:          --- [12]
```

* [1] A unique name for the streaming domain.
* [2] The type of the streaming domain. Set to `kafka` by default.
* [3] A Kafka cluster, including Confluent Server, Confluent Cloud Kafka, or Apache Kafka®, that the
  Confluent Gateway can route traffic to.
* [4] The name of the Kafka cluster.
* [5] A list of Kafka bootstrap servers in the format `host:port`. At minimum,
  one bootstrap server is required per Kafka cluster. For each listener, one can
  define one bootstrap server.
* [6] A unique identifier for the bootstrap-server. Recommended to use the
  protocol, such as `SASL_PLAINTEXT`, `SSL` or `PLAINTEXT_SASL_PLAIN` for
  clear distinction between both TLS channel type and SASL mechanism.
* [7] The bootstrap endpoint of the Kafka broker in the format,
  `protocol://host:port`
* [8] Only required for SSL/SASL_SSL configuration.

  See the [SSL configuration](gateway-security.md#gateway-ssl-docker) section for details.
* [9] The node ID ranges. Only required for port-based broker identification.
  These should be the broker IDs defined in the Kafka deployment.
* [10] The name of the node ID range.
* [11] The start of the node ID range, inclusive.
* [12] The end of the node ID range, inclusive.

An example configuration for a Confluent Gateway streaming domain:

```yaml
gateway:
  streamingDomains:
    - name: sales # unique across gateway
      type: kafka # default: kafka
      kafkaCluster:
        name: sales-cluster # default: <streamingDomain.name>
        bootstrapServers:
          - id: PLAINTEXT-1
            endpoint: kafka0.example.com:9092
          - id: SASL_SSL-1
            endpoint: kafka0.example.com:9093
            ssl:  # required when using SASL_SSL/SSL
              ignoreTrust: false
              truststore:
                type: PKCS12  # default: JKS
                location: /opt/ssl/client-truststore.p12
                password:
                  file: /opt/secrets/client-truststore.password
              keystore: # gateway's identity when needed
                type: PKCS12 # default: JKS
                location: /opt/ssl/gw-keystore.p12
                password:
                  file: /opt/secrets/gw-keystore.password
                keyPassword:
                  value: inline-password
        nodeIdRanges:
          - name: default
            start: 0              # inclusive
            end: 3                # inclusive
```

- `password` can be a file path or an inline value.
- `ignoreTrust` is used to skip certificate validation (not recommended for
  production). Other settings are ignored if `ignoreTrust` is true

<a id="gateway-config-routes-docker"></a>

### Routes configuration

Routes are Confluent Gateway endpoints where clients connect to stream
data.

Confluent Gateway uses routes to define how clients connect to Kafka
clusters. Clients connect to the Gateway as if it were a Kafka cluster, while the
Gateway handles routing and governance.

```yaml
gateway:
  routes:
    - name:                         --- [1]
      endpoint:                     --- [2]
      brokerIdentificationStrategy: --- [3]
        type:                       --- [4]
        pattern:                    --- [5]
      streamingDomain:              --- [6]
        name:                       --- [7]
        bootstrapServerId:          --- [8]
      security:                     --- [9]
      fence:                        --- [10]
```

* [1] The unique name for the route.
* [2] The `host:port` combination that Confluent Gateway listens on. This is
  the external address clients use to bootstrap to the Kafka cluster.
* [3] Specifies the strategy for mapping client requests to a specific Kafka
  broker.
* [4] The type of broker identification strategy. Set to `port` (default) or
  `host`.
  * `port` strategy: Each Kafka broker is identified using a unique port
    number. This is the default strategy.

    Clients connect to different ports to reach specific brokers (for example,
    port 9092 to connect with broker-0, port 9093 to connect with broker-1).

    The `nodeIdRanges` for the streaming domain you set in
    [Streaming domains configuration](#gateway-config-streaming-domains-docker) is used.

    `nodeIdRanges` should be present in all clusters associated
    with route’s streaming domain.
  * `host` strategy: Each Kafka broker is represented using a unique hostname.

    Clients use different host names to reach specific brokers (for
    example, `broker-0.kafka.company.com`,
    `broker-1.kafka.company.com`), and the gateway routes based on the
    SNI header.

    The `pattern` setting ([5]) is used.
* [5] The pattern for the broker identification strategy. Required if the type
  ([4]) is `host`. For example,
  `broker-$(nodeId).eu-gw.sales.example.com:9092`.
* [6] The reference to a streaming domain.
* [7] The name of the streaming domain. Must be a valid name from the
  `gateway.streamingDomains[].name`.
* [8] The bootstrap server ID. Must match
  `kafkaCluster.bootstrapServers[].id`.
* [9] The security configuration. For details, see the
  [Configure Security for Confluent Cloud Gateway](gateway-security.md#gateway-security-docker) section.
* [10] Optional. The fencing filter configuration. For more information,
  see [Fencing filter](#gateway-config-fencing-docker).

An example configuration for Confluent Gateway routes:

```yaml
gateway:
 routes:
   - name: eu-sales
     endpoint: eu-gw.sales.example.com:9092
     brokerIdentificationStrategy:
       type: host
       pattern: broker-$(nodeId).eu-gw.sales.example.com:9092
     streamingDomain:
       name: sales
       bootstrapServerId: SASL_SSL-1
```

### Route filters configuration

Filters allow you to control and manage traffic flow for specific routes in
Confluent Gateway. You can apply filters at the route level to enforce policies, block
or allow requests, and customize error handling for different scenarios.

<a id="gateway-config-fencing-docker"></a>

#### Fencing filter

The fencing filter in Confluent Gateway is a route-level filter that allows you
to control the traffic flow on a specific route. It supports two fencing
scopes:

* `ALL`: Blocks all requests on the specified route. This is useful
  for scenarios such as maintenance windows or when you want to
  temporarily disable access to a route.
* `NONE`: Allows all requests on the specified route.

```yaml
gateway:
  routes:
    - name:
      fence:
        scope:          --- [1]
        errorCode:      --- [2]
        errorMessage:   --- [3]
```

* [1] The fencing scope of the filter. The default value is `NONE`.
  Set to `ALL` to block all requests on the route.
* [2] Optional. The error code to return for blocked requests. The default
  value is `BROKER_NOT_AVAILABLE`.

  For a list of valid error codes, see [Kafka protocol error codes](https://kafka.apache.org/42/design/protocol/#error-codes).
* [3] Optional. The error message to return for blocked requests. The default
  value is `This route is currently unavailable - all requests are blocked.`

  Some Kafka protocol APIs such as `ApiVersions` do not include a message
  field in their error response schema. For these APIs, Confluent Gateway can’t
  return custom `errorMessage` strings to the client, and blocked
  requests might appear as generic connection or handshake failures rather
  than the configured error.

The following is an example configuration for a Confluent Gateway route with the
fencing filter enabled:

```yaml
gateway:
  routes:
    - name: eu-sales
      endpoint: eu-gw.sales.example.com:9092
      fence:
        scope: ALL
        errorCode: BROKER_NOT_AVAILABLE
        errorMessage: "Maintenance in progress - route temporarily unavailable"
      brokerIdentificationStrategy:
        type: host
        pattern: broker-$(nodeId).eu-gw.sales.example.com:9092
      streamingDomain:
        name: sales
        bootstrapServerId: SASL_SSL-1
```

<a id="gateway-config-admin-metrics-docker"></a>

### Administration and metrics configuration

```yaml
gateway:
  admin:
    bindAddress:             --- [1]
    port:                    --- [2]
    endpoints:
      metrics:               --- [3]
    jvmMetrics:              --- [4]
      - JvmGcMetrics
      - JvmMemoryMetrics
      - JvmThreadMetrics
      - ProcessorMetrics
      - UptimeMetrics
    commonTags:              --- [5]
      host:
      region:
```

* [1] The local address to bind the admin service and to listen on for incoming
  connections. The default value is `0.0.0.0`.

  This address determines which network interfaces the gateway uses to
  expose its administrative endpoints, such as metrics and liveness checks.
* [2] The TCP port for exposing admin endpoints. The default value is `9190`.

  The Confluent Gateway serves metrics at `http://{bindAddress}:{port}/metrics`
  and liveness check at `http://{bindAddress}:{port}/livez`.
* [3] The metrics endpoints to be enabled and exposed. The default value is
  `true`.
* [4] The standard JVM Metrics (uses Micrometer classes). By default
  `JvmGcMetrics`, `JvmMemoryMetrics`, `JvmThreadMetrics`,
  `ProcessorMetrics`, `UptimeMetrics` are enabled.
* [5] Optional. The common tags to be applied to all the metrics.

An example configuration for a Confluent Gateway Admin and Metrics:

```yaml
gateway:
  admin:
    bindAddress: 0.0.0.0
    port: 9190
    endpoints:
      metrics: true
    jvmMetrics:
      - JvmGcMetrics
      - JvmMemoryMetrics
      - JvmThreadMetrics
      - ProcessorMetrics
      - UptimeMetrics
    commonTags:
      host: pod-0
      region: us-west-2
```

For a recommended set of metrics to monitor and example alerting queries,
see [Monitor Confluent Cloud Gateway Metrics](gateway-metrics-monitoring.md#gateway-metrics-monitoring).

<a id="gateway-config-license-docker"></a>

### License configuration

The table below summarizes the license modes supported by Confluent Cloud Gateway.

| Deployment mode   | Trial mode (default)                           | Enterprise mode for Confluent Cloud deployments   |
|-------------------|------------------------------------------------|---------------------------------------------------|
| License required  | No license required                            | Valid Confluent Cloud Gateway license(s)          |
| Limitation        | Maximum of 4 routes can be configured          | Supports only Confluent Cloud streaming domains   |
| Purpose           | Evaluation and testing                         | Gateway forwarding to Confluent Cloud clusters    |
| Duration          | N/A                                            | As specified in the license claim                 |
| Image             | Use `confluentinc/confluent-gateway-for-cloud` | Use `confluentinc/confluent-gateway-for-cloud`    |

Self-managed and Confluent Cloud routing require separate license grants. Trial mode
enables both features automatically. In Enterprise mode, your license key must
include both stacked grants to migrate or fail over clients from a
self-managed cluster to Confluent Cloud. For more information, see
[Migrate between Kafka Clusters using Confluent Cloud Gateway](gateway-migrate.md#gateway-client-switchover).

To configure the Enterprise license mode:

1. Contact [Confluent Support](https://support.confluent.io) to
   obtain one or more valid Confluent Cloud Gateway license keys for production
   use.
2. Configure the `GATEWAY_LICENSES` environment variable using the license
   keys you obtained in the previous step.
   * Option A: Set the environment variable before starting the Confluent Gateway.
     ```bash
     export GATEWAY_LICENSES="<your-license-key>"
     ```

     To add multiple license keys, use the following syntax using the dollar
     sign (`$`) to escape the newline character (`\n`).
     ```bash
     export GATEWAY_LICENSES=$'<your-first-license-key>\n<your-second-license-key>'
     ```
   * Option B: Edit `docker-compose.yaml`. You can add multiple
     license keys, one per line.
     ```yaml
     gateway:
       environment:
         GATEWAY_LICENSES: |
           <your-first-license-key>
           <your-second-license-key>
     ```
3. To verify the license status, inspect the Confluent Gateway logs for license
   information after starting the Confluent Gateway.
   ```bash
   docker logs gateway | grep -i license
   ```

For example license configurations, see [Confluent Gateway examples in GitHub](https://github.com/confluentinc/gateway-images/tree/master/examples/license-configuration).

After completing your configuration, save the file as `docker-compose.yaml`.
To deploy Confluent Gateway, see [Install Confluent Gateway using Docker](#gateway-install-with-docker).

<a id="gateway-install-with-docker"></a>

## Install Confluent Gateway using Docker

Deploy Confluent Gateway using the configuration file (`docker-compose.yaml` by
default) you set up in the previous section, [Configure Confluent Gateway using Docker Compose](#gateway-config-using-docker).

1. Pull the Confluent Gateway Docker image:
   ```bash
   docker pull confluentinc/confluent-gateway-for-cloud:<version-tag>
   ```

   Replace `<version-tag>` with the Confluent Gateway version you want to install.
   For example, use `1.2.0` to install version 1.2.0.
2. Start Confluent Gateway:
   ```bash
   docker compose -f docker-compose.yaml up -d
   ```
