Rails 7.1+ ships aDocumentation Index
Fetch the complete documentation index at: https://tally.wharflab.com/llms.txt
Use this file to discover all available pages before exploring further.
/up health endpoint by default. The Ruby stdlib’s Net::HTTP is already in the image —
no extra apt-get install curl needed.
| Property | Value |
|---|---|
| Severity | Info |
| Category | Correctness |
| Default | Enabled (advisory) |
| Auto-fix | FixSuggestion (no-edit) |
Description
Rails 7.1 addedRails::HealthController mounted at /up by default. It returns 200 if the app booted
cleanly, 500 otherwise — exactly the right shape for a Docker HEALTHCHECK. Almost no Rails Dockerfile
uses it, and the few that do reach for curl, which forces an extra package install on ruby:*-slim and
ruby:*-alpine bases (where curl is not present by default).
This rule has two flavors:
- Missing
HEALTHCHECKon a Rails 7.1+ runtime stage — recommend adding the canonical Ruby-native one. HEALTHCHECKpresent but usescurlorwget— suggest replacing with the Ruby stdlib equivalent. Especially when the same Dockerfile installscurlonly because the healthcheck needs it (the corpus shows this exact pattern).
- 6 of 196 use
HEALTHCHECKat all. - 2 of 196 target
/up. - Both
/uphealthchecks usecurlagainst aruby:*-slimbase — both then needapt-get install ... curl ...upstream of that line. - 0 of 196 use a Ruby-native healthcheck.
- The final stage is a Rails web-server runtime (Ruby base + ENTRYPOINT/CMD references
rails/puma/unicorn/thrust/rackup/falcon/thin/passenger/iodine). - Variant 1: no
HEALTHCHECKat all. - Variant 2:
HEALTHCHECKpresent and the command starts withcurlorwget.
sidekiq, resque, …) — they don’t expose an HTTP
endpoint, so /up would not respond there.
HEALTHCHECK NONE (the explicit “I have an external orchestrator” signal) is recognized as a deliberate
opt-out and suppresses the rule.
Examples
Before
After
The Ruby-native form uses the stdlibNet::HTTP (already in the image), targets /up (the Rails default),
and uses the JSON exec form so the command runs as execve rather than under /bin/sh -c:
ruby -rnet/http -ekeeps the entire HTTP client in the image’s existing Ruby interpreter — nocurl, nowget, no extra layer.Net::HTTP.get_response(URI('...'))returns aNet::HTTPResponsewhose subclass implementsNet::HTTPSuccessfor any 2xx — so the check succeeds for/up’s200 OKand correctly fails on500(which is whatRails::HealthControllerreturns when the boot fails).- Using
127.0.0.1rather thanlocalhostavoids one DNS lookup per probe and is robust against IPv6-onlylocalhostweirdness inside containers. - The JSON exec form (
["ruby", ...]) means Docker runs the command directly viaexecverather than spawning/bin/sh -c. This matters more forHEALTHCHECKthanCMDbecause healthchecks run on every interval — the per-invocation shell startup adds up.
Auto-fix
FixSuggestion (no-edit). Description names the canonical Ruby-native form. Variant 2 (curl/wget present)
also notes that the user can drop the apt-get install curl line if it was added solely for the
healthcheck.