38 lines
1.4 KiB
Markdown
38 lines
1.4 KiB
Markdown
---
|
|
id: e9abb352-ae92-4714-9b07-5ee6568953d5
|
|
type: fix
|
|
title: "Fix: Docker healthcheck - use node -e when container lacks wget/curl"
|
|
tags: [docker, healthcheck, troubleshooting, homelab, nodejs, fix]
|
|
importance: 0.6
|
|
confidence: 0.8
|
|
created: "2026-02-20T17:09:36.080059+00:00"
|
|
updated: "2026-02-20T17:09:36.080059+00:00"
|
|
---
|
|
|
|
# Fix: Docker Healthcheck Binary Missing in Container Image
|
|
|
|
## Problem
|
|
A Docker container (Termix, `ghcr.io/lukegus/termix:latest`) was perpetually unhealthy. The `HEALTHCHECK` directive used `wget`, but the image had neither `wget` nor `curl` installed.
|
|
|
|
## Diagnosis
|
|
When a container is stuck in `unhealthy` state, verify the binary used in the `HEALTHCHECK` actually exists in the image.
|
|
|
|
## Fix
|
|
Replace the `wget`-based healthcheck with one using the app runtime (Node.js in this case):
|
|
|
|
```yaml
|
|
healthcheck:
|
|
test: ["CMD", "node", "-e", "require('http').get('http://localhost:PORT', r => process.exit(r.statusCode === 200 ? 0 : 1)).on('error', () => process.exit(1))"]
|
|
interval: 30s
|
|
timeout: 10s
|
|
retries: 3
|
|
```
|
|
|
|
Replace `PORT` with the actual port the app listens on.
|
|
|
|
## Important
|
|
- `docker compose restart` does NOT pick up compose file changes — must run `docker compose up -d` to recreate the container.
|
|
|
|
## General Pattern
|
|
For Node.js apps without curl/wget, use the Node.js HTTP module directly in the healthcheck. Adapts to any language runtime available in the image (python3 -c, etc.).
|