First:
As far as I have seen, there is no way to tell the Docker Engine to get something else than a "stream" as a response, because it´s the nature of some Docker calls, for example, if you "attach" to a running container, the output can be endless so it´s not a "one call->wait 2 seconds->get response" - because containers can run forever, so the output can be endless long.
Secondly:
Removing the binary string with a simple regex is working like explained here.
Finally:
How to read the Stream with PHP?
Using Guzzle is in most cases the easiest way to handle HTTP calls with PHP.
<?php
$response = $client->request('POST', '/exec/' . $id . '/start', [
'json' => [
"Detach" => false,
"Tty" => false,
],
'stream' => true // <---------- THIS IS THE IMPORTANT PART HERE
]);
The Docker Engine Documentation clearly explains how to read the Stream:
The simplest way to implement this protocol is the following:
- Read 8 bytes.
- Choose stdout or stderr depending on the first byte.
- Extract the frame size from the last four bytes.
- Read the extracted size and output it on the correct output.
- Goto 1.
So with the Help of an old PHP Package, that shows how it's done, I
was able to finally get a "clear" output:
$body = $response->getBody();
$str = '';
do {
$strToUnpack = $body->read(8);
if (strlen($strToUnpack)) {
$decoded = \unpack('C1type/C3/N1size', $strToUnpack);
if ($decoded) {
$str = $body->read($decoded['size']);
echo $str . "\n";
}
}
} while (!$body->of());