Hi Iain, I think the health check in the example is buggy? At least running it directly (in the server container) produces a type error because process.exit
wants a number, not a boolean. A sly ? 1 : 0
appears to fix it. Shell output attached.
niklas@speckle-dev-server-newest-version:/opt/speckle$ docker compose exec -it speckle-server /nodejs/bin/node -e "console.log('test')"
test
niklas@speckle-dev-server-newest-version:/opt/speckle$ docker compose exec -it speckle-server /nodejs/bin/node -e "try { require('node:http').request({headers: {'Content-Type': 'application/json'}, port:3000, hostname:'0.0.0.0', path:'/readiness', method: 'GET', timeout: 2000 }, (res) => { body = ''; res.on('data', (chunk) => {body += chunk;}); res.on('end', () => {process.exit(res.statusCode != 200 || body.toLowerCase().includes('error'));}); }).end(); } catch { process.exit(1); }"
node:internal/errors:540
throw error;
^
TypeError [ERR_INVALID_ARG_TYPE]: The "code" argument must be of type number. Received type boolean (false)
at process.set [as exitCode] (node:internal/bootstrap/node:122:9)
at process.exit (node:internal/process/per_thread:189:24)
at IncomingMessage.<anonymous> ([eval]:1:262)
at IncomingMessage.emit (node:events:530:35)
at endReadableNT (node:internal/streams/readable:1698:12)
at process.processTicksAndRejections (node:internal/process/task_queues:90:21) {
code: 'ERR_INVALID_ARG_TYPE'
}
Node.js v22.17.0
niklas@speckle-dev-server-newest-version:/opt/speckle$ docker compose exec -it speckle-server /nodejs/bin/node -e "try { require('node:http').request({headers: {'Content-Type': 'application/json'}, port:3000, hostname:'0.0.0.0', path:'/readiness', method: 'GET', timeout: 2000 }, (res) => { body = ''; res.on('data', (chunk) => {body += chunk;}); res.on('end', () => {process.exit(res.statusCode != 200 || body.toLowerCase().includes('error') ? 1 : 0);}); }).end(); } catch { process.exit(1); }"
niklas@speckle-dev-server-newest-version:/opt/speckle$ echo $?
0
I.e., my full health check in my docker-compose.yml
is:
healthcheck:
test: ["CMD", '/nodejs/bin/node', '-e', "try { require('node:http').request({headers: {'Content-Type': 'application/json'}, port:3000, hostname:'127.0.0.1', path:'/readiness', method: 'GET', timeout: 2000 }, (res) => { body = ''; res.on('data', (chunk) => {body += chunk;}); res.on('end', () => {process.exit(res.statusCode != 200 || body.toLowerCase().includes('error') ? 1 : 0);}); }).end(); } catch { process.exit(1); }"]
interval: 10s
timeout: 10s
retries: 3
I can send a PR on Github if you like.
PS: To be clear, this is also a surprise to me, and if I run Node on my workstation, process.exit(true)
works as expected. So I don’t know exactly what’s going on.