docker-client/client
Lightweight PHP client for the Docker Engine API. Create, start, delete, inspect, list, and stream logs for containers; manage images (create/delete/inspect). Early-stage package with minimal supported actions; see examples for usage.
Installation:
composer require docker-client/client
Requires PHP 7.2+ (check composer.json for exact version).
Basic Client Initialization:
use Docker\Client;
$client = new Client();
By default, connects to unix://var/run/docker.sock (Linux) or npipe:////./pipe/docker_engine (Windows).
First Use Case: List running containers:
$containers = $client->containers()->list();
print_r($containers);
examples/ folder for practical use cases.src/ for direct method implementations (e.g., Container.php, Image.php).Create and Run:
$container = $client->containers()->create([
'Image' => 'nginx:alpine',
'Cmd' => ['nginx', '-g', 'daemon off;'],
'ExposedPorts' => ['80/tcp'],
]);
$client->containers()->start($container['Id']);
Stream Logs:
$logs = $client->containers()->logs($container['Id'], [
'Stdout' => true,
'Stderr' => true,
'Follow' => true,
'Timestamps' => true,
]);
while ($output = $logs->read()) {
echo $output;
}
Inspect and Act:
$inspect = $client->containers()->inspect($container['Id']);
if ($inspect['State']['Status'] === 'running') {
$client->containers()->stop($container['Id']);
}
Pull and Delete:
$client->images()->create(['fromImage' => 'alpine']);
$client->images()->delete('alpine');
Inspect Image:
$image = $client->images()->inspect('nginx:alpine');
print_r($image['Config']['Cmd']);
Dependency Injection: Bind the client in Laravel’s service container:
$app->singleton(Client::class, function () {
return new Client();
});
Inject via constructor:
public function __construct(private Client $docker) {}
Error Handling: Wrap calls in try-catch for Docker API errors:
try {
$client->containers()->start($id);
} catch (\Docker\Exception\DockerException $e) {
Log::error("Docker error: " . $e->getMessage());
}
Configuration: Override default Docker host (e.g., for remote Docker daemons):
$client = new Client('tcp://host.docker.internal:2375');
Add authentication for TLS:
$client = new Client('https://host.docker.internal:2376', [
'auth' => ['username' => 'user', 'password' => 'pass'],
]);
Async Operations:
Use wait() for container lifecycle events:
$result = $client->containers()->wait($container['Id']);
if ($result['StatusCode'] === 0) {
echo "Container exited successfully";
}
No Retry Logic: Docker API calls may fail transiently (e.g., network issues). Implement retries manually:
use Symfony\Component\Process\Exception\ProcessTimedOutException;
try {
$client->containers()->start($id);
} catch (DockerException $e) {
if (str_contains($e->getMessage(), 'Connection refused')) {
sleep(1);
retry();
}
}
Deprecated Methods:
The package lacks support for newer Docker features (e.g., build(), commit()). Use exec() with docker CLI as a fallback:
$process = new \Symfony\Component\Process\Process(['docker', 'build', '-t', 'my-image', '.']);
$process->run();
No Event System:
Real-time events (e.g., container start/stop) require polling or external tools like docker events.
Limited Image Build:
The create() method for images only supports fromImage. For custom builds, use:
exec('docker build -t my-image .');
Enable Verbose Logging:
Set the DOCKER_CLIENT_DEBUG environment variable to log raw API requests/responses:
export DOCKER_CLIENT_DEBUG=1
Inspect Raw API Calls: The package uses Guzzle under the hood. Add a middleware to log requests:
$client = new Client();
$client->getClient()->getEmitter()->attach(
new \GuzzleHttp\Middleware::tap(function ($request) {
error_log($request->getUri());
})
);
Validate Docker Daemon: Ensure the Docker daemon is running and accessible:
docker info # Should return daemon info
Custom API Endpoints: Extend the client to support unsupported endpoints by subclassing:
class CustomClient extends Client {
public function customEndpoint() {
return $this->getClient()->get($this->getBaseUri() . '/custom');
}
}
Add New Methods:
Mirror the existing pattern (e.g., containers()->list()). Example for commit():
public function commit($containerId, array $config = []) {
return $this->getClient()->post(
$this->getBaseUri() . "/containers/{$containerId}/commit",
['json' => $config]
);
}
Plugin System: Use Laravel’s service providers to register additional Docker utilities:
public function register() {
$this->app->singleton('docker', function () {
return new Client();
});
$this->app->alias('docker', DockerClient::class);
}
Testing: Mock the client in tests using PHPUnit:
$mock = $this->createMock(Client::class);
$mock->method('containers')->willReturnSelf();
$mock->method('list')->willReturn(['Id' => 'test']);
Docker Socket Permissions:
On Linux, ensure the PHP process has access to /var/run/docker.sock:
sudo chmod 666 /var/run/docker.sock # Temporary fix (not recommended for production)
Or add the user to the docker group:
sudo usermod -aG docker $USER
Windows Paths:
Use npipe:////./pipe/docker_engine for Windows Docker Desktop. For WSL2, use the Linux socket:
$client = new Client('unix:///mnt/c/users/youruser/.docker/desktop/docker.sock');
Timeouts: Adjust Guzzle timeouts in the client constructor:
$client = new Client(null, [
'connect_timeout' => 5,
'timeout' => 30,
]);
How can I help you explore Laravel packages today?