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
This commit is contained in:
@@ -454,6 +454,12 @@ function applicationParser(Application $resource, int $pull_request_id = 0, ?int
|
||||
}
|
||||
}
|
||||
|
||||
// generate SERVICE_NAME variables for docker compose services
|
||||
$serviceNameEnvironments = collect([]);
|
||||
if ($resource->build_pack === 'dockercompose') {
|
||||
$serviceNameEnvironments = generateDockerComposeServiceName($services, $pullRequestId);
|
||||
}
|
||||
|
||||
// Parse the rest of the services
|
||||
foreach ($services as $serviceName => $service) {
|
||||
$image = data_get_str($service, 'image');
|
||||
@@ -567,7 +573,7 @@ function applicationParser(Application $resource, int $pull_request_id = 0, ?int
|
||||
}
|
||||
$source = replaceLocalSource($source, $mainDirectory);
|
||||
if ($isPullRequest) {
|
||||
$source = $source."-pr-$pullRequestId";
|
||||
$source = addPreviewDeploymentSuffix($source, $pull_request_id);
|
||||
}
|
||||
LocalFileVolume::updateOrCreate(
|
||||
[
|
||||
@@ -610,7 +616,7 @@ function applicationParser(Application $resource, int $pull_request_id = 0, ?int
|
||||
$name = "{$uuid}_{$slugWithoutUuid}";
|
||||
|
||||
if ($isPullRequest) {
|
||||
$name = "{$name}-pr-$pullRequestId";
|
||||
$name = addPreviewDeploymentSuffix($name, $pull_request_id);
|
||||
}
|
||||
if (is_string($volume)) {
|
||||
$parsed = parseDockerVolumeString($volume);
|
||||
@@ -651,11 +657,11 @@ function applicationParser(Application $resource, int $pull_request_id = 0, ?int
|
||||
$newDependsOn = collect([]);
|
||||
$depends_on->each(function ($dependency, $condition) use ($pullRequestId, $newDependsOn) {
|
||||
if (is_numeric($condition)) {
|
||||
$dependency = "$dependency-pr-$pullRequestId";
|
||||
$dependency = addPreviewDeploymentSuffix($dependency, $pullRequestId);
|
||||
|
||||
$newDependsOn->put($condition, $dependency);
|
||||
} else {
|
||||
$condition = "$condition-pr-$pullRequestId";
|
||||
$condition = addPreviewDeploymentSuffix($condition, $pullRequestId);
|
||||
$newDependsOn->put($condition, $dependency);
|
||||
}
|
||||
});
|
||||
@@ -1082,7 +1088,7 @@ function applicationParser(Application $resource, int $pull_request_id = 0, ?int
|
||||
$payload['volumes'] = $volumesParsed;
|
||||
}
|
||||
if ($environment->count() > 0 || $coolifyEnvironments->count() > 0) {
|
||||
$payload['environment'] = $environment->merge($coolifyEnvironments);
|
||||
$payload['environment'] = $environment->merge($coolifyEnvironments)->merge($serviceNameEnvironments);
|
||||
}
|
||||
if ($logging) {
|
||||
$payload['logging'] = $logging;
|
||||
@@ -1091,7 +1097,7 @@ function applicationParser(Application $resource, int $pull_request_id = 0, ?int
|
||||
$payload['depends_on'] = $depends_on;
|
||||
}
|
||||
if ($isPullRequest) {
|
||||
$serviceName = "{$serviceName}-pr-{$pullRequestId}";
|
||||
$serviceName = addPreviewDeploymentSuffix($serviceName, $pullRequestId);
|
||||
}
|
||||
|
||||
$parsedServices->put($serviceName, $payload);
|
||||
|
@@ -2058,12 +2058,12 @@ function parseDockerComposeFile(Service|Application $resource, bool $isNew = fal
|
||||
$name = $name->replaceFirst('~', $dir);
|
||||
}
|
||||
if ($pull_request_id !== 0) {
|
||||
$name = $name."-pr-$pull_request_id";
|
||||
$name = addPreviewDeploymentSuffix($name, $pull_request_id);
|
||||
}
|
||||
$volume = str("$name:$mount");
|
||||
} else {
|
||||
if ($pull_request_id !== 0) {
|
||||
$name = $name."-pr-$pull_request_id";
|
||||
$name = addPreviewDeploymentSuffix($name, $pull_request_id);
|
||||
$volume = str("$name:$mount");
|
||||
if ($topLevelVolumes->has($name)) {
|
||||
$v = $topLevelVolumes->get($name);
|
||||
@@ -2102,7 +2102,7 @@ function parseDockerComposeFile(Service|Application $resource, bool $isNew = fal
|
||||
$name = $volume->before(':');
|
||||
$mount = $volume->after(':');
|
||||
if ($pull_request_id !== 0) {
|
||||
$name = $name."-pr-$pull_request_id";
|
||||
$name = addPreviewDeploymentSuffix($name, $pull_request_id);
|
||||
}
|
||||
$volume = str("$name:$mount");
|
||||
}
|
||||
@@ -2121,7 +2121,7 @@ function parseDockerComposeFile(Service|Application $resource, bool $isNew = fal
|
||||
$source = str($source)->replaceFirst('~', $dir);
|
||||
}
|
||||
if ($pull_request_id !== 0) {
|
||||
$source = $source."-pr-$pull_request_id";
|
||||
$source = addPreviewDeploymentSuffix($source, $pull_request_id);
|
||||
}
|
||||
if ($read_only) {
|
||||
data_set($volume, 'source', $source.':'.$target.':ro');
|
||||
@@ -2130,7 +2130,7 @@ function parseDockerComposeFile(Service|Application $resource, bool $isNew = fal
|
||||
}
|
||||
} else {
|
||||
if ($pull_request_id !== 0) {
|
||||
$source = $source."-pr-$pull_request_id";
|
||||
$source = addPreviewDeploymentSuffix($source, $pull_request_id);
|
||||
}
|
||||
if ($read_only) {
|
||||
data_set($volume, 'source', $source.':'.$target.':ro');
|
||||
@@ -2182,13 +2182,13 @@ function parseDockerComposeFile(Service|Application $resource, bool $isNew = fal
|
||||
$name = $name->replaceFirst('~', $dir);
|
||||
}
|
||||
if ($pull_request_id !== 0) {
|
||||
$name = $name."-pr-$pull_request_id";
|
||||
$name = addPreviewDeploymentSuffix($name, $pull_request_id);
|
||||
}
|
||||
$volume = str("$name:$mount");
|
||||
} else {
|
||||
if ($pull_request_id !== 0) {
|
||||
$uuid = $resource->uuid;
|
||||
$name = $uuid."-$name-pr-$pull_request_id";
|
||||
$name = $uuid.'-'.addPreviewDeploymentSuffix($name, $pull_request_id);
|
||||
$volume = str("$name:$mount");
|
||||
if ($topLevelVolumes->has($name)) {
|
||||
$v = $topLevelVolumes->get($name);
|
||||
@@ -2230,7 +2230,7 @@ function parseDockerComposeFile(Service|Application $resource, bool $isNew = fal
|
||||
$name = $volume->before(':');
|
||||
$mount = $volume->after(':');
|
||||
if ($pull_request_id !== 0) {
|
||||
$name = $name."-pr-$pull_request_id";
|
||||
$name = addPreviewDeploymentSuffix($name, $pull_request_id);
|
||||
}
|
||||
$volume = str("$name:$mount");
|
||||
}
|
||||
@@ -2258,7 +2258,7 @@ function parseDockerComposeFile(Service|Application $resource, bool $isNew = fal
|
||||
if ($pull_request_id === 0) {
|
||||
$source = $uuid."-$source";
|
||||
} else {
|
||||
$source = $uuid."-$source-pr-$pull_request_id";
|
||||
$source = $uuid.'-'.addPreviewDeploymentSuffix($source, $pull_request_id);
|
||||
}
|
||||
if ($read_only) {
|
||||
data_set($volume, 'source', $source.':'.$target.':ro');
|
||||
@@ -2298,7 +2298,7 @@ function parseDockerComposeFile(Service|Application $resource, bool $isNew = fal
|
||||
|
||||
if ($pull_request_id !== 0 && count($serviceDependencies) > 0) {
|
||||
$serviceDependencies = $serviceDependencies->map(function ($dependency) use ($pull_request_id) {
|
||||
return $dependency."-pr-$pull_request_id";
|
||||
return addPreviewDeploymentSuffix($dependency, $pull_request_id);
|
||||
});
|
||||
data_set($service, 'depends_on', $serviceDependencies->toArray());
|
||||
}
|
||||
@@ -2692,7 +2692,7 @@ function parseDockerComposeFile(Service|Application $resource, bool $isNew = fal
|
||||
});
|
||||
if ($pull_request_id !== 0) {
|
||||
$services->each(function ($service, $serviceName) use ($pull_request_id, $services) {
|
||||
$services[$serviceName."-pr-$pull_request_id"] = $service;
|
||||
$services[addPreviewDeploymentSuffix($serviceName, $pull_request_id)] = $service;
|
||||
data_forget($services, $serviceName);
|
||||
});
|
||||
}
|
||||
@@ -3072,3 +3072,17 @@ function parseDockerfileInterval(string $something)
|
||||
|
||||
return $seconds;
|
||||
}
|
||||
|
||||
function addPreviewDeploymentSuffix(string $name, int $pull_request_id = 0): string
|
||||
{
|
||||
return ($pull_request_id === 0)? $name : $name.'-pr-'.$pull_request_id;
|
||||
}
|
||||
|
||||
function generateDockerComposeServiceName(mixed $services, int $pullRequestId = 0) : Collection
|
||||
{
|
||||
$collection = collect([]);
|
||||
foreach ($services as $serviceName => $_) {
|
||||
$collection->put('SERVICE_NAME_'.str($serviceName)->upper(), addPreviewDeploymentSuffix($serviceName,$pullRequestId));
|
||||
}
|
||||
return $collection;
|
||||
}
|
||||
|
Reference in New Issue
Block a user