---
title: Install & configure NRDOT for PostgreSQL monitoring with Docker
source: https://docs.newrelic.com/docs/opentelemetry/db360/postgresql/docker
---

Set up PostgreSQL monitoring using the NRDOT Collector as a sibling container to a PostgreSQL instance that's already running in Docker.

> #### 💡 TIP
>
> Looking to automate this at scale, or run on Kubernetes instead? Refer to [Ansible install](https://docs.newrelic.com/docs/opentelemetry/db360/postgresql/ansible), [Chef install](https://docs.newrelic.com/docs/opentelemetry/db360/postgresql/chef), or [Helm chart install](https://docs.newrelic.com/docs/opentelemetry/db360/postgresql/helm).

## Prerequisites [#prerequisites]

Before you install, make sure you have:

-   Docker installed on the host.
-   A PostgreSQL container already running (PostgreSQL 14 or later).
-   A New Relic [license key](https://docs.newrelic.com/docs/apis/intro-apis/new-relic-api-keys/#ingest-license-key).
-   Network connectivity from the collector container to [New Relic OTLP endpoints](https://docs.newrelic.com/docs/opentelemetry/best-practices/opentelemetry-otlp/).

For supported PostgreSQL versions, required grants, and recommended server parameters, see [Compatibility and prerequisites](https://docs.newrelic.com/docs/opentelemetry/db360/postgresql/compatibility).

## Configure database user and grants [#user]

Create a monitoring user with the necessary privileges by running SQL against your PostgreSQL container with `docker exec`. Replace `<YOUR_POSTGRESQL_CONTAINER_NAME>`, `<YOUR_SUPERUSER>`, `<YOUR_DB_USERNAME>`, and `<YOUR_DB_PASSWORD>` with your own values.

1.  Create the monitoring user, connecting as a superuser:

    ```bash
    docker exec -i <YOUR_POSTGRESQL_CONTAINER_NAME> psql -U <YOUR_SUPERUSER> -d postgres -c "
    CREATE USER <YOUR_DB_USERNAME> WITH LOGIN PASSWORD '<YOUR_DB_PASSWORD>';
    "
    ```

2.  If you're on PostgreSQL 15 and above, assign the role to inherit privileges:

    ```bash
    docker exec -i <YOUR_POSTGRESQL_CONTAINER_NAME> psql -U <YOUR_SUPERUSER> -d postgres -c "
    ALTER ROLE <YOUR_DB_USERNAME> INHERIT;
    "
    ```

    > #### 💡 TIP
    >
    > If you're on PostgreSQL 14, the monitoring user inherits privileges by default, so you can skip this step.

3.  Apply the schema and grants in every database you want to monitor. Replace `<DB_NAMES>` with a space-separated list of your database names:

    ```bash
    for db in <DB_NAMES>; do
      docker exec -i <YOUR_POSTGRESQL_CONTAINER_NAME> psql -U <YOUR_SUPERUSER> -d "$db" -c "
      CREATE SCHEMA IF NOT EXISTS otel;
      GRANT USAGE ON SCHEMA otel TO <YOUR_DB_USERNAME>;
      GRANT USAGE ON SCHEMA public TO <YOUR_DB_USERNAME>;
      GRANT SELECT ON ALL TABLES IN SCHEMA public TO <YOUR_DB_USERNAME>;
      GRANT pg_monitor TO <YOUR_DB_USERNAME>;
      CREATE EXTENSION IF NOT EXISTS pg_stat_statements;
      "
    done
    ```

4.  (Optional) To collect vector metrics, create the `pgvector` extension in each database:

    ```bash
    for db in <DB_NAMES>; do
      docker exec -i <YOUR_POSTGRESQL_CONTAINER_NAME> psql -U <YOUR_SUPERUSER> -d "$db" -c "CREATE EXTENSION IF NOT EXISTS vector;"
    done
    ```

    The `l1`, `hamming`, and `jaccard` distance functions require `pgvector` version `0.7.0` or above.

5.  (Optional) To verify the connection and grants, run:

    ```bash
    docker exec -i <YOUR_POSTGRESQL_CONTAINER_NAME> psql -U <YOUR_DB_USERNAME> -d <YOUR_DATABASE_NAME> -c "SELECT * FROM pg_stat_statements LIMIT 1;"
    ```

    If the command completes without an error, the monitoring user and grants are correct.

## Create the NRDOT Collector configuration [#configure]

This configuration focuses on essential PostgreSQL monitoring with the `nrpostgresql` receiver. Run the following on the Docker host to generate `postgresql-config.yaml` in your current directory:

```bash
cat << 'EOF' > postgresql-config.yaml
receivers:
  nrpostgresql:
    endpoint: "<YOUR_POSTGRESQL_CONTAINER_NAME>:5432"
    username: "<YOUR_DB_USERNAME>"
    password: "<YOUR_DB_PASSWORD>"
    databases:
      - <YOUR_DATABASE_NAME>
    collection_interval: 15s
    events:
      db.server.top_query:
        enabled: true
      db.server.query_sample:
        enabled: true
      db.server.query_plan:
        enabled: true
    top_query_collection:
      max_rows_per_query: 1000
      top_n_query: 200
      collection_interval: 60s
      allowed_comment_keys: [nr_service_guid]
    query_sample_collection:
      max_rows_per_query: 1000
      allowed_comment_keys: [nr_service_guid]

    resource_attributes:
      db.system.version:
        enabled: true
    # Metrics needed for the out-of-the-box dashboard but disabled by default:
    # see "Available metrics" below for the full default-on/default-off breakdown.
    metrics:
      postgresql.database.locks:
        enabled: true
      postgresql.deadlocks:
        enabled: true
      postgresql.function.calls:
        enabled: true
      postgresql.query.conflicts:
        enabled: true
      postgresql.sequential_scans:
        enabled: true
      postgresql.temp.io:
        enabled: true
      postgresql.temp_files:
        enabled: true

processors:
  batch:
  batch/metrics:
    send_batch_size: 8192
    send_batch_max_size: 8192
    timeout: 10s

exporters:
  otlp/newrelic:
    endpoint: "<YOUR_NEWRELIC_OTLP_ENDPOINT>"
    headers:
      api-key: "<YOUR_NEWRELIC_LICENSE_KEY>"
    compression: gzip
    sending_queue:
      enabled: true
      sizer: bytes
      queue_size: 100_000_000
      num_consumers: 10
      batch:
        sizer: bytes
        max_size: 1_000_000
        min_size: 0
        flush_timeout: 5s
    retry_on_failure:
      enabled: true
      initial_interval: 5s
      max_interval: 30s
      max_elapsed_time: 300s

service:
  telemetry:
    metrics:
      level: none
  pipelines:
    metrics:
      receivers: [nrpostgresql]
      processors: [batch/metrics]
      exporters: [otlp/newrelic]
    logs:
      receivers: [nrpostgresql]
      processors: [batch]
      exporters: [otlp/newrelic]
EOF
```

### Configuration parameters [#configuration-parameters]

| Parameter                          | Description                                                                                                                                                          |
| ---------------------------------- | -------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
| `<YOUR_POSTGRESQL_CONTAINER_NAME>` | The name (or Docker DNS-resolvable hostname) of your running PostgreSQL container.                                                                                   |
| `<YOUR_DB_USERNAME>`               | The monitoring user you created in [Configure database user and grants](#user).                                                                                      |
| `<YOUR_DB_PASSWORD>`               | The password of the monitoring user you created in [Configure database user and grants](#user).                                                                      |
| `databases`                        | The list of database names to monitor. Each one must have the `otel` schema and grants applied.                                                                      |
| `<YOUR_NEWRELIC_OTLP_ENDPOINT>`    | Your New Relic OTLP endpoint. For more information, see [New Relic OTLP endpoints](https://docs.newrelic.com/docs/opentelemetry/best-practices/opentelemetry-otlp/). |
| `<YOUR_NEWRELIC_LICENSE_KEY>`      | Your New Relic [license key](https://docs.newrelic.com/docs/apis/intro-apis/new-relic-api-keys/#ingest-license-key).                                                 |

## Start the NRDOT Collector container [#start]

Run the collector on the same Docker network as your PostgreSQL container so it can resolve `<YOUR_POSTGRESQL_CONTAINER_NAME>` by its container name:

```bash
docker run -d \
  --name nrdot-collector \
  --network <YOUR_DOCKER_NETWORK> \
  -v "$PWD/postgresql-config.yaml:/etc/nrdot-collector/postgresql-config.yaml" \
  newrelic/nrdot-collector:latest \
  --config /etc/nrdot-collector/postgresql-config.yaml
```

> #### 💡 TIP
>
> Find your PostgreSQL container's network with `docker inspect <YOUR_POSTGRESQL_CONTAINER_NAME> --format '{{json .NetworkSettings.Networks}}'`. If it isn't on a shared user-defined network yet, create one and connect both containers to it:
>
> ```bash
> docker network create <YOUR_DOCKER_NETWORK>
> docker network connect <YOUR_DOCKER_NETWORK> <YOUR_POSTGRESQL_CONTAINER_NAME>
> ```

Confirm the collector container is running:

```bash
docker ps --filter name=nrdot-collector
```

If it's not running, check its logs for errors. The most common causes are YAML indentation issues in `postgresql-config.yaml` or an unreachable PostgreSQL container:

```bash
docker logs nrdot-collector
```

> #### 💡 TIP
>
> After changing `postgresql-config.yaml`, restart the container to apply your changes:
>
> ```bash
> docker restart nrdot-collector
> ```

## Find and use your data [#find]

Once your data is being collected, you can access comprehensive PostgreSQL database monitoring through the New Relic UI.

To find your PostgreSQL database entity in New Relic:

1.  Go to **[one.newrelic.com](https://one.newrelic.com) > All capabilities > Databases**.
2.  From the **Entity type** dropdown, select **PostgreSQL instance**, then click **Apply**.
3.  Select your PostgreSQL database from the list of entities.

To confirm data is arriving, run this query in the [query builder](https://docs.newrelic.com/docs/query-your-data/explore-query-data/query-builder/introduction-query-builder/):

```sql
SELECT count(*) FROM Metric
WHERE metricName LIKE 'postgresql.%'
AND instrumentation.provider = 'opentelemetry'
SINCE 10 minutes ago
```

## Related documentation [#related]

[Introduction to PostgreSQL monitoring with NRDOT](https://docs.newrelic.com/docs/opentelemetry/db360/postgresql/introduction)

Learn about all the available installation methods for PostgreSQL monitoring with New Relic.

[Self-hosted install](https://docs.newrelic.com/docs/opentelemetry/db360/postgresql/hosted)

Learn how to set up PostgreSQL monitoring on physical servers, virtual machines, and standalone installations.

[Ansible install](https://docs.newrelic.com/docs/opentelemetry/db360/postgresql/ansible)

Learn how to install and configure PostgreSQL monitoring at scale with the newrelic.newrelic_install Ansible role.

[Chef install](https://docs.newrelic.com/docs/opentelemetry/db360/postgresql/chef)

Learn how to install and configure PostgreSQL monitoring at scale with the newrelic-install Chef cookbook.

[Helm chart install](https://docs.newrelic.com/docs/opentelemetry/db360/postgresql/helm)

Learn how to install and configure PostgreSQL monitoring on Kubernetes with the postgresql-otel Helm chart.
