mirror of
https://github.com/coollabsio/coolify.git
synced 2026-11-06 13:10:37 -04:00
fix(services): treat SERVICE_FQDN_ twin as a copy of SERVICE_URL_ declaration
A service that declares SERVICE_FQDN_X_PORT while the named service declares SERVICE_URL_X_PORT (same value) now counts as a copy, like an exact copy, so it does not take the named service's domain. Also replace the Postgres-only regex in the magic variable loop with the same check in PHP.
This commit is contained in:
@@ -594,7 +594,7 @@ function findServiceApplicationForEnvName(Service $resource, string $envServiceN
|
||||
|
||||
/**
|
||||
* Check if a service copies a SERVICE_FQDN_ / SERVICE_URL_ declaration of the application named in it.
|
||||
* The copy (same key, same value) must not generate a domain or overwrite the variable (#11924).
|
||||
* The copy (same name, port and value; URL or FQDN) must not generate a domain or overwrite the variable (#11924).
|
||||
* Declarations with another port or path share the host on purpose (for example Appwrite).
|
||||
*
|
||||
* @param array<string, mixed>|Collection<string, mixed> $services Parsed compose services
|
||||
@@ -618,9 +618,19 @@ function isCopiedServiceUrlDeclaration(
|
||||
$ownerDeclarations = $declarationsOf($owner->name);
|
||||
$currentDeclarations = $declarationsOf($current->name);
|
||||
|
||||
return $ownerDeclarations->has($key)
|
||||
&& $currentDeclarations->has($key)
|
||||
&& (string) $ownerDeclarations->get($key) === (string) $currentDeclarations->get($key);
|
||||
if (! $currentDeclarations->has($key)) {
|
||||
return false;
|
||||
}
|
||||
|
||||
// SERVICE_URL_X_3000 and SERVICE_FQDN_X_3000 write the same variable pair, so either one counts.
|
||||
$twinKey = str_starts_with($key, 'SERVICE_URL_')
|
||||
? 'SERVICE_FQDN_'.substr($key, strlen('SERVICE_URL_'))
|
||||
: 'SERVICE_URL_'.substr($key, strlen('SERVICE_FQDN_'));
|
||||
$value = (string) $currentDeclarations->get($key);
|
||||
|
||||
return collect([$key, $twinKey])->contains(
|
||||
fn (string $ownerKey) => $ownerDeclarations->has($ownerKey) && (string) $ownerDeclarations->get($ownerKey) === $value
|
||||
);
|
||||
}
|
||||
|
||||
/**
|
||||
|
||||
@@ -2671,8 +2671,8 @@ function serviceParser(Service $resource): Collection
|
||||
// Also check if a port-suffixed version exists (e.g., SERVICE_FQDN_UMAMI_3000)
|
||||
$portSuffixedExists = $resource->environment_variables()
|
||||
->where('key', 'LIKE', $key->value().'_%')
|
||||
->whereRaw('key ~ ?', ['^'.$key->value().'_[0-9]+$'])
|
||||
->exists();
|
||||
->pluck('key')
|
||||
->contains(fn ($envKey) => preg_match('/^'.preg_quote($key->value(), '/').'_[0-9]+$/', $envKey) === 1);
|
||||
$serviceExists = findServiceApplicationForEnvName($resource, (string) $fqdnFor);
|
||||
// Check if FQDN already has a port set (contains ':' after the domain)
|
||||
$fqdnHasPort = $serviceExists && str($serviceExists->fqdn)->contains(':') && str($serviceExists->fqdn)->afterLast(':')->isMatch('/^\d+$/');
|
||||
@@ -2716,8 +2716,8 @@ function serviceParser(Service $resource): Collection
|
||||
// Also check if a port-suffixed version exists (e.g., SERVICE_URL_DASHBOARD_6791)
|
||||
$portSuffixedExists = $resource->environment_variables()
|
||||
->where('key', 'LIKE', $key->value().'_%')
|
||||
->whereRaw('key ~ ?', ['^'.$key->value().'_[0-9]+$'])
|
||||
->exists();
|
||||
->pluck('key')
|
||||
->contains(fn ($envKey) => preg_match('/^'.preg_quote($key->value(), '/').'_[0-9]+$/', $envKey) === 1);
|
||||
$serviceExists = findServiceApplicationForEnvName($resource, (string) $urlFor);
|
||||
// Check if FQDN already has a port set (contains ':' after the domain)
|
||||
$fqdnHasPort = $serviceExists && str($serviceExists->fqdn)->contains(':') && str($serviceExists->fqdn)->afterLast(':')->isMatch('/^\d+$/');
|
||||
|
||||
@@ -154,3 +154,25 @@ it('fixes SERVICE_URL_TWENTY for installs where worker already has a generated d
|
||||
expect($this->service->environment_variables()->where('key', 'SERVICE_URL_TWENTY')->value('value'))->toBe('https://crm.example.com')
|
||||
->and($this->service->applications()->where('name', 'worker')->value('fqdn'))->toBe('http://twenty-stale.10.0.1.1.sslip.io');
|
||||
});
|
||||
|
||||
it('treats SERVICE_FQDN_ with the same name, port and value as a copy of SERVICE_URL_', function () {
|
||||
$this->service->update(['docker_compose_raw' => <<<'YAML'
|
||||
services:
|
||||
twenty:
|
||||
image: twentycrm/twenty:v1.15
|
||||
environment:
|
||||
- SERVICE_URL_TWENTY_3000
|
||||
worker:
|
||||
image: twentycrm/twenty:v1.15
|
||||
environment:
|
||||
- SERVICE_FQDN_TWENTY_3000
|
||||
YAML]);
|
||||
|
||||
$this->service->parse();
|
||||
$this->service->applications()->where('name', 'twenty')->first()->update(['fqdn' => 'https://crm.example.com']);
|
||||
$this->service->fresh()->parse();
|
||||
|
||||
expect($this->service->environment_variables()->where('key', 'SERVICE_URL_TWENTY')->value('value'))->toBe('https://crm.example.com')
|
||||
->and($this->service->environment_variables()->where('key', 'SERVICE_FQDN_TWENTY_3000')->value('value'))->toBe('crm.example.com:3000')
|
||||
->and($this->service->applications()->where('name', 'worker')->value('fqdn'))->toBeNull();
|
||||
});
|
||||
|
||||
Reference in New Issue
Block a user