chore(docker): add HEALTHCHECK against /api/health - #1412
Conversation
Uses Node fetch so slim images do not need curl/jq. Fails when the endpoint is unreachable, non-2xx, or status is not ok. Closes papra-hq#691
📝 WalkthroughWalkthroughAdded Node-based Docker health checks to three application Dockerfiles. Each check polls ChangesDocker health checks
Estimated code review effort: 2 (Simple) | ~5 minutes Possibly related PRs
Suggested reviewers: 🚥 Pre-merge checks | ✅ 5✅ Passed checks (5 passed)
Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out. Comment |
There was a problem hiding this comment.
Actionable comments posted: 1
🤖 Prompt for all review comments with AI agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.
Inline comments:
In `@apps/papra-server/Dockerfile`:
- Around line 59-61: Replace the shell-form HEALTHCHECK CMD with exec-form
JSON-array arguments in apps/papra-server/Dockerfile lines 59-61,
packages/app/Dockerfile lines 61-63, and packages/app/Dockerfile.rootless lines
70-72. Preserve the existing node healthcheck script and behavior while invoking
node directly without shell parsing.
🪄 Autofix
Fix all unresolved CodeRabbit comments on this PR:
- Push a commit to this branch (recommended)
- Create a new PR with the fixes
ℹ️ Review info
⚙️ Run configuration
Configuration used: Organization UI
Review profile: ASSERTIVE
Plan: Pro Plus
Run ID: 45d13d4f-5c4a-469d-88ac-26e7669ede2c
📒 Files selected for processing (3)
apps/papra-server/Dockerfilepackages/app/Dockerfilepackages/app/Dockerfile.rootless
| # Validate /api/health (node is in the image; avoids curl/jq on slim) | ||
| HEALTHCHECK --interval=30s --timeout=5s --start-period=20s --retries=3 \ | ||
| CMD node -e "fetch('http://127.0.0.1:'+(process.env.PORT||1221)+'/api/health').then(async r=>{if(!r.ok)process.exit(1);const j=await r.json();process.exit(j.status==='ok'?0:1)}).catch(()=>process.exit(1))" |
There was a problem hiding this comment.
📐 Maintainability & Code Quality | 🔵 Trivial | ⚡ Quick win
Use exec-form arguments for the shared healthcheck.
All three Dockerfiles use shell-form HEALTHCHECK CMD commands. Use the JSON-array form to run node without shell parsing. Docker supports this form for healthchecks. (docs.docker.com)
apps/papra-server/Dockerfile#L59-L61: replace the shell-form command withCMD ["node", "-e", "..."].packages/app/Dockerfile#L61-L63: replace the shell-form command withCMD ["node", "-e", "..."].packages/app/Dockerfile.rootless#L70-L72: replace the shell-form command withCMD ["node", "-e", "..."].
🧰 Tools
🪛 Hadolint (2.15.1)
[warning] 60-60: Use arguments JSON notation for CMD and ENTRYPOINT arguments
(DL3025)
📍 Affects 3 files
apps/papra-server/Dockerfile#L59-L61(this comment)packages/app/Dockerfile#L61-L63packages/app/Dockerfile.rootless#L70-L72
🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.
In `@apps/papra-server/Dockerfile` around lines 59 - 61, Replace the shell-form
HEALTHCHECK CMD with exec-form JSON-array arguments in
apps/papra-server/Dockerfile lines 59-61, packages/app/Dockerfile lines 61-63,
and packages/app/Dockerfile.rootless lines 70-72. Preserve the existing node
healthcheck script and behavior while invoking node directly without shell
parsing.
Source: Linters/SAST tools
Contributor License AgreementThanks for the contribution! Before this pull request can be merged, everyone who contributed to it has to sign the Papra CLA for it. The agreement should be signed per contributions, so signing for earlier work does not cover this one. Still to sign: @xusnitdinov -> Sign the CLA This check re-runs on its own once you have signed. |
Summary
HEALTHCHECKtoapps/papra-server/Dockerfile,packages/app/Dockerfile, andpackages/app/Dockerfile.rootless/api/healthwith Nodefetch(already in the image — nocurl/jqneeded on slim)status !== \"ok\"(covers the 500 DB-unhealthy path)Closes #691
Why this approach
Maintainer note on the issue suggested
curl -f, but these images arenode:*-slimand do not include curl by default. Node 18+fetchkeeps the images unchanged.Test plan
docker buildone of the Dockerfilesdocker inspect→State.Health.Statusbecomeshealthyafter start-periodunhealthyMade with Cursor