mirror of
https://github.com/coollabsio/coolify.git
synced 2026-03-11 08:55:47 +00:00
fix: resolve Docker Compose service name collisions with dots
Services like "api.test" and "api-test" now create unique Traefik labels by normalizing dots to hyphens and adding a 4-char hash suffix. Update docker_compose_domains storage to use original service names instead of transformed names to prevent key collisions. 🤖 Generated with [Claude Code](https://claude.com/claude-code) Co-Authored-By: Claude <noreply@anthropic.com>
This commit is contained in:
parent
0e6a2fc15d
commit
22ce45fb84
2 changed files with 25 additions and 7 deletions
|
|
@ -11,6 +11,16 @@ use Spatie\Url\Url;
|
|||
use Symfony\Component\Yaml\Yaml;
|
||||
use Visus\Cuid2\Cuid2;
|
||||
|
||||
/**
|
||||
* Generate a stable 4-character hash from a service name for uniqueness
|
||||
* This is used to differentiate services like "api.test" and "api-test"
|
||||
* which would otherwise collide when normalized.
|
||||
*/
|
||||
function serviceNameHash(string $serviceName): string
|
||||
{
|
||||
return substr(md5($serviceName), 0, 4);
|
||||
}
|
||||
|
||||
function getCurrentApplicationContainerStatus(Server $server, int $id, ?int $pullRequestId = null, ?bool $includePullrequests = false): Collection
|
||||
{
|
||||
$containers = collect([]);
|
||||
|
|
@ -467,8 +477,13 @@ function fqdnLabelsForTraefik(string $uuid, Collection $domains, bool $is_force_
|
|||
$http_label = "http-{$loop}-{$uuid}";
|
||||
$https_label = "https-{$loop}-{$uuid}";
|
||||
if ($service_name) {
|
||||
$http_label = "http-{$loop}-{$uuid}-{$service_name}";
|
||||
$https_label = "https-{$loop}-{$uuid}-{$service_name}";
|
||||
// Normalize service name for Traefik labels by replacing dots with hyphens
|
||||
// This prevents label parsing issues with service names like "api.test"
|
||||
// Add a 4-char hash to ensure uniqueness for services like "api.test" vs "api-test"
|
||||
$normalized_service_name = str($service_name)->replace('.', '-')->value();
|
||||
$hash = serviceNameHash($service_name);
|
||||
$http_label = "http-{$loop}-{$uuid}-{$normalized_service_name}-{$hash}";
|
||||
$https_label = "https-{$loop}-{$uuid}-{$normalized_service_name}-{$hash}";
|
||||
}
|
||||
if (str($image)->contains('ghost')) {
|
||||
$labels->push("traefik.http.middlewares.redir-ghost-{$uuid}.redirectregex.regex=^{$path}/(.*)");
|
||||
|
|
|
|||
|
|
@ -601,24 +601,27 @@ function applicationParser(Application $resource, int $pull_request_id = 0, ?int
|
|||
if ($resource->build_pack === 'dockercompose') {
|
||||
// Check if a service with this name actually exists
|
||||
$serviceExists = false;
|
||||
$actualServiceName = null;
|
||||
foreach ($services as $serviceNameKey => $service) {
|
||||
$transformedServiceName = str($serviceNameKey)->replace('-', '_')->replace('.', '_')->value();
|
||||
if ($transformedServiceName === $serviceName) {
|
||||
$serviceExists = true;
|
||||
$actualServiceName = $serviceNameKey; // Store the ORIGINAL service name
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
// Only add domain if the service exists
|
||||
if ($serviceExists) {
|
||||
if ($serviceExists && $actualServiceName) {
|
||||
$domains = collect(json_decode(data_get($resource, 'docker_compose_domains'))) ?? collect([]);
|
||||
$domainExists = data_get($domains->get($serviceName), 'domain');
|
||||
// Use the ORIGINAL service name as the key to avoid collisions
|
||||
$domainExists = data_get($domains->get($actualServiceName), 'domain');
|
||||
|
||||
// Update domain using URL with port if applicable
|
||||
$domainValue = $port ? $urlWithPort : $url;
|
||||
|
||||
if (is_null($domainExists)) {
|
||||
$domains->put($serviceName, [
|
||||
$domains->put($actualServiceName, [
|
||||
'domain' => $domainValue,
|
||||
]);
|
||||
$resource->docker_compose_domains = $domains->toJson();
|
||||
|
|
@ -1077,8 +1080,8 @@ function applicationParser(Application $resource, int $pull_request_id = 0, ?int
|
|||
if ($resource->build_pack !== 'dockercompose') {
|
||||
$domains = collect([]);
|
||||
}
|
||||
$changedServiceName = str($serviceName)->replace('-', '_')->replace('.', '_')->value();
|
||||
$fqdns = data_get($domains, "$changedServiceName.domain");
|
||||
// Use the original service name for lookup (no transformation needed)
|
||||
$fqdns = data_get($domains, "$serviceName.domain");
|
||||
// Generate SERVICE_FQDN & SERVICE_URL for dockercompose
|
||||
if ($resource->build_pack === 'dockercompose') {
|
||||
foreach ($domains as $forServiceName => $domain) {
|
||||
|
|
|
|||
Loading…
Reference in a new issue