• Skip to secondary menu
  • Skip to main content
  • Skip to primary sidebar
  • Home
  • Projects
  • Products
  • Themes
  • Tools
  • Request for Quote

Vengala Vinay

Having 12+ Years of Experience in Software Development

  • Home
  • WordPress
  • PHP
    • Codeigniter
  • Django
  • Magento
  • Selenium
  • Server
Home » Server Monitoring Best Practices: Keeping Your WooCommerce App and Elasticsearch Clusters Alive on DigitalOcean

Server Monitoring Best Practices: Keeping Your WooCommerce App and Elasticsearch Clusters Alive on DigitalOcean

Proactive Monitoring for WooCommerce & Elasticsearch on DigitalOcean

Maintaining high availability for a critical e-commerce platform like WooCommerce, especially when augmented by Elasticsearch for search and analytics, demands a robust, multi-layered monitoring strategy. This isn’t about reactive alerts; it’s about predictive insights and rapid, informed remediation. We’ll focus on key metrics, essential tools, and practical configurations for DigitalOcean Droplets hosting both your WooCommerce application stack and your Elasticsearch cluster.

I. WooCommerce Application Stack Monitoring

The WooCommerce application stack typically involves a web server (Nginx/Apache), PHP-FPM, and a MySQL database. Each layer presents unique monitoring challenges.

A. Web Server (Nginx) Metrics

Nginx is the frontline. Monitoring its request volume, error rates, and latency is paramount. We’ll leverage the `stub_status` module and integrate with a time-series database like Prometheus.

1. Enabling Nginx Stub Status

First, ensure the `ngx_http_stub_status_module` is compiled into your Nginx binary. Most standard DigitalOcean images include this. Configure a location to expose these metrics:

# /etc/nginx/sites-available/your_woocommerce_site.conf
server {
    listen 80;
    server_name your-domain.com;

    # ... other configurations ...

    location /nginx_status {
        stub_status;
        allow 127.0.0.1; # Restrict access to localhost for security
        deny all;
    }

    # ... other configurations ...
}

Reload Nginx to apply changes:

sudo systemctl reload nginx

You can then test it locally:

curl http://localhost/nginx_status

This will output something like:

Active connections: 123
server accepts handled requests
 1667890 1667890 12345678
Reading: 10 Writing: 5 Waiting: 108

2. Prometheus Exporter Configuration

We’ll use the `nginx-exporter` to scrape these metrics and send them to Prometheus. Download the latest release from GitHub.

# Example for amd64
wget https://github.com/nginxinc/nginx-prometheus-exporter/releases/download/0.10.0/nginx-prometheus-exporter_0.10.0_linux_amd64.tar.gz
tar -zxvf nginx-prometheus-exporter_0.10.0_linux_amd64.tar.gz
sudo mv nginx-prometheus-exporter /usr/local/bin/
rm nginx-prometheus-exporter_0.10.0_linux_amd64.tar.gz

Create a systemd service file for the exporter:

# /etc/systemd/system/nginx-exporter.service
[Unit]
Description=Nginx Prometheus Exporter
Wants=network-online.target
After=network-online.target

[Service]
Type=simple
User=prometheus
Group=prometheus
ExecStart=/usr/local/bin/nginx-prometheus-exporter \
  --nginx.scrape-uri="http://localhost/nginx_status" \
  --web.listen-address=":9113"

[Install]
WantedBy=multi-user.target

Create the `prometheus` user and group, then start and enable the service:

sudo groupadd --system prometheus
sudo useradd --system --no-create-home --gid prometheus prometheus
sudo systemctl daemon-reload
sudo systemctl start nginx-exporter
sudo systemctl enable nginx-exporter
sudo systemctl status nginx-exporter

Configure Prometheus to scrape this exporter. In your `prometheus.yml`:

scrape_configs:
  - job_name: 'nginx'
    static_configs:
      - targets: ['localhost:9113'] # Or the IP of your Prometheus server if not co-located

3. Key Nginx Metrics to Monitor

  • nginx_http_connections_active: Number of active client connections. High numbers might indicate slow backend processing or DoS.
  • nginx_http_requests_total: Total requests processed. Track rate of change for traffic spikes.
  • nginx_http_requests_errors_total: Count of requests resulting in errors (e.g., 5xx). Crucial for application health.
  • nginx_http_requests_duration_seconds: Latency of requests. Use histogram/summary to track percentiles (p95, p99).

B. PHP-FPM Monitoring

PHP-FPM’s performance directly impacts WooCommerce responsiveness. We need to monitor its process pool status and execution times.

1. Enabling PHP-FPM Status Page

Similar to Nginx, PHP-FPM can expose a status page. This requires the `pm.status_path` directive in your pool configuration (e.g., `/etc/php/8.1/fpm/pool.d/www.conf`).

; /etc/php/8.1/fpm/pool.d/www.conf
[www]
listen = /run/php/php8.1-fpm.sock
user = www-data
group = www-data
pm = dynamic
pm.max_children = 100
pm.start_servers = 10
pm.min_spare_servers = 5
pm.max_spare_servers = 20
pm.process_idle_timeout = 10s
pm.max_requests = 500

; Enable status page
pm.status_path = /fpm_status

You’ll need to configure your web server (Nginx) to proxy requests to this status page. This is often done by creating a separate FastCGI configuration for the status path.

# /etc/nginx/conf.d/php-fpm-status.conf
location ~ ^/fpm_status {
    include fastcgi_params;
    fastcgi_param SCRIPT_FILENAME $document_root$fastcgi_script_name;
    fastcgi_pass unix:/run/php/php8.1-fpm.sock; # Match your PHP-FPM socket
    allow 127.0.0.1;
    deny all;
}

Reload Nginx and PHP-FPM:

sudo systemctl reload nginx
sudo systemctl reload php8.1-fpm

Accessing `http://your-domain.com/fpm_status` will show detailed metrics.

2. Prometheus Exporter for PHP-FPM

The `php-fpm_exporter` is a common choice. Download and install it similarly to the Nginx exporter.

# Example for amd64
wget https://github.com/prometheus/php-fpm_exporter/releases/download/v0.3.0/php-fpm_exporter-0.3.0.linux-amd64.tar.gz
tar -zxvf php-fpm_exporter-0.3.0.linux-amd64.tar.gz
sudo mv php-fpm_exporter-0.3.0.linux-amd64/php-fpm_exporter /usr/local/bin/
rm -rf php-fpm_exporter-0.3.0.linux-amd64*

Create a systemd service file:

# /etc/systemd/system/php-fpm-exporter.service
[Unit]
Description=PHP-FPM Prometheus Exporter
Wants=network-online.target
After=network-online.target

[Service]
Type=simple
User=prometheus
Group=prometheus
ExecStart=/usr/local/bin/php-fpm_exporter \
  --php-fpm.status-path="http://localhost/fpm_status" \
  --web.listen-address=":9253"

[Install]
WantedBy=multi-user.target

Start and enable the service:

sudo systemctl daemon-reload
sudo systemctl start php-fpm-exporter
sudo systemctl enable php-fpm-exporter
sudo systemctl status php-fpm-exporter

Add it to your `prometheus.yml`:

scrape_configs:
  # ... other jobs ...
  - job_name: 'php-fpm'
    static_configs:
      - targets: ['localhost:9253']

3. Key PHP-FPM Metrics to Monitor

  • php_fpm_process_active: Number of active PHP-FPM processes. Monitor against pm.max_children. If consistently maxed out, increase it or optimize PHP code.
  • php_fpm_process_idle: Number of idle PHP-FPM processes.
  • php_fpm_request_duration_seconds: Request latency. Essential for identifying slow PHP execution.
  • php_fpm_accepted_connections_total: Total connections accepted.
  • php_fpm_slow_requests_total: Count of requests exceeding the request_slowlog_timeout. Critical for debugging performance bottlenecks.

C. MySQL Database Monitoring

WooCommerce relies heavily on MySQL. Database performance directly impacts everything from product loading to checkout. We’ll use `mysqld_exporter`.

1. MySQL User and Permissions

