Skip to content

Instantly share code, notes, and snippets.

@FergusInLondon
Created April 23, 2018 23:41
Show Gist options
  • Save FergusInLondon/c3eb96f1f6565a81e509ece6b14b9a78 to your computer and use it in GitHub Desktop.
Save FergusInLondon/c3eb96f1f6565a81e509ece6b14b9a78 to your computer and use it in GitHub Desktop.
Example Docker Engine API Client using PHP
<?php
class DockerClient {
/** @param resource */
private $curlClient;
/** @param string */
private $socketPath;
/** @param string|null */
private $curlError = null;
/**
* Constructor: Initialises the Curl Resource, making it usable for subsequent
* API requests.
*
* @param string
*/
public function __construct(string $socketPath)
{
$this->curlClient = curl_init();
$this->socketPath = $socketPath;
curl_setopt($this->curlClient, CURLOPT_UNIX_SOCKET_PATH, $socketPath);
curl_setopt($this->curlClient, CURLOPT_RETURNTRANSFER, true);
}
/**
* Deconstructor: Ensure the Curl Resource is correctly closed.
*/
public function __destruct()
{
curl_close($this->curlClient);
}
private function generateRequestUri(string $requestPath)
{
/* Please note that Curl doesn't use http+unix:// or any other mechanism for
* specifying Unix Sockets; once the CURLOPT_UNIX_SOCKET_PATH option is set,
* Curl will simply ignore the domain of the request. Hence why this works,
* despite looking as though it should attempt to connect to a host found at
* the domain "unixsocket". See L14 where this is set.
*
* @see Client.php:L14
* @see https://github.com/curl/curl/issues/1338
*/
return sprintf("http://unixsocket%s", $requestPath);
}
/**
* Dispatches a command - via Curl - to Commander's Unix Socket.
*
* @param string Docker Engine endpoint to hit.
* @param array Data to post to $endpoint.
* @return array JSON decoded response from Commander.
*/
public function dispatchCommand(string $endpoint, array $parameters = null): array
{
curl_setopt($this->curlClient, CURLOPT_URL, $this->generateRequestUri($endpoint));
if (!is_null($parameters)) {
$payload = json_encode($parameters);
curl_setopt($this->curlClient, CURLOPT_POSTFIELDS, $payload);
}
$result = curl_exec($this->curlClient);
if ($result === FALSE) {
$this->curlError = curl_error($this->curlClient);
return array();
}
return json_decode($result, true);
}
/**
* Returns a human readable string from Curl in the event of an error.
*
* @return bool|string
*/
public function getCurlError()
{
return is_null($this->curlError) ? false : $this->curlError;
}
}
/*
* Example Usage:
*/
$client = new DockerClient('/var/run/docker.sock');
$dockerContainers = $client->dispatchCommand('/containers/json');
foreach ($dockerContainers as $container) {
printf("%s (%s) - %s\n", implode(', ', $container['Names']),
$container['Id'], $container['Image']);
}
$dockerVersion = $client->dispatchCommand('/version')
printf("%s (%s - %s)", $dockerVersion['Version'],
$dockerVersion['Os'], $dockerVersion['KernelVersion']);
@povesteam
Copy link

Thanks, this is exactly what I needed.

I am using it to read and update a node label in docker swarm, as documented here.

@tasosmitsi
Copy link

Amazing. Works perfectly well!

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment