v0.33.7_docker_hostnames

This commit is contained in:
Mateusz Gruszczyński committed 2026-10-22 19:00:26 +02:00
1 parent f462ca7194
commit 7e625c5876
6 files changed
+90 -73

No files matched your search

+43 -6
View File
@@ -2,6 +2,7 @@ package main
import (
"context"
"crypto/sha256"
"encoding/json"
"fmt"
"io"
@@ -92,20 +93,18 @@ func serviceIdentity(c dockerContainer, p dockerPort) (key, technical string) {
project := c.Labels["com.docker.compose.project"]
composeService := c.Labels["com.docker.compose.service"]
replica := c.Labels["com.docker.compose.container-number"]
suffix := strconv.Itoa(int(p.PrivatePort))
if project != "" && composeService != "" {
if replica == "" {
replica = name
}
key = fmt.Sprintf("compose:%s/%s/%s:%d/%s", project, composeService, replica, p.PrivatePort, p.Type)
technicalBase := project + "-" + composeService
if replica != "1" {
technicalBase += "-" + replica
technical = dnsLabel(name)
if name == "container" {
technical = dnsLabel(composeService)
}
technical = dnsLabel(technicalBase + "-" + suffix)
} else {
key = fmt.Sprintf("container:%s:%d/%s", name, p.PrivatePort, p.Type)
technical = dnsLabel(name + "-" + suffix)
technical = dnsLabel(name)
}
return key, technical
}
@@ -163,5 +162,43 @@ func servicesFrom(containers []dockerContainer) []service {
out = append(out, *item)
}
sort.Slice(out, func(i, j int) bool { return out[i].Key < out[j].Key })
// Prefer the Docker container name. Add the internal port only when names
// collide; retain stable service keys and prevent any duplicate hostnames.
counts := make(map[string]int, len(out))
for _, item := range out {
counts[item.TechnicalName]++
}
for i := range out {
if counts[out[i].TechnicalName] > 1 {
out[i].TechnicalName = dnsLabel(out[i].TechnicalName + "-" + strconv.Itoa(int(out[i].PrivatePort)))
}
}
// Port suffixes can still collide after normalization/truncation.
// Resolve these deterministically using a short hash of the stable key.
counts = make(map[string]int, len(out))
for _, item := range out {
counts[item.TechnicalName]++
}
used := make(map[string]struct{}, len(out))
for i := range out {
name := out[i].TechnicalName
if counts[name] > 1 {
digest := sha256.Sum256([]byte(out[i].Key))
name = fmt.Sprintf("%s-%x", strings.TrimRight(name[:min(len(name), 48)], "-"), digest[:6])
}
// Extremely unlikely hash collisions are still resolved without
// changing the stable key or depending on Docker listing order.
for attempt := 0; ; attempt++ {
candidate := name
if attempt > 0 {
candidate = fmt.Sprintf("%s-%d", name[:min(len(name), 56)], attempt)
}
if _, exists := used[candidate]; !exists {
out[i].TechnicalName = candidate
used[candidate] = struct{}{}
break
}
}
}
return out
}