---
id: applications
sidebar_position: 340
title: Connecting from an application
---

# Connecting from an application
<!-- SPDX-License-Identifier: CC-BY-4.0 -->

Applications are supposed to work with the services created by CloudNativePG
in the same Kubernetes cluster.

For more information on services and how to manage them, please refer to the
["Service management"](service_management.md) section.

:::tip[Hint]
    It is highly recommended using those services in your applications,
    and avoiding connecting directly to a specific PostgreSQL instance, as the latter
    can change during the cluster lifetime.
:::

You can use these services in your applications through:

* DNS resolution
* environment variables

For the credentials to connect to PostgreSQL, you can
use the secrets generated by the operator.

:::note[Connection Pooling]
    Please refer to the ["Connection Pooling" section](connection_pooling.md) for
    information about how to take advantage of PgBouncer as a connection pooler,
    and create an access layer between your applications and the PostgreSQL clusters.
:::

### DNS resolution

You can use the Kubernetes DNS service to point to a given server.
The Kubernetes DNS service is required by the operator.
You can do that by using the name of the service if the application is
deployed in the same namespace as the PostgreSQL cluster.
In case the PostgreSQL cluster resides in a different namespace, you can use the
full qualifier: `service-name.namespace-name`.

DNS is the preferred and recommended discovery method.

### Environment variables

If you deploy your application in the same namespace that contains the
PostgreSQL cluster, you can also use environment variables to connect to the database.

For example, suppose that your PostgreSQL cluster is called `pg-database`,
you can use the following environment variables in your applications:

* `PG_DATABASE_R_SERVICE_HOST`: the IP address of the service
  pointing to all the PostgreSQL instances for read-only workloads

* `PG_DATABASE_RO_SERVICE_HOST`: the IP address of the
  service pointing to all hot-standby replicas of the cluster

* `PG_DATABASE_RW_SERVICE_HOST`: the IP address of the
  service pointing to the *primary* instance of the cluster

### Secrets

The PostgreSQL operator will generate up to two `basic-auth` type secrets for
every PostgreSQL cluster it deploys:

* `[cluster name]-app` (unless you have provided an existing secret through `.spec.bootstrap.initdb.secret.name`)
* `[cluster name]-superuser` (if `.spec.enableSuperuserAccess` is set to `true`
  and you have not specified a different secret using `.spec.superuserSecret`)

Each secret contain the following:

* username
* password
* hostname to the RW service
* port number
* database name
* a working [`.pgpass file`](https://www.postgresql.org/docs/current/libpq-pgpass.html)
* [uri](https://www.postgresql.org/docs/current/libpq-connect.html#LIBPQ-CONNSTRING)
* [jdbc-uri](https://jdbc.postgresql.org/documentation/use/#connecting-to-the-database)
* [fqdn-uri](https://www.postgresql.org/docs/current/libpq-connect.html#LIBPQ-CONNSTRING)
* [fqdn-jdbc-uri](https://jdbc.postgresql.org/documentation/use/#connecting-to-the-database)

The FQDN to be used in the URIs is calculated using the Kubernetes cluster
domain specified in the `KUBERNETES_CLUSTER_DOMAIN` configuration parameter.
See [the operator configuration documentation](operator_conf.md) for more information
about that.

The `-app` credentials are the ones that should be used by applications
connecting to the PostgreSQL cluster, and correspond to the user *owning* the
database.

The `-superuser` ones are supposed to be used only for administrative purposes,
and correspond to the `postgres` user.

:::info[Important]
    Superuser access over the network is disabled by default.
:::