Skip to content

Fix broken and outdated README examples - #606

Open
tas50 wants to merge 1 commit into
upserve:masterfrom
tas50:fix-readme-examples
Open

Fix broken and outdated README examples#606
tas50 wants to merge 1 commit into
upserve:masterfrom
tas50:fix-readme-examples

Conversation

@tas50

@tas50 tas50 commented Aug 23, 2026

Copy link
Copy Markdown
Contributor

Audited every example in the README against a live Docker daemon. All ten Ruby blocks now parse under ruby -c; three did not before.

Syntax errors

container.update("CpuShares" => 50000") unbalanced quote
Docker::Event.stream({ read_timeout: 60 * 60 * 24) }) stray paren
pasted command output inside ruby blocks bare tokens (a tar dump, event to_s lines, streaming log lines) — now commented

Wrong documented return values

Each checked against a running daemon:

  • image.save('my_export.tar') returns nil, not a Docker::Image. Image#save only returns a String when no filename is given.
  • container.run('pwd', 10) returns a Docker::Container, not a Docker::Image. It commits the container and runs the command in the resulting image, and Image#run returns a Container.
  • image.remove(:force => true) returns the raw response body, not true.

Event read timeouts

The first argument to Event.stream and Event.since is the query parameter hash for /events, not Excon options. So the documented

Docker::Event.stream({ read_timeout: 0 }) { |event| ... }

sent read_timeout=0 to Docker as a query parameter and left the timeout entirely untouched. I confirmed this by tracing the call:

path   = "/events"
QUERY  = {read_timeout: 0}
EXCON  = {}

The section now documents setting it on the connection, which does work. It also notes that the global Docker.options[:read_timeout] = ... form only takes effect if set before the default connection is first used — Docker.connection is memoized, and Connection#initialize copies the options hash for unix sockets, so mutating it afterwards is silently ignored.

A code bug this turned up

container.exec(['date'], stderr: false) was documented as returning only stdout. It does not. Container#exec computes

stderr = options.delete(:stderr) || !detach

so passing stderr: false yields false || truetrue, and stderr is still captured. Verified:

stdout=["O\n"] stderr=["E\n"] -> NOT SUPPRESSED

I replaced the example with destructuring the documented [stdout, stderr, exit_code] return value rather than papering over it. Fixing the actual behaviour is a code change rather than a docs one, so I have left it alone here — happy to follow up separately if you would like stderr: false to work as advertised.

Stale references

  • The base image no longer exists on Docker Hub (pull access denied for base, repository does not exist). Four examples used it; switched to debian:stable, which is what the specs use.
  • sudo docker -d fails with unknown shorthand flag: 'd'. Now dockerd.
  • The docker_remote_api_v1.14 doc links 404.
  • docker images <IMAGE.ID> is not the equivalent of Image.get, which hits /images/{id}/json. That is docker inspect.
  • ubuntu:14.04 went EOL in 2019; use 24.04.
  • Dropped the "meant to interface with Docker version 1.4.*" claim. The gem sends no API version prefix, so requests use the daemon's default.

Verification

Every corrected example was run against Docker 29.7.2 (API 1.55):

build FROM debian:stable (corrected)           OK 85e9a8522968
create Image=>debian:stable (corrected)        OK
image.save(file) => nil (corrected)            nil
container.run => Container (corrected)         Docker::Container
exec destructure (corrected)                   ["Sun Aug 23 18:44:07 UTC 2026\n"]
Event conn w/ read_timeout (corrected)         OK first event="create"
ubuntu:24.04 pull (corrected)                  OK

Docs only — no library code is touched.

Audited every example in the README against a live daemon. All ten Ruby
blocks now parse under `ruby -c`; three did not before.

Syntax errors:

- `container.update("CpuShares" => 50000")` had an unbalanced quote.
- `Docker::Event.stream({ read_timeout: 60 * 60 * 24) })` had a stray
  paren.
- Pasted command output (a tar dump, event to_s lines, streaming log
  lines) sat inside ruby blocks as bare tokens. Commented out.

Wrong documented return values, all checked against a running daemon:

- `image.save('my_export.tar')` returns nil, not a Docker::Image.
  Image#save only returns a String when no filename is given.
- `container.run('pwd', 10)` returns a Docker::Container, not a
  Docker::Image. It commits the container and runs the command in the
  resulting image, and Image#run returns a Container.
- `image.remove(:force => true)` returns the raw response body, not true.

Event read timeouts. The first argument to Event.stream and Event.since
is the query parameter hash for /events, not Excon options, so
`Event.stream({ read_timeout: 0 })` sent read_timeout=0 to Docker as a
query parameter and left the timeout untouched. Documented setting it on
the connection instead. Also noted that the global
`Docker.options[:read_timeout] = ...` form only takes effect if set
before the default connection is first used, since Docker.connection is
memoized and Connection#initialize copies the options hash.

`container.exec(['date'], stderr: false)` was documented as returning
only stdout. It does not: Container#exec computes stderr as
`options.delete(:stderr) || !detach`, so passing false still resolves to
true and stderr is captured. Replaced with destructuring the documented
[stdout, stderr, exit_code] return value. The underlying behaviour looks
like a bug, but that is a code change rather than a docs one, so it is
left alone here.

Stale references:

- The `base` image no longer exists on Docker Hub ("pull access denied
  for base, repository does not exist"). Four examples used it; switched
  to debian:stable, which is what the specs use.
- `sudo docker -d` fails with "unknown shorthand flag: 'd'". Now dockerd.
- The docker_remote_api_v1.14 doc links 404.
- `docker images <IMAGE.ID>` is not the equivalent of Image.get, which
  hits /images/{id}/json. That is docker inspect.
- ubuntu:14.04 went EOL in 2019; use 24.04.
- Dropped the "meant to interface with Docker version 1.4.*" claim. The
  gem sends no API version prefix, so requests use the daemon default.
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant