Docker-Compose-Service hinzugefügt und DDEV-Hooks für Umgebungsvariablen konfiguriert
This commit is contained in:
@@ -14,6 +14,9 @@ composer_version: "2"
|
|||||||
web_environment: []
|
web_environment: []
|
||||||
corepack_enable: false
|
corepack_enable: false
|
||||||
omit_containers: [db]
|
omit_containers: [db]
|
||||||
|
hooks:
|
||||||
|
pre-start:
|
||||||
|
- exec-host: ddev dotenv set .ddev/.env --docker-dotenv-vars="$(docker compose -f .ddev/.ddev-docker-compose-full.yaml config | awk '/^[[:space:]]{2}web:$/ {inweb=1; next} inweb && /^[[:space:]]{4}environment:$/ {inenv=1; next} inenv && /^[[:space:]]{6}[A-Za-z0-9_]+:/ {gsub(/^[[:space:]]+|:$/, "", $1); print $1; next} inenv && /^[[:space:]]{4}[^[:space:]]/ {inenv=0} inweb && /^[[:space:]]{2}[^[:space:]]/ && !/^[[:space:]]{4}/ {inweb=0}' | sort -u | paste -sd, -)"
|
||||||
|
|
||||||
# Key features of DDEV's config.yaml:
|
# Key features of DDEV's config.yaml:
|
||||||
|
|
||||||
|
|||||||
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