Skip to content

Commit e90f847

Browse files
committed
Cover health endpoint env activation
1 parent b876f08 commit e90f847

3 files changed

Lines changed: 25 additions & 1 deletion

File tree

docs/oss/building-features/node-renderer/health-checks.md

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -124,7 +124,10 @@ gating readiness on `/ready` deadlocks the rollout: no traffic → no first rend
124124

125125
Only use `/ready` as the readiness gate when something other than probe-gated traffic delivers the first render,
126126
for example a deployment pipeline step or Rails initializer that POSTs a warm-up render to each new replica
127-
directly (bypassing the Service), or a container `postStart` hook that does the same. With a warm-up path in place:
127+
directly (bypassing the Service), or a container `postStart` hook that does the same. That warm-up must reach
128+
every renderer worker that can answer probes; with `workersCount > 1`, one render per replica is not enough
129+
unless you intentionally run a single worker or fan out warm-up renders to each worker. With a warm-up path in
130+
place:
128131

129132
```yaml
130133
readinessProbe:

packages/react-on-rails-pro-node-renderer/src/shared/configBuilder.ts

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -410,6 +410,7 @@ export function buildConfig(providedUserConfig?: Partial<Config>): Config {
410410
password: env.RENDERER_PASSWORD,
411411
// Re-evaluate env-derived defaults at build time in case env vars are set post-import.
412412
replayServerAsyncOperationLogs: defaultReplayServerAsyncOperationLogs(),
413+
enableHealthEndpoints: truthy(env.RENDERER_ENABLE_HEALTH_ENDPOINTS),
413414
};
414415
config = { ...runtimeDefaultConfig, ...userConfig };
415416
if (explicitUndefinedPassword) {

packages/react-on-rails-pro-node-renderer/tests/healthEndpoints.test.ts

Lines changed: 20 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -25,6 +25,7 @@ const testName = 'healthEndpoints';
2525
const gemVersion = packageJson.version;
2626
const { protocolVersion } = packageJson;
2727
const railsEnv = 'test';
28+
const originalEnableHealthEndpointsEnv = process.env.RENDERER_ENABLE_HEALTH_ENDPOINTS;
2829

2930
disableHttp2();
3031

@@ -58,6 +59,7 @@ describe('built-in health endpoints', () => {
5859
let app: ReturnType<typeof createWorker> | undefined;
5960

6061
beforeEach(async () => {
62+
delete process.env.RENDERER_ENABLE_HEALTH_ENDPOINTS;
6163
await resetForTest(testName);
6264
});
6365

@@ -67,6 +69,11 @@ describe('built-in health endpoints', () => {
6769
});
6870

6971
afterAll(async () => {
72+
if (originalEnableHealthEndpointsEnv === undefined) {
73+
delete process.env.RENDERER_ENABLE_HEALTH_ENDPOINTS;
74+
} else {
75+
process.env.RENDERER_ENABLE_HEALTH_ENDPOINTS = originalEnableHealthEndpointsEnv;
76+
}
7077
await resetForTest(testName);
7178
});
7279

@@ -90,6 +97,19 @@ describe('built-in health endpoints', () => {
9097
expect(JSON.parse(res.payload)).toEqual({ status: 'ok' });
9198
});
9299

100+
test('GET /health and GET /ready are registered when enabled by environment variable', async () => {
101+
process.env.RENDERER_ENABLE_HEALTH_ENDPOINTS = 'true';
102+
app = createWorker();
103+
104+
const healthRes = await app.inject().get('/health').end();
105+
expect(healthRes.statusCode).toBe(200);
106+
expect(JSON.parse(healthRes.payload)).toEqual({ status: 'ok' });
107+
108+
const readyRes = await app.inject().get('/ready').end();
109+
expect(readyRes.statusCode).toBe(503);
110+
expect(JSON.parse(readyRes.payload)).toEqual({ status: 'waiting_for_bundle' });
111+
});
112+
93113
test('GET /ready returns 503 before a bundle is loaded and 200 after', async () => {
94114
app = createWorker({ enableHealthEndpoints: true });
95115

0 commit comments

Comments
 (0)