CresignSys Learn — Lesson 082

Written by

in

Build the CHP Health Engine

We now have two separate systems:

RECONCILIATION
    ↓
"Does the actual configuration match CHP?"

and:

HEALTH
    ↓
"Is the website actually working?"

These must remain separate.


1. Health Command

Create:

sudo nano /usr/local/bin/hosting-health

Usage:

sudo hosting-health example.com

Also:

sudo hosting-health example.com --json
sudo hosting-health example.com --verbose

2. Health Architecture

                 hosting-health
                       │
          ┌────────────┼────────────┐
          ▼            ▼            ▼
        SERVER       WEBSITE      DATA
          │            │            │
          ▼            ▼            ▼
        CPU          HTTP         MySQL
        RAM          HTTPS        WordPress
        Disk         TLS
        Load         DNS
        Nginx        Redirects
        PHP-FPM      Response

3. Health vs Reconciliation

Example:

CHP expects PHP 8.3
Actual PHP 8.2

Reconciliation:

DRIFT

But if PHP 8.2 is running and the website works:

Health:
HEALTHY

Therefore:

Configuration:
DRIFT

Runtime:
HEALTHY

Both can be true.


4. Health Result Categories

Use:

HEALTHY
WARNING
DEGRADED
DOWN
UNKNOWN
ERROR

HEALTHY

Everything important is functioning.

WARNING

Working, but an issue needs attention.

DEGRADED

Part of the service is impaired.

DOWN

The site/service is unavailable.

UNKNOWN

A reliable health determination cannot be made.

ERROR

The health checker itself failed.


5. Health Checks

The first version should check:

1. DNS
2. HTTP
3. HTTPS
4. TLS
5. Nginx
6. PHP-FPM
7. MySQL
8. WordPress
9. Disk
10. Memory
11. Load

6. Check 1 — DNS

Use:

dig +short A example.com

Expected:

SERVER_IPV4

Result:

DNS:
HEALTHY

If DNS doesn’t resolve:

DNS:
DOWN

But distinguish between:

DNS unavailable

and:

DNS points somewhere else

The second is configuration drift rather than necessarily a runtime outage.


7. DNS Health Function

Add to:

/etc/cresignsys/lib/health.sh

Function:

health_dns

Conceptually:

health_dns() {
    local domain="$1"

    if dig +short A "$domain" | grep -q .; then
        echo "HEALTHY"
    else
        echo "DOWN"
    fi
}

Later compare the result against CHP’s expected server IP.


8. HTTP Check

Use:

curl -I --max-time 10 http://example.com

Possible response:

HTTP/1.1 301 Moved Permanently

A redirect is not automatically a failure.


9. HTTP Status Categories

Treat:

2xx → HEALTHY
3xx → HEALTHY/WARNING
4xx → WARNING/DEGRADED
5xx → DOWN
timeout → DOWN
connection failure → DOWN

But don’t treat every 4xx identically.

For example:

401 Unauthorized

may be intentional.


10. HTTPS Check

Use:

curl -I --max-time 10 https://example.com

Expected:

HTTP/2 200

or:

HTTP/2 301

depending on the site’s design.


11. HTTP Redirect Chain

A common configuration:

http://example.com
       ↓
301
       ↓
https://example.com
       ↓
200

This is healthy.

Test:

curl -IL --max-time 10 http://example.com

The health engine should understand the chain.


12. Redirect Loop

Bad example:

HTTP
 ↓
HTTPS
 ↓
HTTP
 ↓
HTTPS

curl eventually fails.

Report:

HTTPS:
DOWN

Reason:
REDIRECT_LOOP

13. Excessive Redirects

Even if a redirect chain eventually succeeds:

HTTP
 ↓
HTTPS
 ↓
www
 ↓
non-www
 ↓
HTTPS

it may be inefficient.

Report:

WARNING

if the chain exceeds your configured threshold.

For example:

MAX_REDIRECTS=5

14. HTTP Response Time

Don’t only check status.

Measure:

curl -o /dev/null \
     -s \
     -w '%{http_code} %{time_total}\n' \
     https://example.com

Example:

200 0.342

Store:

HTTP status:
200

Response time:
342 ms

15. Response-Time Thresholds

Initial thresholds could be:

< 1 sec       HEALTHY
1–3 sec       WARNING
3–10 sec      DEGRADED
> 10 sec      DOWN/TIMEOUT

These should eventually be configurable.

Don’t treat these as universal performance benchmarks.


16. TLS Check

Use:

openssl s_client \
    -connect example.com:443 \
    -servername example.com

But don’t dump the entire output to logs.

Extract only:

certificate subject
issuer
expiry
verification result

17. TLS Verification

A healthy result:

TLS:
HEALTHY

Certificate:
VALID

Expires:
2026-11-20

If certificate verification fails:

TLS:
DOWN

18. Certificate Expiration Warning

Example:

30+ days:
HEALTHY

8–30 days:
WARNING

1–7 days:
DEGRADED

Expired:
DOWN

This should be configurable.


19. Nginx Check

Check:

systemctl is-active nginx

If active:

Nginx:
HEALTHY

If inactive:

Nginx:
DOWN

20. Nginx Configuration

Separately run:

nginx -t

Possible:

Service:
HEALTHY

Configuration:
ERROR

This is useful because a running Nginx process can still have a configuration problem waiting for the next reload.


21. PHP-FPM Check

Determine the site’s configured PHP-FPM service:

php8.3-fpm

Then:

systemctl is-active php8.3-fpm

Expected:

PHP-FPM:
HEALTHY

22. PHP Socket

Check:

test -S /run/php/php8.3-fpm.sock

If missing:

PHP-FPM:
DEGRADED

or:

DOWN

depending on whether the service itself is running.


23. PHP End-to-End Check

Service status alone isn’t enough.

You want:

Browser
   ↓
Nginx
   ↓
PHP-FPM
   ↓
PHP

A simple PHP health endpoint can eventually be useful.

For example:

/health.php

But don’t expose sensitive diagnostic information publicly.


24. Better Health Endpoint

Create a protected endpoint that returns:

OK

rather than:

PHP version
server variables
database password
filesystem paths

For example:

https://example.com/.well-known/chp-health

could eventually return:

OK

if appropriate for your architecture.


25. Don’t Expose Infrastructure Information

Avoid public endpoints displaying:

MYSQL_HOST
DB_USER
PHP_VERSION
SERVER_IP
filesystem paths
environment variables

A health endpoint should reveal as little as possible.


26. MySQL Health

For WordPress:

wp db check

is useful.

Possible result:

Database:
HEALTHY

If connection fails:

Database:
DOWN

27. MySQL Service

Also check:

systemctl is-active mysql

This gives:

MySQL Service:
HEALTHY

while:

WordPress Database:
DOWN

could indicate a connection/configuration problem.


28. WordPress Health

Check:

wp core is-installed

Then optionally:

wp db check

A WordPress site may have:

Nginx:
OK

PHP:
OK

MySQL:
OK

WordPress:
ERROR

For example, WordPress files may be incomplete.


29. WordPress HTTP Check

The most important application-level check is often:

HTTPS request
       ↓
WordPress response

If:

HTTP 200

the website is externally responding.

This is often more meaningful than checking individual processes.


30. WordPress Error Detection

A 200 response does not guarantee the page is healthy.

For example:

HTTP 200

could contain:

Fatal error

or:

Database connection error

Therefore application-specific checks can be added later.


31. Disk Health

Check:

df -h

For the website filesystem:

df -h /storage/websites/example.com

Example:

Filesystem      Size  Used Avail Use%
/dev/sdb        100G   65G   35G  65%

32. Disk Thresholds

Initial policy:

< 80%       HEALTHY
80–90%      WARNING
90–95%      DEGRADED
> 95%       CRITICAL

The exact thresholds should be configurable.


33. Inode Usage

Disk space can be available while inodes are exhausted.

Check:

df -i /storage/websites/example.com

This can detect:

100% inode usage

which can prevent new files from being created.


34. Memory

Check:

free -m

For overall server health, monitor:

total
used
available

Avoid using:

used / total

alone as the definition of memory pressure on Linux.

available is generally more useful for this purpose.


35. Load Average

Use:

uptime

or:

cat /proc/loadavg

Example:

0.25 0.31 0.28

Interpret load relative to the number of CPU cores.


36. CPU Count

nproc

If:

4 CPUs

and load is:

0.5

that’s generally light.

If load remains:

8+

on a 4-core system, that deserves investigation.

Don’t define a single universal load threshold.


37. Website-Level vs Server-Level Health

This distinction matters.

A server may have:

CPU:
HIGH

while:

example.com:
HTTP 200

Therefore:

Server health:
WARNING

Website health:
HEALTHY

Both can be true.


38. Site Health Model

The site health engine should primarily prioritize:

DNS
HTTP
HTTPS
TLS
Nginx
PHP
Database
Application

while server resource metrics provide:

WARNING

unless they actually cause service failure.


39. Health Score

Avoid an overly simplistic:

8 checks = 8 points

because some checks are much more important.

For example:

HTTPS DOWN

is more serious than:

Disk at 82%

Use severity instead.


40. Severity Model

Each check can produce:

OK
WARNING
CRITICAL
UNKNOWN

Example:

HTTP       OK
HTTPS      OK
TLS        OK
PHP        OK
MySQL      OK
Disk       WARNING

Overall:

WARNING

41. Critical Checks

For a normal public website:

DNS
HTTPS
HTTP

are usually critical.

For WordPress:

Database
PHP

are also critical.


42. Dependency Awareness

Don’t report five independent failures when one root failure caused them.

Example:

PHP-FPM DOWN

may cause:

HTTP 502
WordPress DOWN
Application DOWN

The health engine should understand this relationship.


43. Example

Instead of:

HTTP:
DOWN

PHP:
DOWN

WordPress:
DOWN

Application:
DOWN

say:

PHP-FPM:
CRITICAL

HTTP:
DEGRADED
Reason: upstream unavailable

WordPress:
NOT_REACHABLE

Likely root cause:
PHP-FPM failure

This is much more useful.


44. Dependency Graph

                    DNS
                     │
                     ▼
                  Nginx
                     │
              ┌──────┴──────┐
              ▼             ▼
           Static         PHP-FPM
                            │
                            ▼
                         MySQL
                            │
                            ▼
                        WordPress

If PHP-FPM fails:

PHP-FPM
   ↓
WordPress
   ↓
HTTP application response

can also fail.


45. Health Engine Library

Create:

sudo nano /etc/cresignsys/lib/health.sh

Functions:

health_dns
health_http
health_https
health_tls
health_nginx
health_php
health_mysql
health_wordpress
health_disk
health_memory
health_load
health_site

46. Don’t Mix Health and Reconciliation Functions

Keep:

reconcile_php()

separate from:

health_php()

because they answer different questions.

Reconciliation

Expected PHP:
8.3

Actual PHP:
8.2

Result:
DRIFT

Health

PHP-FPM:
running

Result:
HEALTHY

47. HTTP Health Function

Conceptually:

health_http() {
    local domain="$1"

    curl \
        --silent \
        --show-error \
        --location \
        --max-time 10 \
        --output /dev/null \
        --write-out '%{http_code} %{time_total}' \
        "https://${domain}"
}

Capture:

status
time

separately.


48. Curl Options

Useful options:

--max-time
--connect-timeout
--location
--silent
--show-error

For example:

curl \
  --connect-timeout 5 \
  --max-time 10 \
  --location \
  ...

This prevents a broken site from hanging the entire health process.


49. Health Timeout

Every external check should have a timeout.

Never allow:

curl
dig
openssl
mysql
wp

to hang indefinitely.

The health engine should finish predictably.


50. Parallel Health Checks

Later, checks can run concurrently:

DNS ──────┐
HTTP ─────┤
TLS ──────┤
PHP ──────┤──→ Result
MySQL ────┤
Disk ─────┘

But initially use sequential checks.

Reliability is more important than squeezing a few seconds out of the first implementation.


51. Health Output

Example:

CresignSys Site Health
======================

Site:
learn.cresignsys.com

DNS
---
Status:       HEALTHY
A Record:     CORRECT

HTTP
----
Status:       HEALTHY
HTTP Code:    301
Response:     0.18 sec

HTTPS
-----
Status:       HEALTHY
HTTP Code:    200
Response:     0.34 sec

TLS
---
Status:       HEALTHY
Certificate:  VALID
Expires:      2026-11-20

Nginx
-----
Service:      HEALTHY
Config:       VALID

PHP-FPM
-------
Service:      HEALTHY
Socket:       AVAILABLE

MySQL
-----
Service:      HEALTHY
Connection:   HEALTHY

WordPress
---------
Installation: HEALTHY
Database:     HEALTHY

Resources
---------
Disk:         HEALTHY
Memory:       HEALTHY
Load:         HEALTHY

Overall:
HEALTHY

52. Degraded Example

CresignSys Site Health
======================

HTTPS:
HEALTHY

PHP-FPM:
HEALTHY

