Docker-Compose-Service hinzugefügt und DDEV-Hooks für Umgebungsvariablen konfiguriert
This commit is contained in:
232
src/Service/Docker/DockerCompose.php
Normal file
232
src/Service/Docker/DockerCompose.php
Normal file
@@ -0,0 +1,232 @@
|
||||
<?php
|
||||
/*
|
||||
* DockerCompose.php 2026-03-27 thomas
|
||||
*
|
||||
* Copyright (c) 2026 Thomas Schneider <thomas@inter-mundos.de>
|
||||
* Alle Rechte vorbehalten.
|
||||
*/
|
||||
|
||||
namespace App\Service\Docker;
|
||||
|
||||
use App\Service\Process\CleanProcess;
|
||||
use Dotenv\Dotenv;
|
||||
use Exception;
|
||||
use Spatie\Docker\Exceptions\CouldNotStartDockerContainer;
|
||||
use Symfony\Component\Filesystem\Filesystem;
|
||||
use Symfony\Component\Process\Process;
|
||||
|
||||
class DockerCompose
|
||||
{
|
||||
protected string $composeCmd = 'compose';
|
||||
|
||||
protected float $startCommandTimeout = 600;
|
||||
|
||||
protected string $name = '';
|
||||
|
||||
protected bool $daemonize = false;
|
||||
|
||||
protected string $dockerHost = '';
|
||||
|
||||
protected string $workingDir = '';
|
||||
|
||||
|
||||
protected array $composeFiles = [];
|
||||
|
||||
protected array $envFiles = [];
|
||||
|
||||
protected array $inlineEnvFiles = [];
|
||||
|
||||
/**
|
||||
* @throws CouldNotStartDockerContainer
|
||||
*/
|
||||
public function up(array $optionalArgs = []): void
|
||||
{
|
||||
$process = $this->process('up', $optionalArgs);
|
||||
$process->run(function ($type, $buffer): void
|
||||
{
|
||||
echo $buffer;
|
||||
});
|
||||
|
||||
// if(!$process->isSuccessful())
|
||||
// {
|
||||
// throw CouldNotStartDockerContainer::processFailed($this, $process);
|
||||
// }
|
||||
|
||||
$error = $process->getErrorOutput();
|
||||
|
||||
$dockerIdentifier = trim($process->getOutput());
|
||||
}
|
||||
|
||||
|
||||
protected function process(string $cmd, array $optionalArgs = []): Process
|
||||
{
|
||||
$env = [...$this->loadDotEnv(), ...$this->parseInlineEnvFiles()];
|
||||
|
||||
if(!empty($env['DOCKER_HOST']))
|
||||
{
|
||||
$this->dockerHost = $env['DOCKER_HOST'];
|
||||
}
|
||||
|
||||
return CleanProcess::fromShellCommandline(
|
||||
command: implode(' ', [...$this->getBaseCommand(), $cmd, ...$this->getExtraOptions($optionalArgs)]),
|
||||
cwd: $this->workingDir,
|
||||
env: $env,
|
||||
timeout: $this->startCommandTimeout,
|
||||
);
|
||||
}
|
||||
|
||||
|
||||
protected function getBaseCommand(): array
|
||||
{
|
||||
return [
|
||||
...explode(' ', $this->composeCmd),
|
||||
...$this->getExtraDockerOptions(),
|
||||
];
|
||||
}
|
||||
|
||||
|
||||
protected function getExtraDockerOptions(): array
|
||||
{
|
||||
$extraDockerOptions = [];
|
||||
|
||||
if($this->dockerHost !== '')
|
||||
{
|
||||
$extraDockerOptions[] = "-H {$this->dockerHost}";
|
||||
}
|
||||
|
||||
if($this->name !== '')
|
||||
{
|
||||
$extraDockerOptions[] = "-p {$this->name}";
|
||||
}
|
||||
|
||||
if($this->composeFiles)
|
||||
{
|
||||
foreach($this->composeFiles as $file)
|
||||
{
|
||||
$extraDockerOptions[] = "--file {$file}";
|
||||
}
|
||||
}
|
||||
|
||||
if($this->envFiles)
|
||||
{
|
||||
foreach($this->envFiles as $file)
|
||||
{
|
||||
$extraDockerOptions[] = "--env-file {$file}";
|
||||
}
|
||||
}
|
||||
|
||||
return $extraDockerOptions;
|
||||
}
|
||||
|
||||
|
||||
protected function getExtraOptions(array $optionalArgs = []): array
|
||||
{
|
||||
$extraOptions = [...$optionalArgs];
|
||||
|
||||
if($this->daemonize && !in_array('-d', $extraOptions, true))
|
||||
{
|
||||
$extraOptions[] = '-d';
|
||||
}
|
||||
|
||||
return $extraOptions;
|
||||
}
|
||||
|
||||
|
||||
public function setName(string $name): self
|
||||
{
|
||||
$this->name = $name;
|
||||
return $this;
|
||||
}
|
||||
|
||||
|
||||
public function setWorkingDir(string $workingDir): self
|
||||
{
|
||||
$this->workingDir = $workingDir;
|
||||
return $this;
|
||||
}
|
||||
|
||||
|
||||
public function setStartCommandTimeout(float $startCommandTimeout): self
|
||||
{
|
||||
$this->startCommandTimeout = $startCommandTimeout;
|
||||
return $this;
|
||||
}
|
||||
|
||||
|
||||
public function setDockerHost(string $dockerHost): self
|
||||
{
|
||||
$this->dockerHost = $dockerHost;
|
||||
return $this;
|
||||
}
|
||||
|
||||
|
||||
public function daemonize(bool $daemonize): self
|
||||
{
|
||||
$this->daemonize = $daemonize;
|
||||
return $this;
|
||||
}
|
||||
|
||||
|
||||
public function setComposeFiles(array $composeFiles): self
|
||||
{
|
||||
$this->composeFiles = [...$this->composeFiles, ...$composeFiles];
|
||||
return $this;
|
||||
}
|
||||
|
||||
|
||||
public function setEnvFiles(array $envFiles): self
|
||||
{
|
||||
$this->envFiles = [...$this->envFiles, ...$envFiles];
|
||||
return $this;
|
||||
}
|
||||
|
||||
|
||||
public function setInlineEnvFiles(array $envFiles): self
|
||||
{
|
||||
$this->inlineEnvFiles = [...$this->inlineEnvFiles, ...$envFiles];
|
||||
return $this;
|
||||
}
|
||||
|
||||
|
||||
public function getInlineEnvFiles(): array
|
||||
{
|
||||
return $this->inlineEnvFiles;
|
||||
}
|
||||
|
||||
|
||||
protected function parseInlineEnvFiles(): array
|
||||
{
|
||||
$env = [];
|
||||
$filesystem = new Filesystem();
|
||||
|
||||
foreach ($this->inlineEnvFiles as $file)
|
||||
{
|
||||
try
|
||||
{
|
||||
if(!empty($envFromFile = Dotenv::parse($filesystem->readFile($file))))
|
||||
{
|
||||
$env = [...$env, ...$envFromFile];
|
||||
}
|
||||
}
|
||||
catch(Exception $e)
|
||||
{
|
||||
continue;
|
||||
}
|
||||
}
|
||||
|
||||
return $env;
|
||||
}
|
||||
|
||||
|
||||
protected function loadDotEnv(): array
|
||||
{
|
||||
try
|
||||
{
|
||||
return Dotenv::createArrayBacked($this->workingDir)->load();
|
||||
}
|
||||
catch(Exception $e)
|
||||
{
|
||||
return [];
|
||||
}
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user