Build the Unified hosting-site-status
We now have three separate capabilities:
hosting-db-import
↓
KNOW THE SITE
hosting-reconcile
↓
KNOW CONFIGURATION DRIFT
hosting-health
↓
KNOW RUNTIME HEALTH
The next step is to create one command that brings everything together.
sudo hosting-site-status example.com
1. Goal
The command should answer, in one screen:
What is this site?
Is it configured correctly?
Is it currently working?
Is SSL healthy?
Is DNS correct?
Are backups available?
Is the server under pressure?
What happened recently?
2. Status Architecture
SITE
│
┌──────────┼──────────┐
▼ ▼ ▼
Identity Configuration Health
│ │ │
▼ ▼ ▼
Domains Reconcile Runtime
│ │ │
└──────────┼──────────┘
▼
Backups
│
▼
Operations
│
▼
STATUS ENGINE
│
▼
UNIFIED SITE STATUS
3. Create Command
sudo nano /usr/local/bin/hosting-site-status
Start with:
#!/usr/bin/env bash
set -Eeuo pipefail
4. Load Libraries
source /etc/cresignsys/hosting.conf
source /etc/cresignsys/lib/common.sh
source /etc/cresignsys/lib/logging.sh
source /etc/cresignsys/lib/domain.sh
source /etc/cresignsys/lib/database.sh
source /etc/cresignsys/lib/discovery.sh
source /etc/cresignsys/lib/reconcile.sh
source /etc/cresignsys/lib/health.sh
5. Require Root
require_root
6. Validate Domain
DOMAIN="$(normalize_domain "$1")"
validate_domain "$DOMAIN"
Usage:
sudo hosting-site-status learn.cresignsys.com
7. Find Site
First query:
domains
↓
site_id
↓
sites
If the site isn’t registered:
SITE:
NOT REGISTERED
Then suggest:
hosting-db-import example.com
Do not automatically import.
8. Header
The output should start with:
CresignSys Site Status
======================
Site:
learn.cresignsys.com
Site ID:
7
Management:
VERIFIED
9. Identity Section
Show:
Identity
--------
Primary Domain:
learn.cresignsys.com
Web Root:
/storage/websites/learn.cresignsys.com/public
Application:
WORDPRESS
Owner:
www-data:www-data
10. Management State
Display:
Management:
READ_ONLY
or:
Management:
MANAGED
This is important because an imported website may be monitored but not yet controlled by CHP.
11. Domain Section
Example:
Domains
-------
learn.cresignsys.com
Type: PRIMARY
DNS: CORRECT
SSL: ACTIVE
www.learn.cresignsys.com
Type: ALIAS
DNS: CORRECT
SSL: ACTIVE
12. Don’t Duplicate Everything
The site-status command should summarize.
Detailed information remains available through:
hosting-reconcile
hosting-health
hosting-info
So:
hosting-site-status
is the dashboard.
13. Configuration Section
Run reconciliation:
Configuration
-------------
Filesystem:
MATCH
Nginx:
MATCH
PHP:
DRIFT
Database:
MATCH
SSL:
MATCH
DNS:
MATCH
Overall:
DRIFT
14. Runtime Section
Run health:
Runtime Health
--------------
HTTP:
HEALTHY
HTTPS:
HEALTHY
TLS:
HEALTHY
Nginx:
HEALTHY
PHP-FPM:
HEALTHY
MySQL:
HEALTHY
WordPress:
HEALTHY
Overall:
HEALTHY
15. Combined Example
This is an important scenario:
Configuration:
DRIFT
Runtime:
HEALTHY
For example:
PHP expected:
8.3
PHP actual:
8.2
but the site still works.
The overall site status should not be DOWN.
16. Status Priority
Use separate states:
RUNTIME:
HEALTHY
WARNING
DEGRADED
DOWN
UNKNOWN
and:
CONFIGURATION:
MATCH
DRIFT
UNKNOWN
Then calculate a final operational state.
17. Final Status Logic
A practical first version:
Runtime DOWN
↓
OVERALL DOWN
Runtime DEGRADED
↓
OVERALL DEGRADED
Runtime WARNING
↓
OVERALL WARNING
Runtime HEALTHY
+
Configuration DRIFT
↓
OVERALL WARNING
Runtime HEALTHY
+
Configuration MATCH
↓
OVERALL HEALTHY
18. Why Drift Becomes WARNING
Suppose:
PHP expected: 8.3
PHP actual: 8.2
but:
HTTPS:
200 OK
Calling the site:
DOWN
would be misleading.
Instead:
OVERALL:
WARNING
is more accurate.
19. Critical Health Overrides
If:
HTTPS:
DOWN
then:
OVERALL:
DOWN
even if:
Configuration:
MATCH
Because the website isn’t currently reachable.
20. Example Status
CresignSys Site Status
======================
Site:
example.com
Configuration:
DRIFT
Runtime:
HEALTHY
Overall:
WARNING
This immediately communicates the situation.
21. SSL Summary
Show:
SSL
---
Status:
ACTIVE
Issuer:
Let's Encrypt
Expires:
2026-11-20
Days Remaining:
99
If near expiration:
Status:
WARNING
22. DNS Summary
DNS
---
A Record:
CORRECT
Server:
YOUR_SERVER_IP
Resolved:
YOUR_SERVER_IP
If different:
A Record:
DRIFT
23. Backup Summary
Don’t list every backup.
Show:
Backups
-------
Latest:
2026-08-13 02:00
Count:
12
Verified:
12
Status:
HEALTHY
If:
Verified:
9 / 12
show:
Status:
WARNING
24. Backup Age
A very useful metric is:
Latest Backup Age:
14 hours
Suppose policy says:
< 24 hours:
HEALTHY
24–48 hours:
WARNING
> 48 hours:
DEGRADED
Then status can be calculated.
This policy should eventually be configurable per hosting plan.
25. Resource Summary
Display:
Resources
---------
Disk:
65%
Memory Available:
8.2 GB
Load:
0.42
Status:
HEALTHY
If disk is high:
Disk:
91%
Status:
WARNING
26. WordPress Summary
For WordPress:
WordPress
---------
Version:
6.8.2
Installation:
HEALTHY
Database:
HEALTHY
Core:
INSTALLED
Don’t display sensitive configuration.
27. PHP Summary
PHP
---
Configured:
8.3
Running:
8.3
Service:
HEALTHY
Socket:
AVAILABLE
If drift:
Configured:
8.3
Running:
8.2
Configuration:
DRIFT
Runtime:
HEALTHY
28. Nginx Summary
Nginx
-----
Service:
HEALTHY
Configuration:
VALID
Site:
LOADED
This combines reconciliation and health information.
29. Recent Operations
Show the last few operations:
Recent Operations
-----------------
2026-08-13 14:20
RECONCILE
DRIFT
2026-08-13 13:00
HEALTH CHECK
HEALTHY
2026-08-13 02:00
BACKUP
SUCCESS
2026-08-12 14:00
RECONCILE
MATCH
Only show the last 5–10 records.
30. Why Operations Matter
Suppose the site suddenly becomes unhealthy.
The operator can immediately ask:
What changed?
and see:
14:00 REPAIR
14:01 HEALTH DOWN
This creates a basic operational timeline.
31. Final Summary
At the bottom:
Overall Status
--------------
Configuration:
DRIFT
Runtime:
HEALTHY
Backups:
HEALTHY
SSL:
HEALTHY
Resources:
HEALTHY
FINAL:
WARNING
32. Status Colors
For a future web interface:
HEALTHY → green
WARNING → yellow
DEGRADED → orange
DOWN → red
UNKNOWN → gray
Don’t hard-code terminal colors into the underlying health logic.
The CLI presentation layer can add colors later.
33. JSON Output
Support:
sudo hosting-site-status example.com --json
Example:
{
"site": {
"id": 7,
"domain": "example.com",
"application": "WORDPRESS",
"management": "VERIFIED"
},
"configuration": {
"status": "DRIFT"
},
"runtime": {
"status": "HEALTHY"
},
"ssl": {
"status": "HEALTHY"
},
"dns": {
"status": "HEALTHY"
},
"backups": {
"status": "HEALTHY"
},
"resources": {
"status": "HEALTHY"
},
"overall": "WARNING"
}
34. This JSON Becomes the API Contract
Later the CHP web panel can consume:
hosting-site-status --json
or, preferably, call the same internal library/API.
The web dashboard should not scrape human-readable terminal output.
35. Don’t Duplicate Business Logic
Bad architecture:
CLI
└── own health calculations
Web Panel
└── different health calculations
API
└── another health calculation
Better:
CHP Core
│
┌─────────┼─────────┐
▼ ▼ ▼
CLI API Dashboard
All use the same status engine.
36. Build a Status Library
Create:
sudo nano /etc/cresignsys/lib/status.sh
Functions:
calculate_runtime_status
calculate_configuration_status
calculate_backup_status
calculate_resource_status
calculate_overall_status
37. Overall Status Function
Conceptually:
calculate_overall_status() {
local runtime="$1"
local config="$2"
local backup="$3"
local resources="$4"
# Critical runtime failure wins.
if [[ "$runtime" == "DOWN" ]]; then
echo "DOWN"
return
fi
if [[ "$runtime" == "DEGRADED" ]]; then
echo "DEGRADED"
return
fi
if [[ "$runtime" == "WARNING" ||
"$config" == "DRIFT" ||
"$backup" == "WARNING" ||
"$resources" == "WARNING" ]]; then
echo "WARNING"
return
fi
echo "HEALTHY"
}
This is only the first policy.
38. Don’t Make UNKNOWN Look Healthy
If:
DNS:
UNKNOWN
and:
HTTPS:
UNKNOWN
the final state should not be:
HEALTHY
Use:
UNKNOWN
or:
WARNING
depending on which critical checks could not be performed.
39. Critical Check Policy
Define:
Critical:
DNS
HTTPS
HTTP
for public sites.
If all three are:
UNKNOWN
then:
OVERALL:
UNKNOWN
rather than claiming the site is healthy.
40. Management State Does Not Equal Health
This distinction is critical.
A site can be:
Management:
READ_ONLY
Health:
HEALTHY
or:
Management:
MANAGED
Health:
DOWN
Management state describes CHP’s authority.
Health describes runtime condition.
41. Example
Site:
example.com
Management:
READ_ONLY
Configuration:
MATCH
Runtime:
HEALTHY
Overall:
HEALTHY
This is perfectly valid.
42. Example Managed Site
Site:
shop.example.com
Management:
MANAGED
Configuration:
MATCH
Runtime:
DOWN
Overall:
DOWN
CHP has management permission, but the site is currently unavailable.
43. Security State
Don’t include security in overall health yet.
Eventually:
Health:
HEALTHY
Security:
WARNING
For example:
SSL:
valid
WordPress:
outdated
The site can still be operational.
44. Four Operational Dimensions
The eventual dashboard should have:
┌────────────────────────────────┐
│ example.com │
├────────────────────────────────┤
│ Runtime HEALTHY │
│ Configuration DRIFT │
│ Backups HEALTHY │
│ Security WARNING │
└────────────────────────────────┘
This is more useful than a single status.
45. hosting-info vs hosting-site-status
Use:
hosting-info example.com
for:
metadata
Use:
hosting-site-status example.com
for:
current operational condition
Use:
hosting-reconcile example.com
for:
configuration investigation
Use:
hosting-health example.com
for:
runtime investigation
46. Command Map
hosting-info
│
└── WHAT IS THIS SITE?
hosting-site-status
│
└── HOW IS THIS SITE NOW?
hosting-reconcile
│
└── DOES CONFIG MATCH?
hosting-health
│
└── IS IT WORKING?
hosting-db-import
│
└── HOW DO WE REGISTER IT?
47. Site Status API Model
Eventually the same structure can be represented as:
{
"site_id": 7,
"domain": "example.com",
"runtime_status": "HEALTHY",
"configuration_status": "DRIFT",
"backup_status": "HEALTHY",
"security_status": "WARNING",
"overall_status": "WARNING"
}
This becomes the central object for the CHP dashboard.
48. Database View
Later you can create a view:
CREATE VIEW site_status_summary AS
SELECT
s.id,
s.primary_domain,
s.management_state,
s.service_state,
s.health_state
FROM sites s;
But don’t put transient calculations permanently into sites.
The site record should contain durable metadata.
49. Durable vs Temporary Data
Durable
domain
web_root
site_user
application_type
management_state
Observed
PHP currently running
certificate currently valid
HTTP response time
disk usage
Historical
health checks
operations
backups
reconciliation events
Keep these concepts separate.
50. Status Data Model
SITE
│
├── configuration metadata
│
├── current health
│
├── health history
│
├── configuration history
│
├── backup history
│
└── operation history
This will scale much better as CHP grows.
51. Test the Command
First:
sudo chmod +x /usr/local/bin/hosting-site-status
Then:
sudo hosting-site-status learn.cresignsys.com
Then:
sudo hosting-site-status learn.cresignsys.com --json
52. Test Healthy Site
Expected:
Runtime:
HEALTHY
Configuration:
MATCH
Backups:
HEALTHY
Resources:
HEALTHY
Overall:
HEALTHY
53. Test Configuration Drift
Change nothing on the server.
Use an existing difference, if available.
Expected:
Runtime:
HEALTHY
Configuration:
DRIFT
Overall:
WARNING
54. Test Runtime Failure Safely
Do not stop production services merely to test the health engine.
Instead use a controlled test environment or temporary test site.
For example:
test.example.com
can deliberately return:
HTTP 500
Then:
hosting-health test.example.com
should detect:
DOWN
55. Never Test by Breaking Production
Avoid:
systemctl stop nginx
on a live production site just to test monitoring.
CHP should be developed with:
test site
staging environment
for failure simulations.
56. Site Status Example
A polished result could look like:
╔══════════════════════════════════════════╗
║ CRESIGNSYS SITE STATUS ║
╠══════════════════════════════════════════╣
║ Site: learn.cresignsys.com ║
║ App: WordPress ║
║ Mode: VERIFIED ║
╠══════════════════════════════════════════╣
║ RUNTIME HEALTHY ║
║ CONFIGURATION MATCH ║
║ SSL HEALTHY ║
║ DNS HEALTHY ║
║ BACKUPS HEALTHY ║
║ RESOURCES HEALTHY ║
╠══════════════════════════════════════════╣
║ OVERALL HEALTHY ║
╚══════════════════════════════════════════╝
The exact visual formatting can be improved later.
57. Why This Command Is Important
Previously, you had to run:
hosting-info
hosting-health
hosting-reconcile
hosting-backup
separately.
Now:
hosting-site-status example.com
becomes the single operational entry point.
58. Future Control Panel
This command maps directly to a web dashboard:
┌─────────────────────────────────────────┐
│ CresignSys Hosting Platform │
├─────────────────────────────────────────┤
│ │
│ Sites │
│ │
│ example.com HEALTHY │
│ learn.com WARNING │
│ shop.com DOWN │
│ blog.com HEALTHY │
│ │
└─────────────────────────────────────────┘
Click:
shop.com
and show:
Runtime
Configuration
SSL
DNS
Backups
Resources
Operations
59. The CHP Control Loop
We now have a complete observation loop:
EXISTING SERVER
│
▼
DISCOVERY
│
▼
CHP DATABASE
│
▼
RECONCILIATION
│
▼
CONFIG STATE
│
▼
HEALTH
│
▼
RUNTIME STATE
│
▼
SITE STATUS
The next stage is where CHP becomes a real hosting management platform:
SITE STATUS
│
▼
DETECT PROBLEM
│
▼
CREATE REPAIR PLAN
│
▼
VALIDATE
│
▼
APPLY CHANGE
│
▼
VERIFY
60. Lesson 083 — Core Principle
The unified status command must not hide complexity.
It should summarize it.
For example:
OVERALL:
WARNING
must still allow the operator to see:
Why?
Configuration:
DRIFT
PHP:
Expected 8.3
Actual 8.2
Runtime:
HEALTHY
That makes CHP operationally useful rather than just another dashboard showing red and green indicators.
Next Lesson — 084
Build the CHP Repair Engine — Safely
Now we can begin the write side of CHP.
The first repair engine should not immediately change anything.
We will build:
sudo hosting-repair-plan example.com
which converts detected drift into a proposed repair plan:
DRIFT
↓
ANALYZE
↓
PROPOSE
↓
SHOW EXACT CHANGES
↓
VALIDATE
↓
APPROVAL REQUIRED
For example:
PHP VERSION DRIFT
Expected:
8.3
Actual:
8.2
Proposed repair:
Update Nginx site configuration
from PHP 8.2-FPM
to PHP 8.3-FPM
Files affected:
1 Nginx configuration
Services affected:
Nginx
Rollback:
Available
Risk:
MEDIUM
NO CHANGES HAVE BEEN MADE
This will establish the most important rule for CHP’s write operations:
Never change the server directly from a detected problem. First generate a repair plan, validate it, and only then apply it.
Leave a Reply