Skip to main content

System Requirements

Before installing, verify your system meets these requirements:

PostgreSQL Version

PostgreSQL 13-18 (recommended)PostgreSQL 9.1+ supported with reduced functionality

Operating System

Linux (amd64, arm64, armv7, ppc64le)Windows and macOS supported for development

Network

Port 9187 (exporter metrics endpoint)Access to PostgreSQL port 5432 (or custom port)

Permissions

PostgreSQL user with pg_monitor role (PostgreSQL 10+)Or custom monitoring functions (PostgreSQL 9.x)

Installation Methods

Docker Installation

The fastest way to deploy postgres_exporter is using the official Docker image.

Pull the Image

docker pull quay.io/prometheuscommunity/postgres-exporter:latest
Images are published to both Quay.io (primary) and Docker Hub. Use prometheuscommunity/postgres-exporter for Docker Hub.

Basic Deployment

docker run -d \
  --name postgres-exporter \
  -p 9187:9187 \
  -e DATA_SOURCE_URI="postgres-host:5432/postgres?sslmode=require" \
  -e DATA_SOURCE_USER="postgres_exporter" \
  -e DATA_SOURCE_PASS="your-password" \
  quay.io/prometheuscommunity/postgres-exporter:latest

Production Deployment with Secrets

Use file-based secrets for production:
# Create password file
echo "your-secure-password" > postgres-password.txt
chmod 400 postgres-password.txt

docker run -d \
  --name postgres-exporter \
  -p 9187:9187 \
  -v $(pwd)/postgres-password.txt:/secrets/password:ro \
  -e DATA_SOURCE_URI="postgres-host:5432/postgres?sslmode=require" \
  -e DATA_SOURCE_USER="postgres_exporter" \
  -e DATA_SOURCE_PASS_FILE="/secrets/password" \
  quay.io/prometheuscommunity/postgres-exporter:latest
The container runs as uid/gid 65534 (user nobody). Ensure mounted files have appropriate permissions:
chown 65534:65534 postgres-password.txt
chmod 400 postgres-password.txt

Enable Optional Collectors

Pass command-line flags to enable additional collectors:
docker run -d \
  --name postgres-exporter \
  -p 9187:9187 \
  -e DATA_SOURCE_URI="postgres-host:5432/postgres?sslmode=require" \
  -e DATA_SOURCE_USER="postgres_exporter" \
  -e DATA_SOURCE_PASS_FILE="/secrets/password" \
  -v $(pwd)/postgres-password.txt:/secrets/password:ro \
  quay.io/prometheuscommunity/postgres-exporter:latest \
  --collector.stat_statements \
  --collector.long_running_transactions \
  --collector.database_wraparound

Docker Compose

docker-compose.yml
version: '3.8'
services:
  postgres-exporter:
    image: quay.io/prometheuscommunity/postgres-exporter:latest
    container_name: postgres-exporter
    ports:
      - "9187:9187"
    environment:
      DATA_SOURCE_URI: "postgres:5432/mydb?sslmode=require"
      DATA_SOURCE_USER: "postgres_exporter"
      DATA_SOURCE_PASS_FILE: "/secrets/password"
      PG_EXPORTER_COLLECTION_TIMEOUT: "2m"
    volumes:
      - ./postgres-password.txt:/secrets/password:ro
      - ./postgres-exporter.yml:/etc/postgres-exporter.yml:ro
    command:
      - --config.file=/etc/postgres-exporter.yml
      - --collector.stat_statements
    restart: unless-stopped
    networks:
      - monitoring

networks:
  monitoring:
    driver: bridge

Verify Installation

# Check container logs
docker logs postgres-exporter

# Test metrics endpoint
curl http://localhost:9187/metrics | grep pg_up

Configuration File

The exporter supports a YAML configuration file for advanced settings, particularly for multi-target monitoring.

Create Configuration File

Create postgres_exporter.yml:
postgres_exporter.yml
auth_modules:
  production:
    type: userpass
    userpass:
      username: postgres_exporter
      password: prod-password
    options:
      sslmode: require
      connect_timeout: 10

  staging:
    type: userpass
    userpass:
      username: postgres_exporter
      password: staging-password
    options:
      sslmode: disable

  readonly:
    type: userpass
    userpass:
      username: readonly_user
      password: readonly-password
    options:
      sslmode: require
      application_name: postgres_exporter

Use Configuration File

# With binary
./postgres_exporter --config.file=/etc/postgres-exporter.yml