Create a dedicated user for the exporter with minimal necessary privileges:

CREATE USER 'exporter'@'localhost' IDENTIFIED BY 'your_secure_password';
GRANT PROCESS, REPLICATION CLIENT, SELECT ON *.* TO 'exporter'@'localhost';
FLUSH PRIVILEGES;

Create a `.my.cnf` file for the exporter user (ensure permissions are strict):

# /home/prometheus/.my.cnf
[client]
user=exporter
password=your_secure_password
host=localhost
sudo chown prometheus:prometheus /home/prometheus/.my.cnf
sudo chmod 600 /home/prometheus/.my.cnf

2. Prometheus Exporter for MySQL

Download and install `mysqld_exporter`.

# Example for amd64
wget https://github.com/prometheus/mysqld_exporter/releases/download/v0.14.0/mysqld_exporter-0.14.0.linux-amd64.tar.gz
tar -zxvf mysqld_exporter-0.14.0.linux-amd64.tar.gz
sudo mv mysqld_exporter-0.14.0.linux-amd64/mysqld_exporter /usr/local/bin/
rm -rf mysqld_exporter-0.14.0.linux-amd64*

Create a systemd service file:

# /etc/systemd/system/mysqld-exporter.service
[Unit]
Description=MySQL Prometheus Exporter
Wants=network-online.target
After=network-online.target

[Service]
Type=simple
User=prometheus
Group=prometheus
EnvironmentFile=/etc/prometheus/mysqld_exporter.env # Optional: for credentials
ExecStart=/usr/local/bin/mysqld_exporter \
  --config.my-cnf="/home/prometheus/.my.cnf" \
  --web.listen-address=":9104"

[Install]
WantedBy=multi-user.target

Start and enable the service:

sudo systemctl daemon-reload
sudo systemctl start mysqld-exporter
sudo systemctl enable mysqld-exporter
sudo systemctl status mysqld-exporter

Add to `prometheus.yml`:

scrape_configs:
  # ... other jobs ...
  - job_name: 'mysql'
    static_configs:
      - targets: ['localhost:9104']

3. Key MySQL Metrics to Monitor

  • mysql_global_status_threads_connected: Number of active client connections.
  • mysql_global_status_threads_running: Number of threads actively executing queries. High values can indicate contention.
  • mysql_global_status_slow_queries: Count of queries exceeding long_query_time.
  • mysql_global_status_innodb_buffer_pool_wait_free: Indicates waits for free pages in the InnoDB buffer pool. High values suggest insufficient buffer pool size.
  • mysql_global_status_innodb_row_lock_waits: Number of row lock waits. High values point to concurrency issues or poorly optimized transactions.
  • mysql_global_status_connections: Total connection attempts.
  • mysql_global_status_aborted_connects: Failed connection attempts.
  • mysql_slave_status_seconds_behind_master: (If using replication) Replication lag. Critical for read replicas.

II. Elasticsearch Cluster Monitoring

Elasticsearch is resource-intensive and prone to performance degradation if not monitored closely. We’ll focus on JVM heap usage, indexing rates, search latency, and cluster health.

A. Elasticsearch Metrics Endpoint

Elasticsearch exposes a comprehensive metrics API. We can access it via `curl` or use a dedicated exporter.

curl -X GET "localhost:9200/_nodes/stats?pretty"
curl -X GET "localhost:9200/_cluster/health?pretty"

B. Prometheus Exporter for Elasticsearch

The `elasticsearch_exporter` is the standard tool for integrating Elasticsearch metrics with Prometheus.

# Example for amd64
wget https://github.com/prometheus-community/elasticsearch_exporter/releases/download/v1.4.0/elasticsearch_exporter-1.4.0.linux-amd64.tar.gz
tar -zxvf elasticsearch_exporter-1.4.0.linux-amd64.tar.gz
sudo mv elasticsearch_exporter-1.4.0.linux-amd64/elasticsearch_exporter /usr/local/bin/
rm -rf elasticsearch_exporter-1.4.0.linux-amd64*

Create a systemd service file. Note the `–es.uri` pointing to your Elasticsearch instance.

