Docker-Compose-Service hinzugefügt und DDEV-Hooks für Umgebungsvariablen konfiguriert

This commit is contained in:
2026-03-27 14:32:02 +01:00
committed by Thomas Schneider
parent b14e50af1a
commit 6320fcc8c0
2 changed files with 235 additions and 0 deletions

View File

@@ -14,6 +14,9 @@ composer_version: "2"
web_environment: []
corepack_enable: false
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:

View 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 [];
}
}
}