fix(deployments): filter generated compose service env vars (#10186)

This commit is contained in:
Andras Bacsai
2026-06-01 10:38:36 +02:00
committed by GitHub
2 changed files with 144 additions and 14 deletions
+23 -14
View File
@@ -1293,12 +1293,8 @@ class ApplicationDeploymentJob implements ShouldBeEncrypted, ShouldQueue
$sorted_environment_variables_preview = $this->application->runtime_environment_variables_preview->sortBy('id');
}
if ($this->build_pack === 'dockercompose') {
$sorted_environment_variables = $sorted_environment_variables->filter(function ($env) {
return ! str($env->key)->startsWith('SERVICE_FQDN_') && ! str($env->key)->startsWith('SERVICE_URL_') && ! str($env->key)->startsWith('SERVICE_NAME_');
});
$sorted_environment_variables_preview = $sorted_environment_variables_preview->filter(function ($env) {
return ! str($env->key)->startsWith('SERVICE_FQDN_') && ! str($env->key)->startsWith('SERVICE_URL_') && ! str($env->key)->startsWith('SERVICE_NAME_');
});
$sorted_environment_variables = $sorted_environment_variables->reject(fn (EnvironmentVariable $env) => $this->isGeneratedDockerComposeEnvironmentVariable($env));
$sorted_environment_variables_preview = $sorted_environment_variables_preview->reject(fn (EnvironmentVariable $env) => $this->isGeneratedDockerComposeEnvironmentVariable($env));
}
$ports = $this->application->main_port();
$coolify_envs = $this->generate_coolify_env_variables();
@@ -1451,6 +1447,15 @@ class ApplicationDeploymentJob implements ShouldBeEncrypted, ShouldQueue
return $envs;
}
private function isGeneratedDockerComposeEnvironmentVariable(EnvironmentVariable $environmentVariable): bool
{
$key = str($environmentVariable->key);
return $key->startsWith('SERVICE_FQDN_')
|| $key->startsWith('SERVICE_URL_')
|| $key->startsWith('SERVICE_NAME_');
}
private function save_runtime_environment_variables()
{
// This method saves the .env file with ALL runtime variables
@@ -1666,11 +1671,9 @@ class ApplicationDeploymentJob implements ShouldBeEncrypted, ShouldQueue
->orderBy($this->application->settings->is_env_sorting_enabled ? 'key' : 'id')
->get();
// For Docker Compose, filter out SERVICE_FQDN and SERVICE_URL as we generate these
// For Docker Compose, filter out generated SERVICE_* variables as we generate these
if ($this->build_pack === 'dockercompose') {
$sorted_environment_variables = $sorted_environment_variables->filter(function ($env) {
return ! str($env->key)->startsWith('SERVICE_FQDN_') && ! str($env->key)->startsWith('SERVICE_URL_');
});
$sorted_environment_variables = $sorted_environment_variables->reject(fn (EnvironmentVariable $env) => $this->isGeneratedDockerComposeEnvironmentVariable($env));
}
foreach ($sorted_environment_variables as $env) {
@@ -1719,11 +1722,9 @@ class ApplicationDeploymentJob implements ShouldBeEncrypted, ShouldQueue
->orderBy($this->application->settings->is_env_sorting_enabled ? 'key' : 'id')
->get();
// For Docker Compose, filter out SERVICE_FQDN and SERVICE_URL as we generate these with PR-specific values
// For Docker Compose, filter out generated SERVICE_* variables as we generate these with PR-specific values
if ($this->build_pack === 'dockercompose') {
$sorted_environment_variables = $sorted_environment_variables->filter(function ($env) {
return ! str($env->key)->startsWith('SERVICE_FQDN_') && ! str($env->key)->startsWith('SERVICE_URL_');
});
$sorted_environment_variables = $sorted_environment_variables->reject(fn (EnvironmentVariable $env) => $this->isGeneratedDockerComposeEnvironmentVariable($env));
}
foreach ($sorted_environment_variables as $env) {
@@ -3019,6 +3020,10 @@ COPY ./nginx.conf /etc/nginx/conf.d/default.conf");
->where('is_buildtime', true)
->get();
if ($this->build_pack === 'dockercompose') {
$envs = $envs->reject(fn (EnvironmentVariable $env) => $this->isGeneratedDockerComposeEnvironmentVariable($env));
}
foreach ($envs as $env) {
$resolvedValue = $env->getResolvedValueWithServer($this->mainServer);
if (! is_null($resolvedValue)) {
@@ -3031,6 +3036,10 @@ COPY ./nginx.conf /etc/nginx/conf.d/default.conf");
->where('is_buildtime', true)
->get();
if ($this->build_pack === 'dockercompose') {
$envs = $envs->reject(fn (EnvironmentVariable $env) => $this->isGeneratedDockerComposeEnvironmentVariable($env));
}
foreach ($envs as $env) {
$resolvedValue = $env->getResolvedValueWithServer($this->mainServer);
if (! is_null($resolvedValue)) {
@@ -205,6 +205,127 @@ it('filters buildpack control vars from preview build-time env files', function
expect($buildtimeEnvs->contains(fn (string $env) => str($env)->startsWith('RAILPACK_NODE_VERSION=')))->toBeFalse();
});
it('does not let preview docker compose service names override generated build-time service names', function () {
$compose = <<<'YAML'
services:
app:
image: nginx
postgresapp:
image: postgres:16-alpine
YAML;
[$application, $server] = makeDeploymentControlVarFixture([
'build_pack' => 'dockercompose',
'docker_compose_raw' => $compose,
'docker_compose' => $compose,
'docker_compose_domains' => '[]',
]);
createApplicationEnvironmentVariable($application, [
'key' => 'SERVICE_NAME_POSTGRESAPP',
'value' => '',
'is_preview' => true,
'is_runtime' => true,
'is_buildtime' => true,
]);
createApplicationEnvironmentVariable($application, [
'key' => 'SERVICE_URL_APP',
'value' => '',
'is_preview' => true,
'is_runtime' => true,
'is_buildtime' => true,
]);
[$job, $reflection] = makeControlVarFilteringJob($application, $server, [
'pull_request_id' => 241,
]);
/** @var Collection $buildtimeEnvs */
$buildtimeEnvs = invokeDeploymentJobMethod($job, $reflection, 'generate_buildtime_environment_variables');
$envString = $buildtimeEnvs->implode("\n");
expect($envString)->toContain("SERVICE_NAME_POSTGRESAPP='postgresapp-pr-241'");
expect($envString)->not->toContain('SERVICE_NAME_POSTGRESAPP=""');
expect($envString)->not->toContain('SERVICE_URL_APP=');
});
it('does not let production docker compose service names override generated build-time service names', function () {
$compose = <<<'YAML'
services:
app:
image: nginx
postgresapp:
image: postgres:16-alpine
YAML;
[$application, $server] = makeDeploymentControlVarFixture([
'build_pack' => 'dockercompose',
'docker_compose_raw' => $compose,
'docker_compose' => $compose,
'docker_compose_domains' => '[]',
]);
createApplicationEnvironmentVariable($application, [
'key' => 'SERVICE_NAME_POSTGRESAPP',
'value' => 'stale-postgresapp',
'is_runtime' => true,
'is_buildtime' => true,
]);
[$job, $reflection] = makeControlVarFilteringJob($application, $server);
/** @var Collection $buildtimeEnvs */
$buildtimeEnvs = invokeDeploymentJobMethod($job, $reflection, 'generate_buildtime_environment_variables');
$envString = $buildtimeEnvs->implode("\n");
expect($envString)->toContain("SERVICE_NAME_POSTGRESAPP='postgresapp'");
expect($envString)->not->toContain('stale-postgresapp');
});
it('filters docker compose generated service variables from build args', function () {
[$application, $server] = makeDeploymentControlVarFixture([
'build_pack' => 'dockercompose',
]);
createApplicationEnvironmentVariable($application, [
'key' => 'APP_ENV',
'value' => 'production',
'is_preview' => true,
'is_runtime' => true,
'is_buildtime' => true,
]);
createApplicationEnvironmentVariable($application, [
'key' => 'SERVICE_NAME_POSTGRESAPP',
'value' => '',
'is_preview' => true,
'is_runtime' => true,
'is_buildtime' => true,
]);
createApplicationEnvironmentVariable($application, [
'key' => 'SERVICE_URL_APP',
'value' => 'https://preview.example.com',
'is_preview' => true,
'is_runtime' => true,
'is_buildtime' => true,
]);
[$job, $reflection] = makeControlVarFilteringJob($application, $server, [
'pull_request_id' => 241,
]);
invokeDeploymentJobMethod($job, $reflection, 'generate_env_variables');
/** @var Collection $envArgs */
$envArgs = readDeploymentJobProperty($job, $reflection, 'env_args');
expect($envArgs->get('APP_ENV'))->toBe('production');
expect($envArgs->has('SERVICE_NAME_POSTGRESAPP'))->toBeFalse();
expect($envArgs->has('SERVICE_URL_APP'))->toBeFalse();
});
it('filters buildpack control vars from preview runtime env fallback', function () {
[$application, $server] = makeDeploymentControlVarFixture();