Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
15 changes: 13 additions & 2 deletions internal/podman/quadlet_embed_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -404,8 +404,19 @@ func TestGenerateCustomQuadlet_NoShareHosts(t *testing.T) {
Image: "docker.io/library/mongo:7",
}
out := GenerateCustomQuadlet(svc)
if strings.Contains(out, "/etc/hosts") {
t.Errorf("should not mount hosts file when ShareHosts=false, got:\n%s", out)
// Even without ShareHosts, a sidecar service must mount lerd's managed
// /etc/hosts. Otherwise podman falls back to base_hosts_file (the host's
// /etc/hosts by default), where a stale or client-shim "127.0.0.1 lerd-<svc>"
// entry shadows the container-DNS name and breaks connections — e.g.
// lerd-phpmyadmin resolving lerd-mysql to its own loopback (#issue).
wantVolume := "Volume=" + config.ContainerHostsFile() + ":/etc/hosts:ro,z"
if !strings.Contains(out, wantVolume) {
t.Errorf("ShareHosts=false must mount the managed container hosts file to override host inheritance, got:\n%s", out)
}
// The browser-testing hosts variant is reserved for ShareHosts=true.
browserVolume := "Volume=" + config.BrowserHostsFile() + ":/etc/hosts:ro,z"
if strings.Contains(out, browserVolume) {
t.Errorf("ShareHosts=false must not mount the browser hosts file, got:\n%s", out)
}
}

Expand Down
12 changes: 12 additions & 0 deletions internal/podman/quadlet_generate.go
Original file line number Diff line number Diff line change
Expand Up @@ -50,8 +50,20 @@ func GenerateCustomQuadlet(svc *config.CustomService) string {
b.WriteString("PodmanArgs=--init\n")
}

// Always mount a lerd-managed /etc/hosts. Without an explicit mount podman
// synthesises the file from base_hosts_file, which defaults to the host's
// own /etc/hosts — so any "127.0.0.1 lerd-<svc>" entry there (a stale line
// from an older lerd, or one written for a client shim / host-proxy app)
// shadows the container-DNS name and the service resolves to its own
// loopback instead of the peer container, e.g. lerd-phpmyadmin failing to
// reach lerd-mysql with "Connection refused". PHP-FPM containers already
// bind-mount this file; sidecar services (phpmyadmin, pgadmin, mongo-express)
// need it too. ShareHosts services additionally want .test domains resolved
// to nginx, so they get the browser-hosts variant.
if svc.ShareHosts {
fmt.Fprintf(&b, "Volume=%s:/etc/hosts:ro,z\n", config.BrowserHostsFile())
} else {
fmt.Fprintf(&b, "Volume=%s:/etc/hosts:ro,z\n", config.ContainerHostsFile())
}

for _, port := range svc.Ports {
Expand Down
Loading