Files
Infra-Management/app/Services/Container/DockerManager.php
I-Fun c649f055d8 feat: initialize Infra Manager with React, Tailwind CSS, and Inertia.js
- Added main application entry point (app.jsx) and bootstrap file for React setup.
- Created Wiki index page (Index.jsx) for documentation and file management.
- Implemented utility functions for formatting and status handling in utils.js.
- Set up Blade template (app.blade.php) for Inertia.js integration.
- Defined API routes for metrics and terminal access in api.php.
- Established console commands for scheduled tasks in console.php.
- Created web routes for various application features including authentication, hypervisors, containers, cloud accounts, security, backups, and wiki management in web.php.
- Developed setup scripts for Windows (setup.ps1) and Linux (setup.sh) environments.
- Configured Tailwind CSS for styling with custom themes and animations in tailwind.config.js.
- Set up Vite for asset bundling and development server in vite.config.js.
2026-04-07 20:29:32 +07:00

115 lines
4.1 KiB
PHP

<?php
namespace App\Services\Container;
use App\Models\Container;
use App\Models\DockerEndpoint;
use GuzzleHttp\Client;
class DockerManager
{
private array $clients = [];
private function client(DockerEndpoint $endpoint): Client
{
$key = $endpoint->id;
if (!isset($this->clients[$key])) {
$options = ['timeout' => 30];
if (str_starts_with($endpoint->host, 'unix://')) {
$options['curl'] = [CURLOPT_UNIX_SOCKET_PATH => str_replace('unix://', '', $endpoint->host)];
$options['base_uri'] = 'http://localhost/';
} else {
$options['base_uri'] = $endpoint->host . '/';
if ($endpoint->tls_enabled) {
$options['verify'] = true;
$options['cert'] = $endpoint->tls_cert;
$options['ssl_key'] = $endpoint->tls_key;
}
}
$this->clients[$key] = new Client($options);
}
return $this->clients[$key];
}
public function testConnection(DockerEndpoint $endpoint): array
{
$response = $this->client($endpoint)->get('v1.43/info');
return json_decode($response->getBody()->getContents(), true) ?? [];
}
public function syncEndpoint(DockerEndpoint $endpoint): void
{
$client = $this->client($endpoint);
// Sync info
$info = json_decode($client->get('v1.43/info')->getBody()->getContents(), true);
$endpoint->update([
'status' => 'online',
'info' => $info,
'last_sync_at' => now(),
]);
// Sync containers
$containers = json_decode($client->get('v1.43/containers/json?all=1')->getBody()->getContents(), true) ?? [];
foreach ($containers as $c) {
Container::updateOrCreate(
['endpoint_id' => $endpoint->id, 'container_id' => $c['Id']],
[
'name' => ltrim($c['Names'][0] ?? '', '/'),
'image' => $c['Image'],
'image_id' => $c['ImageID'],
'status' => $c['Status'],
'state' => $c['State'],
'ports' => $c['Ports'],
'labels' => $c['Labels'],
'networks' => array_keys($c['NetworkSettings']['Networks'] ?? []),
'created_at_unix' => $c['Created'],
]
);
}
}
public function action(DockerEndpoint $endpoint, string $containerId, string $action): bool
{
$allowed = ['start', 'stop', 'restart', 'pause', 'unpause', 'kill'];
if (!in_array($action, $allowed)) {
throw new \InvalidArgumentException("Invalid action: {$action}");
}
$this->client($endpoint)->post("v1.43/containers/{$containerId}/{$action}");
return true;
}
public function logs(DockerEndpoint $endpoint, string $containerId, int $tail = 100): string
{
$response = $this->client($endpoint)->get("v1.43/containers/{$containerId}/logs", [
'query' => ['stdout' => 1, 'stderr' => 1, 'tail' => $tail, 'timestamps' => 1],
]);
return $response->getBody()->getContents();
}
public function stats(DockerEndpoint $endpoint, string $containerId): array
{
$response = $this->client($endpoint)->get("v1.43/containers/{$containerId}/stats", [
'query' => ['stream' => 0, 'one-shot' => 1],
]);
return json_decode($response->getBody()->getContents(), true) ?? [];
}
public function deployStack(DockerEndpoint $endpoint, string $name, string $composeContent, array $envVars = []): bool
{
// Write compose file and deploy via API or exec
// For Swarm use stacks API; for local use compose integration
return true;
}
public function removeContainer(DockerEndpoint $endpoint, string $containerId, bool $force = false): bool
{
$this->client($endpoint)->delete("v1.43/containers/{$containerId}", [
'query' => ['force' => $force ? 1 : 0],
]);
return true;
}
}