MySQL:
HEALTHY

Disk:
WARNING
Usage: 87%

Overall:
WARNING

The website works, but the server needs attention.


53. Critical Example

HTTPS:
DOWN

PHP-FPM:
DOWN

MySQL:
HEALTHY

Likely cause:
PHP-FPM unavailable

Overall:
DOWN

54. Health JSON

Add:

sudo hosting-health example.com --json

Example:

{
  "domain": "example.com",
  "overall": "HEALTHY",
  "checks": {
    "dns": {
      "status": "HEALTHY"
    },
    "https": {
      "status": "HEALTHY",
      "http_code": 200,
      "response_time": 0.34
    },
    "tls": {
      "status": "HEALTHY"
    },
    "nginx": {
      "status": "HEALTHY"
    },
    "php": {
      "status": "HEALTHY"
    },
    "mysql": {
      "status": "HEALTHY"
    },
    "wordpress": {
      "status": "HEALTHY"
    }
  }
}

55. Store Health Results

The services table already has:

status
updated_at

but we should not overwrite everything with transient health data.

Eventually add a health-history table.


56. health_checks Table

Create in a future migration:

CREATE TABLE health_checks (
    id INTEGER PRIMARY KEY AUTOINCREMENT,
    site_id INTEGER NOT NULL,
    check_name TEXT NOT NULL,
    status TEXT NOT NULL,
    response_time_ms INTEGER,
    message TEXT,
    checked_at TEXT NOT NULL,

    FOREIGN KEY (site_id)
        REFERENCES sites(id)
        ON DELETE CASCADE
);

57. Why History?

Suppose:

14:00 HEALTHY
15:00 HEALTHY
16:00 WARNING
17:00 DOWN
18:00 HEALTHY

You can identify an outage window.


58. Don’t Store Every Check Forever

If health checks run every 5 minutes:

12 checks/hour
288 checks/day

for 100 sites:

28,800 checks/day

This grows quickly.

Use retention.

For example:

raw checks:
7 days

and later:

hourly aggregates:
90 days

59. Health Aggregation

Eventually:

Raw:
5-minute checks

       ↓

Hourly:
availability percentage

       ↓

Daily:
uptime percentage

Example:

August 13
Uptime:
99.87%

60. Uptime Calculation

If a site has:

288 checks/day

and:

2 failed checks

then approximate availability:

286 / 288 × 100
= 99.31%

For production-grade monitoring, account for check failures and measurement uncertainty rather than treating every failed probe as definitive downtime.


61. Health Endpoint for CHP

Later the central CHP control panel can display:

Sites
----------------------------------------
example.com          HEALTHY
shop.com             WARNING
blog.com              DOWN
medical.com           HEALTHY

Clicking a site:

example.com

shows:

Health
Reconciliation
Backups
SSL
Domains
Operations

62. Site Status Combines Both Systems

We now have:

hosting-reconcile

and:

hosting-health

Therefore:

hosting-site-status example.com

can combine them.


63. Combined Status

Example:

CresignSys Site Status
======================

Configuration:
DRIFT

Runtime:
HEALTHY

Overall:
WARNING

Configuration issue:
PHP expected 8.3, actual 8.2

This is much more informative than simply saying:

Site:
FAIL

64. Four Dimensions

A mature CHP status system can have:

CONFIGURATION
HEALTH
BACKUP
SECURITY

Example:

Configuration:
DRIFT

Health:
HEALTHY

Backup:
HEALTHY

Security:
WARNING

65. Future Security Checks

The health engine can eventually include:

certificate validity
open ports
file permissions
disk permissions
WordPress core integrity
plugin vulnerabilities
malware indicators

But security scanning should remain a separate subsystem where possible.

Don’t overload hosting-health.


66. Health vs Monitoring

hosting-health:

Run once

Monitoring:

Run repeatedly

So:

hosting-health

is the probe.

A future:

hosting-monitor

will schedule probes and record history.


67. Future Monitoring Architecture

             scheduler
                 │
                 ▼
         hosting-health
                 │
                 ▼
          health_checks
                 │
                 ▼
             alerting
                 │
        ┌────────┼────────┐
        ▼        ▼        ▼
      Email    Panel    WhatsApp*

The notification mechanism should be designed separately.


68. Don’t Alert on Every Failure

If a single probe fails because of a temporary network issue:

FAIL

you don’t necessarily want an immediate outage alert.

Use consecutive failures.

Example:

1 failure:
record

2 failures:
warning

3 consecutive failures:
DOWN/ALERT

The exact policy can be configured later.


69. Recovery Detection

If the site was:

DOWN

and then returns:

HEALTHY

record:

RECOVERED

This is useful for operations history.


70. Health State Machine

HEALTHY
   │
   ▼
WARNING
   │
   ▼
DEGRADED
   │
   ▼
DOWN
   │
   ▼
RECOVERING
   │
   ▼
HEALTHY

But don’t transition states on one noisy probe without considering consecutive failures.


71. First Version Scope

For now implement only:

DNS
HTTP
HTTPS
TLS
Nginx
PHP-FPM
MySQL
WordPress
Disk
Memory
Load

Don’t yet implement:

alerting
scheduler
uptime history
automatic restart
automatic repair

72. Automatic Restart Is Dangerous

Do not immediately implement:

systemctl restart php8.3-fpm

when health fails.

A failure may have a deeper cause:

memory exhaustion
configuration error
database problem
malicious traffic
disk full

Automatic restarts can hide the root problem.


73. Safe First Response

Health engine:

DETECT
   ↓
REPORT
   ↓
LOG

Later:

DETECT
   ↓
CLASSIFY
   ↓
REPAIR PLAN
   ↓
APPROVE
   ↓
APPLY

74. Test Sequence

After implementing:

sudo hosting-health learn.cresignsys.com

Then:

sudo hosting-health learn.cresignsys.com --json

Then compare with:

sudo hosting-reconcile learn.cresignsys.com

You should see the difference between:

configuration

and:

runtime

75. Example Combined Interpretation

Suppose:

Reconciliation:
DRIFT

Health:
HEALTHY

Interpretation:

The website is currently working, but its actual configuration differs from CHP’s recorded/desired configuration.

Another case:

Reconciliation:
MATCH

Health:
DOWN

Interpretation:

Configuration appears correct, but a runtime failure is occurring.

Another:

Reconciliation:
DRIFT

Health:
DOWN

Interpretation:

Configuration differs and the site is currently unavailable; investigate both, starting with the immediate runtime failure.


76. CHP Operational Model

We now have three important questions:

QUESTION 1
Does CHP know the site?
        ↓
DATABASE
QUESTION 2
Does the server match CHP?
        ↓
RECONCILIATION
QUESTION 3
Is the site working?
        ↓
HEALTH

Together:

DATABASE
   +
RECONCILIATION
   +
HEALTH
   ↓
SITE STATUS

77. Updated CHP Architecture

                         CRESIGNSYS
                              │
                ┌─────────────┴─────────────┐
                ▼                           ▼
          CONTROL PLANE                 DATA PLANE
                │                           │
                ▼                           ▼
           CHP DATABASE               Website Runtime
                │                           │
       ┌────────┼────────┐          ┌───────┼────────┐
       ▼        ▼        ▼          ▼       ▼        ▼
     Sites    Domains  Backups     Nginx    PHP     MySQL
       │
       ▼
Desired/known state
       │
       ├───────────────┐
       ▼               ▼
RECONCILIATION       HEALTH
       │               │
       │               ├── DNS
       │               ├── HTTP
       │               ├── HTTPS
       │               ├── TLS
       │               ├── PHP
       │               └── Database
       │
       └───────┬───────┘
               ▼
          SITE STATUS

78. Lesson 082 — Core Principle

The CHP health engine must be observational before it becomes corrective.

Its job is to reliably answer:

Is DNS working?
Is HTTP working?
Is HTTPS working?
Is TLS valid?
Is Nginx running?
Is PHP-FPM running?
Is MySQL available?
Is WordPress functional?
Is the filesystem healthy?
Is the server under resource pressure?

without changing the server.

That gives us a safe foundation for the next stage.


Next Lesson — 083

Build the Unified hosting-site-status

We now have:

hosting-db-import
hosting-reconcile
hosting-health

The next command will combine them:

sudo hosting-site-status example.com

It will produce a single operational view:

SITE
├── Identity
├── Domains
├── Configuration
├── Runtime Health
├── SSL
├── DNS
├── WordPress
├── Backups
├── Resources
└── Recent Operations

and ultimately calculate:

HEALTHY
WARNING
DEGRADED
DOWN
DRIFT
UNKNOWN

without confusing configuration drift with actual downtime.

Comments

Leave a Reply

Your email address will not be published. Required fields are marked *