[PR #75] [MERGED] feat(network): resolve container names on the managed bridge (/etc/hosts DNS) #73

Closed
opened 2026-10-15 12:51:48 +00:00 by bsakaguchi · 0 comments
Owner

📋 Pull Request Information

Original PR: https://github.com/games-on-whales/LXC2Docker/pull/75
Author: @JBailes
Created: 6/8/2026
Status: ✅ Merged
Merged: 6/8/2026
Merged by: @JBailes

Base: main ← Head: feat/container-name-dns


📝 Commits (1)

  • ce676f9 feat(network): resolve container names on the managed bridge (/etc/hosts DNS)

📊 Changes

3 files changed (+439 additions, -2 deletions)

View changed files

➕ internal/lxc/dns_hosts.go (+247 -0)
➕ internal/lxc/dns_hosts_test.go (+171 -0)
📝 internal/lxc/manager.go (+21 -2)

📄 Description

Problem

LXC2Docker has no embedded DNS resolver, so containers on the managed bridge can only reach each other by IP. Any caller that bakes a peer's bridge IP into config breaks when that peer is recreated onto a new address — the IP drifts, the dependent keeps dialing the dead one. (Concretely: a service pointed at its database by IP crash-loops after the database is recreated on a new bridge IP.)

Fix

Add Docker libnetwork-style name resolution via /etc/hosts. The daemon writes name→IP records (container name + network aliases) for every container that shares a network into each container's /etc/hosts, and keeps them current. A dependent addressing a peer by name now resolves it to wherever it currently lives, with no recreate.

  • dns_hosts.go — hostsPeersFor groups containers by shared (canonical) network from the store; renderManagedHostsBlock + composeHostsFile splice a markers-delimited managed block into /etc/hosts, replacing any prior block and preserving the image's localhost lines and --add-host entries. writeContainerHosts writes atomically (temp + rename), only when content changed.
  • StartContainer — seeds a container's /etc/hosts before it starts (so its first outbound dial resolves) and syncs peers after it's running.
  • 30s network reconciler — now also calls syncHosts, so a peer that drifts to a new bridge IP is resolvable again within seconds without recreating the dependent.

Resolution is scoped to shared networks (containers on different networks don't leak into each other's /etc/hosts). Only the daemon's managed block is touched — non-managed content is never modified.

Tests

go build ./... + go test ./... green. New unit tests cover: canonical network folding, per-network grouping with no cross-network leakage, managed-block render/splice/replace idempotency, and an end-to-end syncHosts sweep including an IP-drift scenario (peer moves → dependent's /etc/hosts follows, stale entry removed, no duplication).

Notes

  • Backend-agnostic: rootfs path resolves for both raw-LXC (lxcPath/<id>/rootfs) and Proxmox (pveRootfsPath(vmid)).
  • Self-records are included (matching Docker, which maps a container's own name → its IP).

🔄 This issue represents a GitHub Pull Request. It cannot be merged through Gitea due to API limitations.

## 📋 Pull Request Information **Original PR:** https://github.com/games-on-whales/LXC2Docker/pull/75 **Author:** [@JBailes](https://github.com/JBailes) **Created:** 6/8/2026 **Status:** ✅ Merged **Merged:** 6/8/2026 **Merged by:** [@JBailes](https://github.com/JBailes) **Base:** `main` ← **Head:** `feat/container-name-dns` --- ### 📝 Commits (1) - [`ce676f9`](https://github.com/games-on-whales/LXC2Docker/commit/ce676f9e7f4c7331b3d2da53b680deec7a4a516f) feat(network): resolve container names on the managed bridge (/etc/hosts DNS) ### 📊 Changes **3 files changed** (+439 additions, -2 deletions) <details> <summary>View changed files</summary> ➕ `internal/lxc/dns_hosts.go` (+247 -0) ➕ `internal/lxc/dns_hosts_test.go` (+171 -0) 📝 `internal/lxc/manager.go` (+21 -2) </details> ### 📄 Description ## Problem LXC2Docker has no embedded DNS resolver, so containers on the managed bridge can only reach each other by **IP**. Any caller that bakes a peer's bridge IP into config breaks when that peer is recreated onto a new address — the IP drifts, the dependent keeps dialing the dead one. (Concretely: a service pointed at its database by IP crash-loops after the database is recreated on a new bridge IP.) ## Fix Add Docker libnetwork-style name resolution via `/etc/hosts`. The daemon writes name→IP records (container name + network aliases) for every container that **shares a network** into each container's `/etc/hosts`, and keeps them current. A dependent addressing a peer by **name** now resolves it to wherever it currently lives, with no recreate. - **`dns_hosts.go`** — `hostsPeersFor` groups containers by shared (canonical) network from the store; `renderManagedHostsBlock` + `composeHostsFile` splice a **markers-delimited managed block** into `/etc/hosts`, replacing any prior block and **preserving** the image's localhost lines and `--add-host` entries. `writeContainerHosts` writes **atomically** (temp + rename), only when content changed. - **`StartContainer`** — seeds a container's `/etc/hosts` *before* it starts (so its first outbound dial resolves) and syncs peers after it's running. - **30s network reconciler** — now also calls `syncHosts`, so a peer that drifts to a new bridge IP is resolvable again within seconds **without recreating the dependent**. Resolution is scoped to **shared networks** (containers on different networks don't leak into each other's `/etc/hosts`). Only the daemon's managed block is touched — non-managed content is never modified. ## Tests `go build ./...` + `go test ./...` green. New unit tests cover: canonical network folding, per-network grouping with no cross-network leakage, managed-block render/splice/replace idempotency, and an end-to-end `syncHosts` sweep including an IP-drift scenario (peer moves → dependent's `/etc/hosts` follows, stale entry removed, no duplication). ## Notes - Backend-agnostic: rootfs path resolves for both raw-LXC (`lxcPath/<id>/rootfs`) and Proxmox (`pveRootfsPath(vmid)`). - Self-records are included (matching Docker, which maps a container's own name → its IP). --- <sub>🔄 This issue represents a GitHub Pull Request. It cannot be merged through Gitea due to API limitations.</sub>
bsakaguchi 2026-10-15 12:51:48 +00:00
Sign in to join this conversation.
No labels
pull-request
No milestone
No project
No assignees
1 participant
Notifications
Due date
The due date is invalid or out of range. Please use the format "yyyy-mm-dd".

No due date set.

Dependencies

No dependencies set.

Reference
games-on-whales/LXC2Docker#73
No description provided.