Downloads

Download ColdFusion Health Check & Status Endpoint Example

Introduction

This downloadable resource provides a complete, production-ready example of a ColdFusion Health check and Status endpoint. It includes a Lightweight CFML implementation for liveness, readiness, and detailed status checks that return clean JSON for monitoring tools, load balancers, and Kubernetes probes. Whether you’re running Adobe ColdFusion or Lucee, this example helps you expose standardized endpoints that verify application health, dependencies (database, cache, filesystem), and environment Configuration—saving you hours of wiring, testing, and documentation.


What You’ll Get

  • A zip package named cf-healthcheck-example.zip containing:
    • /health/health.cfm – consolidated liveness/readiness/Status endpoint
    • /health/_checks.cfc – modular checks (DB, cache, disk, HTTP, custom)
    • /health/config.json – toggle checks, thresholds, and secrets references
    • /Application.cfc – route mapping and minimal Security headers
    • /lib/json.cfc – helper to format consistent JSON output
    • /examples/ – sample datasource query, Redis ping, S3 ping, and HTTP ping
    • /docs/ – brief setup guide, environment variables mapping, curl recipes
  • Code that works on both Adobe ColdFusion (2018/2021/2023) and Lucee 5.x/6.x
  • JSON response patterns for /health, /ready, and /live endpoints
  • Sample Kubernetes probe specs and load balancer Health check configs
  • Optional basic-auth and IP allowlist examples for securing endpoints

Overview

The package implements three common health endpoints:

  • /live – quick “is the CF engine and app loop alive?” check
  • /ready – verifies dependencies needed to accept traffic (datasource, cache)
  • /health (or /status) – a detailed, human-readable JSON status for observability and support

These endpoints return proper HTTP status codes (200 OK on pass, 503 Service Unavailable on fail) and structured JSON with component-level results, timing, and an overall state.

Supported Environments

  • Application servers:
    • Adobe ColdFusion 2018, 2021, 2023
    • Lucee 5.x, 6.x
  • Java/Tomcat:
    • Bundled CF Tomcat, standalone Tomcat 8.5–10.x
  • Web servers:
  • Platforms:
    • Bare metal, VMs, Docker, Kubernetes (K8s), AWS ECS, Azure App Service

File Contents

  • health/health.cfm – single entry point; routes /live, /ready, /health
  • health/_checks.cfc – CFScript component with public functions:
    • checkEngine()
    • checkDatasource(name)
    • checkRedis(host, port, password)
    • checkDisk(path, minFreeMB)
    • checkHTTP(url, timeout)
    • checkS3(bucket)
    • checkCustom(closure)
  • health/config.json – enables/disables checks, timeouts, thresholds
  • Application.cfc – maps /health path, sets no-cache headers
  • lib/json.cfc – stringify/indent JSON with consistent schema
  • examples/*.cfm – per-check examples you can copy into your app
  • docs/SETUP.md – short install and Security notes
See also  Download ColdFusion to Lucee Migration Project Template

How It Works

The /health/health.cfm file inspects the URL path to determine which mode to run (live, ready, or health). It calls _checks.cfc functions to perform dependency checks and then aggregates results into one JSON document.

  • Liveness checks: engine running, request cycle operational
  • Readiness checks: Database connectivity, cache ping, disk space, critical HTTP upstream
  • Full health: includes version info, build number, environment name, and timings

Response Format

  • HTTP 200 when all selected checks pass; 503 when any required check fails
  • JSON fields:
    • status: “UP” or “DOWN”
    • service: app name, version, build
    • timestamp: ISO-8601
    • durationMs
    • checks: array of objects with name, status, details, durationMs
    • meta: environment, region, node, commit SHA

Example JSON:
{
“status”: “UP”,
“service”: {“name”: “orders-api”, “version”: “2.3.7”, “build”: “2025-09-20”},
“timestamp”: “2025-09-20T12:45:08Z”,
“durationMs”: 38,
“checks”: [
{“name”: “engine”, “status”: “UP”, “durationMs”: 1},
{“name”: “datasource:PrimaryDSN”, “status”: “UP”, “durationMs”: 12},
{“name”: “redis:cache”, “status”: “UP”, “durationMs”: 5},
{“name”: “disk:/mnt/data”, “status”: “UP”, “details”: {“freeMB”: 20480}, “durationMs”: 2}
],
“meta”: {“env”: “prod”, “region”: “us-east-1”, “node”: “app-3”, “commit”: “c4f1a2d”}
}


Installation

Follow these steps to add the endpoints to an existing ColdFusion or Lucee app.

Step 1: Copy Files

  • Unzip cf-healthcheck-example.zip into your webroot or your app root.
  • Ensure the /health directory is accessible via your web server route.

Step 2: Map the Route (if needed)

  • If you use Application.cfc URL routing, include or merge the provided Application.cfc route that maps /health/* to /health/health.cfm.
  • Alternatively, set a web server rewrite to forward /health, /ready, /live to /health/health.cfm?mode=health|ready|live.

Step 3: Configure Datasources and Environment

  • In CF Administrator (ACF) or Lucee admin, define your datasource (e.g., PrimaryDSN).
  • Set environment variables or a config file:
    • APP_ENV, APP_NAME, APP_VERSION, APP_BUILD
    • HEALTHCHECK_REQUIRED_DSN=PrimaryDSN
    • HEALTHCHECK_MIN_FREE_MB=1024
    • HEALTHCHECK_REDIS_HOST=redis
    • HEALTHCHECK_REDIS_PASSWORD=… (store securely)

Step 4: Harden Access (recommended)

  • Allowlist by IP for /health if exposing detailed data.
  • Enable Basic Auth on /health for non-probe uses; keep /live and /ready open to load balancers.
  • Set Cache-Control: no-store on all health responses.

Step 5: Verify


Configuration

Use health/config.json to toggle checks without changing code. Example:

{
“service”: {“name”: “orders-api”, “version”: “2.3.7”, “build”: “2025-09-20”},
“meta”: {“envVarPrefix”: “APP_”},
“checks”: {
“engine”: true,
“datasource”: {“required”: true, “name”: “PrimaryDSN”, “timeoutMs”: 2000},
“redis”: {“enabled”: true, “host”: “${HEALTHCHECK_REDIS_HOST}”, “password”: “${HEALTHCHECK_REDIS_PASSWORD}”, “timeoutMs”: 1000},
“disk”: {“enabled”: true, “path”: “/mnt/data”, “minFreeMB”: 1024},
“upstream”: {“enabled”: false, “url”: “https://api.example.com/ping“, “timeoutMs”: 1500}
}
}

  • ${ENV_VAR} placeholders are read from the process environment.
  • Mark “required” checks to influence /ready result.
  • “enabled” controls inclusion in /health.
See also  Download the ColdFusion Scopes Quick Reference (PDF)

Usage

Kubernetes examples:

readinessProbe:
httpGet:
path: /ready
port: 8500
initialDelaySeconds: 10
periodSeconds: 5
timeoutSeconds: 2
failureThreshold: 3

livenessProbe:
httpGet:
path: /live
port: 8500
initialDelaySeconds: 30
periodSeconds: 10

AWS ALB Target Group:

  • Protocol: HTTP
  • Path: /live
  • Matcher: 200
  • Interval: 15s, Timeout: 5s, Healthy threshold: 2

Code Examples (CFML)

Minimal health.cfm (CFScript style):


mode = lcase(trim(url.mode ?: listLast(cgi.path_info,’/’)));
if (!len(mode)) mode = “health”;
checks = createObject(“component”,”health._checks”);
result = checks.run(mode);
statusCode = (result.status eq “UP”) ? 200 : 503;
cfheader(statusCode=statusCode);
cfheader(name=”Content-Type”, value=”application/json; charset=utf-8″);
writeOutput( createObject(“component”,”lib.json”).stringify(result) );

Sample _checks.cfc excerpt:

component output=”false” {

public struct function run(required string mode) {
var out = {status=”UP”, service=getService(), timestamp=toString(now()), checks=[], meta=getMeta()};
var started = getTickCount();

arrayAppend(out.checks, time("engine", function(){ return checkEngine(); }));

if (mode neq "live") {
  arrayAppend(out.checks, time("datasource:PrimaryDSN", function(){ return checkDatasource("PrimaryDSN"); }));
  arrayAppend(out.checks, time("disk:/mnt/data", function(){ return checkDisk("/mnt/data", 1024); }));
}

out.status = arrayFind(out.checks, function(c){ return c.status eq "DOWN"; }) ? "DOWN" : "UP";
out.durationMs = getTickCount() - started;
return out;

}

private struct function time(string name, any fn){
var t = getTickCount();
var ok = true;
var details = {};
try { details = fn(); }
catch(any e){ ok=false; details={“error”: e.message}; }
return {name=name, status=(ok?”UP”:”DOWN”), details=details, durationMs=(getTickCount()-t)};
}

public struct function checkEngine(){ return {“engine”: server.coldfusion.productname, “version”: server.coldfusion.productversion}; }

public struct function checkDatasource(required string name){
var q = queryExecute(“SELECT 1”, [], {datasource: name, timeout: 2});
return {“rows”: q.recordcount};
}

public struct function checkDisk(required string path, numeric minFreeMB){
var free = int(getFreeSpace(path)/1024/1024);
if (free lt minFreeMB) throw(message=”Low disk space”);
return {“freeMB”: free};
}
}

Application.cfc route snippet:

this.mappings[“/health”] = expandPath(“./health”);


Best practices

Security

  • Restrict detailed endpoints:
    • Keep /live and /ready open to infra probes; secure /health via Basic Auth or IP allowlist.
  • Avoid leaking secrets:
    • Do not echo connection strings, keys, or stack traces; return generic errors.
  • Add Rate limiting at the web server or WAF level.

Performance

  • Keep checks fast and non-blocking:
    • Set timeouts (1–2 seconds) for DB/cache/HTTP.
    • Use HEAD or lightweight queries (SELECT 1).
  • Cache static info (service version) in memory.

Reliability

  • Separate liveness from readiness:
    • Liveness should be minimal; readiness includes dependencies that must be available.
  • Fail closed with correct HTTP 503 when a required dependency is down.
  • Log transitions UP→DOWN and DOWN→UP for alerting hygiene.

Benefits and Use Cases

  • Faster rollout: plug-and-play endpoints without reinventing status checks.
  • Improved uptime and SLOs: precise readiness prevents sending traffic to unready nodes.
  • Seamless Integration with monitoring: standardized JSON consumed by Prometheus, Datadog, New Relic, or UptimeRobot.
  • Safer deployments: use readiness to coordinate blue/green or canary releases.
  • Cross-platform compatibility: same CFML works on Adobe ColdFusion and Lucee, on VMs or containers.
See also  Download ColdBox Starter App for ColdFusion

Use cases:

  • Kubernetes liveness/readiness probes for Microservices written in CFML
  • AWS ALB/NLB or HAProxy health checks for autoscaling groups
  • On-call diagnostics via detailed /health JSON during incidents
  • CI/CD smoke tests post-deploy before flipping traffic

Supported Environments (Quick Matrix)

  • Adobe ColdFusion: 2018, 2021, 2023 (Windows/Linux/macOS)
  • Lucee: 5.x, 6.x
  • Web servers: IIS 10+, Apache 2.4+, NGINX (Reverse proxy)
  • Containers: Docker, Kubernetes, ECS, AKS, GKE
  • Datastores (examples provided): MySQL, SQL Server, Postgres (via DSN), Redis, S3-compatible storage

Troubleshooting

  • Receiving 503 on /ready:
    • Verify datasource credentials and that SELECT 1 works in CF Admin.
    • Increase timeoutMs for slow networks.
  • JSON malformed:
    • Ensure no extraneous output (cfoutput/cfdump) before headers.
  • Access denied:
    • Check IP allowlist and Basic Auth configuration; try from an allowed source.
  • On Lucee with strict mode:
    • Enable this.mappings in Application.cfc; confirm component loads via /health mapping.
  • Probes flapping:
    • Lengthen failureThreshold and initialDelaySeconds; log dependency latencies.

Key Takeaways

  • Implement three tiers: /live (minimal), /ready (dependencies), /health (detailed).
  • Return accurate HTTP statuses and fast, small JSON responses.
  • Secure detailed status while keeping probe endpoints accessible.
  • Make checks configurable via config.json and environment variables.
  • Integrate with Kubernetes, ALB/ELB, and your monitoring stack easily.

FAQ

How do I add a new custom check?

Create a function in _checks.cfc (e.g., checkQueue()) and wrap it with the time() helper. Add config to config.json so you can enable or disable it without code changes. Return small detail objects and throw on failure to mark DOWN.

Can I expose only /ready and hide /health?

Yes. Route or rewrite /live and /ready as public endpoints. Protect /health behind Basic Auth or IP allowlist. You can also disable detailed checks in config.json to minimize output.

Does this work with both Adobe ColdFusion and Lucee?

Yes. The code avoids vendor-specific tags and relies on CFScript/QueryExecute that both engines support. Where behaviors differ (e.g., server scope keys), the checks are defensive.

How should I check databases that don’t support SELECT 1?

Use a vendor-neutral lightweight query. For SQL Server: SELECT 1; for MySQL: SELECT 1; for Oracle: SELECT 1 FROM dual. Adjust the sample query per your database driver.

Can I export metrics for Prometheus?

The package focuses on JSON health. For Prometheus, add a /metrics endpoint that translates check timings into text format (e.g., gauge for durations, 1/0 for status) or have your sidecar scrape /health and map results into metrics.

About the author

Aaron Longnion

Aaron Longnion

Hey there! I'm Aaron Longnion — an Internet technologist, web software engineer, and ColdFusion expert with more than 24 years of experience. Over the years, I've had the privilege of working with some of the most exciting and fast-growing companies out there, including lynda.com, HomeAway, landsofamerica.com (CoStar Group), and Adobe.com.

I'm a full-stack developer at heart, but what really drives me is designing and building internet architectures that are highly scalable, cost-effective, and fault-tolerant — solutions built to handle rapid growth and stay ahead of the curve.