# With Docker
docker run -d \
  -v $(pwd)/postgres_exporter.yml:/config.yml:ro \
  -p 9187:9187 \
  quay.io/prometheuscommunity/postgres-exporter:latest \
  --config.file=/config.yml
See [Multi-Target Setup(../multi-target) for complete configuration examples.

Database User Setup

Create a dedicated monitoring user with minimal required permissions.

PostgreSQL 10 and Later

-- Create user
CREATE USER postgres_exporter WITH PASSWORD 'secure-password' LOGIN;

-- Grant monitoring role (provides read access to all stats views)
GRANT pg_monitor TO postgres_exporter;

-- Grant connection to databases you want to monitor
GRANT CONNECT ON DATABASE postgres TO postgres_exporter;
GRANT CONNECT ON DATABASE myapp TO postgres_exporter;

-- Optional: Enable pg_stat_statements monitoring
CREATE EXTENSION IF NOT EXISTS pg_stat_statements;
GRANT SELECT ON pg_stat_statements TO postgres_exporter;

PostgreSQL 9.x

Older versions require creating helper functions:
-- Create user
CREATE USER postgres_exporter WITH PASSWORD 'secure-password' LOGIN;

-- Create schema
CREATE SCHEMA IF NOT EXISTS postgres_exporter;
GRANT USAGE ON SCHEMA postgres_exporter TO postgres_exporter;
ALTER USER postgres_exporter SET SEARCH_PATH TO postgres_exporter, pg_catalog;

-- Helper function for pg_stat_activity
CREATE OR REPLACE FUNCTION postgres_exporter.get_pg_stat_activity() 
RETURNS SETOF pg_stat_activity AS
$$ SELECT * FROM pg_catalog.pg_stat_activity; $$
LANGUAGE sql VOLATILE SECURITY DEFINER;

CREATE OR REPLACE VIEW postgres_exporter.pg_stat_activity AS
  SELECT * FROM postgres_exporter.get_pg_stat_activity();

GRANT SELECT ON postgres_exporter.pg_stat_activity TO postgres_exporter;

-- Helper function for pg_stat_replication
CREATE OR REPLACE FUNCTION postgres_exporter.get_pg_stat_replication() 
RETURNS SETOF pg_stat_replication AS
$$ SELECT * FROM pg_catalog.pg_stat_replication; $$
LANGUAGE sql VOLATILE SECURITY DEFINER;

CREATE OR REPLACE VIEW postgres_exporter.pg_stat_replication AS
  SELECT * FROM postgres_exporter.get_pg_stat_replication();

GRANT SELECT ON postgres_exporter.pg_stat_replication TO postgres_exporter;

-- Grant database connection
GRANT CONNECT ON DATABASE postgres TO postgres_exporter;

AWS RDS / Aurora

RDS restricts superuser functions. Use the master user or grant the monitoring user to master:
CREATE USER postgres_exporter WITH PASSWORD 'secure-password' LOGIN;
GRANT pg_monitor TO postgres_exporter;
GRANT postgres_exporter TO <RDS_MASTER_USER>;

Verify Installation

Run these commands to verify the exporter is working correctly:
1

Check Process is Running

# For systemd
systemctl status postgres-exporter

# For Docker
docker ps | grep postgres-exporter

# For Kubernetes
kubectl get pods -l app=postgres-exporter
2

Test Metrics Endpoint

curl http://localhost:9187/metrics | head -20
Expected output includes:
# HELP pg_up Whether the last scrape was able to connect to the server (1 for yes, 0 for no)
# TYPE pg_up gauge
pg_up 1
3

Check for Errors

# Binary/systemd
journalctl -u postgres-exporter -n 50

# Docker
docker logs postgres-exporter

# Kubernetes
kubectl logs -l app=postgres-exporter
4

Verify Key Metrics

curl -s http://localhost:9187/metrics | grep -E "(pg_up|pg_stat_database_numbackends|pg_exporter_last_scrape_error)"
All three should be present:
  • pg_up 1 = Connected successfully
  • pg_stat_database_numbackends = Database metrics collected
  • pg_exporter_last_scrape_error 0 = No collection errors

Next Steps

Configuration Reference

Complete guide to collectors, flags, and environment variables

Multi-Target Monitoring

Configure centralized monitoring for multiple PostgreSQL servers

Prometheus Integration

Set up scrape configs and alerting rules

Security Best Practices

Secure your exporter deployment

Build docs developers (and LLMs) love