# /etc/systemd/system/elasticsearch-exporter.service
[Unit]
Description=Elasticsearch Prometheus Exporter
Wants=network-online.target
After=network-online.target

[Service]
Type=simple
User=prometheus
Group=prometheus
ExecStart=/usr/local/bin/elasticsearch_exporter \
  --es.uri="http://localhost:9200" \
  --web.listen-address=":9114" \
  --es.timeout="30s" \
  --es.all_indices \
  --es.indices.include=".*" # Adjust regex if needed

[Install]
WantedBy=multi-user.target

Start and enable the service:

sudo systemctl daemon-reload
sudo systemctl start elasticsearch-exporter
sudo systemctl enable elasticsearch-exporter
sudo systemctl status elasticsearch-exporter

Add to `prometheus.yml`:

scrape_configs:
  # ... other jobs ...
  - job_name: 'elasticsearch'
    static_configs:
      - targets: ['localhost:9114'] # Scrape the exporter, not ES directly

C. Key Elasticsearch Metrics to Monitor

  • elasticsearch_cluster_health_status: Cluster health (0=green, 1=yellow, 2=red). Critical alert threshold.
  • elasticsearch_jvm_memory_used_bytes vs elasticsearch_jvm_memory_max_bytes: JVM Heap usage. Aim to keep below 75-80% to avoid excessive garbage collection.
  • elasticsearch_indices_indexing_index_total: Rate of indexing operations.
  • elasticsearch_indices_search_query_total: Rate of search operations.
  • elasticsearch_indices_search_query_duration_seconds_count: Number of search requests.
  • elasticsearch_indices_search_query_duration_seconds_sum: Total time spent on search requests. Calculate average/percentiles.
  • elasticsearch_nodes_fs_available_bytes: Disk space available on nodes. Crucial for preventing shard allocation failures.
  • elasticsearch_thread_pool_search_rejected: Rejected search requests due to thread pool exhaustion.
  • elasticsearch_thread_pool_index_rejected: Rejected index requests.

III. System-Level Metrics (Droplets)

Beyond application-specific metrics, fundamental system metrics on your DigitalOcean Droplets are essential.

A. Node Exporter

The `node_exporter` provides a wealth of system-level metrics (CPU, RAM, Disk I/O, Network).

# Example for amd64
wget https://github.com/prometheus/node_exporter/releases/download/v1.5.0/node_exporter-1.5.0.linux-amd64.tar.gz
tar -zxvf node_exporter-1.5.0.linux-amd64.tar.gz
sudo mv node_exporter-1.5.0.linux-amd64/node_exporter /usr/local/bin/
rm -rf node_exporter-1.5.0.linux-amd64*

Create a systemd service file:

# /etc/systemd/system/node-exporter.service
[Unit]
Description=Node Exporter
Wants=network-online.target
After=network-online.target

[Service]
Type=simple
User=prometheus
Group=prometheus
ExecStart=/usr/local/bin/node_exporter \
  --web.listen-address=":9100"

[Install]
WantedBy=multi-user.target

Start and enable the service:

sudo systemctl daemon-reload
sudo systemctl start node-exporter
sudo systemctl enable node-exporter
sudo systemctl status node-exporter

Add to `prometheus.yml` for each Droplet:

scrape_configs:
  # ... other jobs ...
  - job_name: 'node'
    static_configs:
      - targets: ['IP_ADDRESS_OF_DROPLET:9100'] # Replace with actual Droplet IP
    # If Prometheus is on a different Droplet, use its IP.
    # If Prometheus is on the same Droplet, use 'localhost:9100'

B. Key System Metrics to Monitor

  • node_cpu_seconds_total: CPU usage by mode (idle, user, system, iowait). High iowait often points to disk or network bottlenecks.
  • node_memory_MemAvailable_bytes: Available memory. Low available memory leads to swapping, severely degrading performance.
  • node_disk_io_time_seconds_total: Disk I/O time. High utilization indicates a disk bottleneck.
  • node_network_receive_bytes_total and node_network_transmit_bytes_total: Network traffic. Monitor for saturation.
  • node_load1, node_load5, node_load15: System load averages.

