Files
coolify/app/Traits/EnvironmentVariableProtection.php
Arnaud B e23ab1e621 feat(deployment): add SERVICE_NAME variables for service discovery
This change introduces automatically generated `SERVICE_NAME_<SERVICE>`
environment variables for each service within a Docker Compose deployment.
This allows services to reliably reference each other by name, which is particularly
useful in pull request environments where container names are dynamically suffixed.

- The application parser now generates and injects these `SERVICE_NAME` variables
   into the environment of all services in the compose file.
- `ApplicationDeploymentJob` is updated to correctly handle and filter these
  new variables during deployment.
- UI components and the `EnvironmentVariableProtection` trait have been updated
to make these generated variables read-only, preventing accidental modification.

This commit introduces two new helper functions to standardize resource naming
for pull request deployments:

-  `addPreviewDeploymentSuffix()`: Generates a consistent suffix format (-pr-{id})
   for resource names in preview deployments
-  `generateDockerComposeServiceName()`: Creates SERVICE_NAME environment variables
   for Docker Compose services
2025-09-08 15:22:44 +02:00

64 lines
2.2 KiB
PHP

<?php
namespace App\Traits;
use Symfony\Component\Yaml\Yaml;
trait EnvironmentVariableProtection
{
/**
* Check if an environment variable is protected from deletion
*
* @param string $key The environment variable key to check
* @return bool True if the variable is protected, false otherwise
*/
protected function isProtectedEnvironmentVariable(string $key): bool
{
return str($key)->startsWith('SERVICE_FQDN_') || str($key)->startsWith('SERVICE_URL_') || str($key)->startsWith('SERVICE_NAME_');
}
/**
* Check if an environment variable is used in Docker Compose
*
* @param string $key The environment variable key to check
* @param string|null $dockerCompose The Docker Compose YAML content
* @return array [bool $isUsed, string $reason] Whether the variable is used and the reason if it is
*/
protected function isEnvironmentVariableUsedInDockerCompose(string $key, ?string $dockerCompose): array
{
if (empty($dockerCompose)) {
return [false, ''];
}
try {
$dockerComposeData = Yaml::parse($dockerCompose);
$dockerEnvVars = data_get($dockerComposeData, 'services.*.environment');
foreach ($dockerEnvVars as $serviceEnvs) {
if (! is_array($serviceEnvs)) {
continue;
}
// Check for direct variable usage
foreach ($serviceEnvs as $env => $value) {
if ($env === $key) {
return [true, "Environment variable '{$key}' is used directly in the Docker Compose file."];
}
}
// Check for variable references in values
foreach ($serviceEnvs as $env => $value) {
if (is_string($value) && str_contains($value, '$'.$key)) {
return [true, "Environment variable '{$key}' is referenced in the Docker Compose file."];
}
}
}
} catch (\Exception $e) {
// If there's an error parsing the Docker Compose file, we'll assume it's not used
return [false, ''];
}
return [false, ''];
}
}