Skip to main content

Prometheus - Docker Compose, Part 4: Nginx

638 words·
Prometheus Alertmanager Grafana Nginx Exporter Docker-Compose Monitoring
Table of Contents
Prometheus-Compose - This article is part of a series.
Part 4: This Article

Overview
#

I’m using the following Ubuntu 24.04 based servers in this tuturial:

192.168.30.10 # Prometheus Docker Compose stack
192.168.30.11 # Nginx Container, Nginx Exporter Container



Nginx & Nginx Exporter Containers
#

File and Folder Structure
#

# Create a directory for Nginx
sudo mkdir -p /opt/nginx && cd /opt/nginx

The file and folder structure looks like this:

nginx
├── docker-compose.yml
└── nginx-status.conf

Nginx Configuration: nginx-status.conf
#

# Create a Nginx configuration file for the Nginx metrics
sudo vi nginx-status.conf
server {
    listen 8080;
    # Optionally: Allow access only from localhost
    # listen 127.0.0.1:8080;

    server_name nginx-exporter;  # Define a custom server name

    location /status {
        stub_status;
    }
}

Docker Compose Manifest
#

# Create a Docker Compose manifest
sudo vi docker-compose.yml
services:
  nginx:
    image: nginx:latest
    container_name: nginx
    restart: unless-stopped
    ports:
      - 8080:8080  # Nginx metrics
      - 80:80  # Nginx default site
    volumes:
      - ./nginx-status.conf:/etc/nginx/conf.d/status.conf:ro
    healthcheck:
      test: ["CMD-SHELL", "curl -f http://localhost:8080/status || exit 1"]
      interval: 10s
      timeout: 5s
      retries: 3

  nginx-exporter:
    image: nginx/nginx-prometheus-exporter:latest
    container_name: nginx-exporter
    restart: unless-stopped
    ports:
      - 9113:9113
    environment:
      - NGINX_HOST=http://nginx:8080
      - NGINX_STATUS_PATH=/status
    depends_on:
      nginx:
        condition: service_healthy
# Create the container
sudo docker compose up -d

Verify the Nginx Metrics & Exporter
#

# List the containers
docker ps

# Shell output:
CONTAINER ID   IMAGE                                    COMMAND                  CREATED          STATUS                    PORTS                                                                          NAMES
539033beb213   nginx/nginx-prometheus-exporter:latest   "/usr/bin/nginx-prom…"   36 seconds ago   Up 25 seconds             0.0.0.0:9113->9113/tcp, :::9113->9113/tcp                                      nginx-exporter
d5c7d6df0d97   nginx:latest                             "/docker-entrypoint.…"   36 seconds ago   Up 35 seconds (healthy)   0.0.0.0:80->80/tcp, :::80->80/tcp, 0.0.0.0:8080->8080/tcp, :::8080->8080/tcp   nginx
# Curl the Nginx metrics
curl http://localhost:8080/status

# Shell output:
Active connections: 1
server accepts handled requests
 6 6 6
Reading: 0 Writing: 1 Waiting: 0
# Curl the Nginx Exporter
curl http://192.168.30.11:9113/metrics



Prometheus Configuration
#

Prometheus Configuration: prometheus.yml
#

# Adapt the Prometheus configuration
sudo vi prometheus_conf/prometheus.yml
# prometheus.yml
global:
  scrape_interval: 15s
  evaluation_interval: 10s


rule_files:
  - rules.yml

alerting:
  alertmanagers:
    - scheme: http
      static_configs:
        - targets: [ 'alertmanager:9093' ]


scrape_configs:
  # Prometheus Server
  - job_name: 'Prometheus-Server'
    static_configs:
      - targets:
        -  localhost:9090

  # Linux Servers / Node Exporter
  - job_name: 'Linux-Server'
    static_configs:
      - targets:
        -  192.168.30.11:9100
        -  192.168.30.12:9100

  # MySQL Server
  - job_name: 'MySQL-Server'
    params:
      auth_module: [client]  # Specify authentication mode
    scrape_interval: 5s
    static_configs:
      - targets: ['192.168.30.11:3306']
    relabel_configs:
      - source_labels: [__address__]
        target_label: __param_target
      - source_labels: [__param_target]
        target_label: instance
      - target_label: __address__
        replacement: 192.168.30.11:9104

  # PostgreSQL Server
  - job_name: 'Postgres-Server'
    static_configs:
      - targets: ["192.168.30.12:9187"]
    relabel_configs:
      - source_labels: [__address__]
        target_label: instance
      - target_label: __address__
        replacement: 192.168.30.12:9187

  # Nginx Webserver
  - job_name: 'Nginx-Webserver'
    metrics_path: /metrics
    static_configs:
      - targets: ['192.168.30.11:9113']

Prometheus Configuration: rules.yml
#

# Adapt the rules.yml configuration
sudo vi prometheus_conf/rules.yml
# rules.yml
groups:
  - name: NodeExporter
    rules:
    - alert: InstanceDown
      expr: up{job="Linux-Server"} == 0
      for: 1m

  - name: MysqldExporter
    rules:
      - alert: MysqlDown
        expr: mysql_up == 0
        for: 0m
        labels:
          severity: critical
        annotations:
          summary: MySQL down (instance {{ $labels.instance }})
          description: "MySQL instance is down on {{ $labels.instance }}\n  VALUE = {{ $value }}\n  LABELS = {{ $labels }}"

  - name: PostgresExporter
    rules:
      - alert: PostgresDown
        expr: pg_up == 0
        for: 0m
        labels:
          severity: critical
        annotations:
          summary: PostgreSQL down (instance {{ $labels.instance }})
          description: |
            PostgreSQL instance is down on {{ $labels.instance }}
            VALUE = {{ $value }}
            LABELS = {{ $labels }}

  - name: NginxExporter
    rules:
      - alert: NginxInstanceDown
        expr: up{job="Nginx-Webserver"} == 0
        for: 1m
        labels:
          severity: critical
        annotations:
          summary: Nginx instance down
          description: "Nginx instance {{ $labels.instance }} is unreachable."

Restart Docker Container
#

# Restart the Docker container
sudo docker compose restart



Prometheus Webinterface
#

Open Webinterface
#

# Open the Prometheus webinterface
http://192.168.30.10:9090

Verify Endpoints
#

  • Select “Status” > “Target health”



Example Alert
#

Stop Nginx Container
#

Stop the Nginx Docker containers:

# CD into the Docker Compose directory
cd /opt/nginx

# Stop the Docker containers
sudo docker compose down

Verify the Prometheus Alert
#

# Verify the alert in the Prometheus webinterface
http://192.168.30.10:9090/alerts

Verify the Alertmanager Alert
#

# Verify the alert in the Prometheus webinterface
http://192.168.30.10:9093/#/alerts
Prometheus-Compose - This article is part of a series.
Part 4: This Article