IV. Alerting and Visualization

Metrics are only useful if they drive action. Prometheus Alertmanager and Grafana are the standard companions.

A. Prometheus Alertmanager Configuration

Define alert rules in Prometheus (e.g., in `/etc/prometheus/alert.rules.yml`):

groups:
- name: woocommerce_alerts
  rules:
  - alert: HighNginxErrorRate
    expr: sum(rate(nginx_http_requests_errors_total[5m])) by (job) / sum(rate(nginx_http_requests_total[5m])) by (job) > 0.05
    for: 5m
    labels:
      severity: critical
    annotations:
      summary: "High Nginx error rate detected on {{ $labels.job }}"
      description: "Nginx error rate is above 5% for the last 5 minutes."

  - alert: HighPhpFpmProcessUsage
    expr: php_fpm_process_active / php_fpm_process_max_children * 100 > 90
    for: 10m
    labels:
      severity: warning
    annotations:
      summary: "PHP-FPM process usage high on {{ $labels.instance }}"
      description: "PHP-FPM is using over 90% of max children for 10 minutes."

  - alert: ElasticsearchClusterRed
    expr: elasticsearch_cluster_health_status == 2
    for: 1m
    labels:
      severity: critical
    annotations:
      summary: "Elasticsearch cluster is RED on {{ $labels.instance }}"
      description: "Elasticsearch cluster health is RED. Shard allocation issues likely."

  - alert: LowDiskSpace
    expr: node_filesystem_avail_bytes / node_filesystem_size_bytes * 100 < 10
    for: 15m
    labels:
      severity: warning
    annotations:
      summary: "Low disk space on {{ $labels.instance }}"
      description: "Filesystem {{ $labels.mountpoint }} on {{ $labels.instance }} has less than 10% free space."

Configure Prometheus to load these rules and point to your Alertmanager instance in `prometheus.yml`:

rule_files:
  - "/etc/prometheus/alert.rules.yml"

alerting:
  alertmanagers:
    - static_configs:
        - targets: ['ALERTMANAGER_IP:9093'] # Replace with Alertmanager IP

Configure Alertmanager (`alertmanager.yml`) for routing and notifications (e.g., Slack, PagerDuty).

B. Grafana Dashboards

Import pre-built dashboards or create custom ones in Grafana. Search for “WooCommerce”, “PHP-FPM”, “MySQL”, and “Elasticsearch” on Grafana.com/dashboards. Key dashboards include:

  • Node Exporter Full dashboard (ID: 1860)
  • MySQL Exporter dashboard (ID: 7362)
  • Elasticsearch Exporter dashboard (ID: 11106)
  • PHP-FPM Exporter dashboard (ID: 10420)

Customize these dashboards to highlight the critical metrics identified earlier, setting up thresholds and visual cues for potential issues.

V. Advanced Considerations & Troubleshooting

A. Log Aggregation

While metrics provide quantitative data, logs offer qualitative insights. Implement a log aggregation solution (e.g., ELK stack, Loki, Graylog) to centralize logs from your web server, PHP-FPM, and Elasticsearch nodes. This is invaluable for correlating metric spikes with specific errors.

B. Application Performance Monitoring (APM)

For deep dives into WooCommerce code performance, consider an APM tool like New Relic, Datadog APM, or Elastic APM. These tools trace requests through your PHP application, pinpointing slow functions, database queries, and external API calls.

C. Elasticsearch Shard Management

Monitor shard size, count, and allocation status. Unbalanced shards or excessively large shards can cripple cluster performance. Use tools like `curator` or Elasticsearch’s Index Lifecycle Management (ILM) to manage indices and shards proactively.

D. Network Latency

If your Elasticsearch cluster is separate from your WooCommerce app, monitor network latency between them. High latency can manifest as slow searches and indexing. DigitalOcean’s monitoring tools can help here, or use `ping` and `mtr` periodically.

E. Troubleshooting Workflow Example

  • Alert: High Nginx error rate (5xx).
  • Grafana Check: Examine Nginx error metrics (nginx_http_requests_errors_total rate). Check PHP-FPM status page/metrics for high request duration or process saturation.
  • Log Dive: Check Nginx error logs (`/var/log/nginx/error.log`) and PHP-FPM slow log for specific error messages.
  • Elasticsearch Check: If errors relate to product search, check Elasticsearch cluster health and search latency metrics. Are indices healthy? Is search latency high?
  • System Check: Examine CPU, RAM, and I/O on the web/PHP-FPM Droplets. Is a resource bottleneck causing PHP to fail?
  • Resolution: Based on findings, optimize PHP code, increase PHP-FPM workers, scale Droplet resources, or investigate Elasticsearch issues.

Implementing this comprehensive monitoring strategy provides the visibility needed to keep your WooCommerce and Elasticsearch infrastructure stable, performant, and available, even under heavy load on DigitalOcean.

Primary Sidebar

A little about the Author

Having 12+ Years of Experience in Software Development, Vinay is a principal software architect, senior systems engineer, and elite technical consultant. He specializes in bespoke PHP/WordPress development, high-performance Magento 2 & Shopify architectures, custom plugin/theme development from scratch, and legacy code modernization (including VB6, VB.NET, PyQt, and Crystal Reports). Known for solving complex database bottlenecks, speed optimization (Core Web Vitals), and advanced security code auditing, Vinay engineers production-ready systems designed to scale under heavy concurrent load conditions.



Chat on WhatsApp

Recent Posts

  • Go Goroutines vs. Node.js Event Loop: Scaling I/O-Bound Microservices Under High Load
  • Elixir Phoenix vs. Go Gin: Concurrency Models and Fault Tolerance Under Peak Request Volume
  • Python Celery vs. Go Channels: Distributed Task Queue Overhead and Memory Reliability
  • Scala Pekko vs. Go Goroutines: Actor Model vs. CSP for Event-Driven Reactive Systems
  • Java Loom Virtual Threads vs. Go Goroutines: Under-the-Hood Scheduler and Thread Overhead Comparison

Categories

  • apache (1)
  • Business & Monetization (390)
  • Centos (4)
  • Comparisons & Decision Making (55)
  • Debian (2)
  • Debugging & Troubleshooting (584)
  • Desktop Applications (14)
  • DevOps (7)
  • DevOps & Cloud Scaling (962)
  • Django (1)
  • Laravel (4)
  • Migration & Architecture (192)
  • Mobile Applications (24)
  • MySQL (1)
  • Performance & Optimization (806)
  • PHP (5)
  • PHP Development (21)
  • Plugins & Themes (244)
  • Programming Languages (9)
  • Python (19)
  • Ruby on Rails (1)
  • Security & Compliance (543)
  • SEO & Growth (491)
  • Server (23)
  • Ubuntu (9)
  • VB6 & VB.NET (8)
  • Web Applications & Frontend (19)
  • Web Assembly (Wasm) (2)
  • WordPress (22)
  • WordPress Plugin Development (7)
  • WordPress Theme Development (357)

Recent Posts

  • Go Goroutines vs. Node.js Event Loop: Scaling I/O-Bound Microservices Under High Load
  • Elixir Phoenix vs. Go Gin: Concurrency Models and Fault Tolerance Under Peak Request Volume
  • Python Celery vs. Go Channels: Distributed Task Queue Overhead and Memory Reliability

Top Categories

  • DevOps & Cloud Scaling (962)
  • Performance & Optimization (806)
  • Debugging & Troubleshooting (584)
  • Security & Compliance (543)
  • SEO & Growth (491)
  • Business & Monetization (390)

Our Products

  • ERP & LMS Systems (4)
  • Directories & Marketplaces (4)
  • Healthcare Portals (3)
  • Point of Sale (POS) (2)
  • E-Commerce Engines (2)

Our Services

  • E-Commerce Development (10)
  • WordPress Development (8)
  • Python & Desktop GUI (7)
  • General Consulting (7)
  • Legacy Modernization (5)
  • Mobile App Development (4)

Copyright © 2026 · Vinay Vengala