You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
Make local workload DNS a platform-aware, connectivity-verified runtime capability across supported Axern local environments.
PR #30 fixes the immediate release blocker by discovering non-loopback host resolver IPs, validating them, passing them through the embedded local bundle to axnoded, and exposing a required runtime_dns doctor check. That is the correct near-term boundary: a resolver address that is valid in the outer Node container is not automatically valid inside a nested OCI sandbox.
This issue tracks the remaining long-term product and architecture work. It does not block PR #30 or the current release candidate.
The local Axern stack runs axnoded inside Docker. axnoded then creates nested OCI workloads with their own network namespace.
On a Docker user-defined network, the Node container commonly receives Docker's embedded resolver, such as 127.0.0.11. Copying that address into a nested sandbox is incorrect: loopback is scoped to the sandbox's own network namespace, so it cannot reach the embedded resolver in the outer container.
axnoded intentionally rejects loopback and unspecified resolver addresses. Relaxing that validation would hide the namespace boundary and produce workloads that start successfully but cannot resolve names.
The orchestration/runtime networking layer must therefore materialize DNS configuration that is reachable from the child workload namespace.
axern local discovers non-loopback resolver IPs from supported host resolver files.
AXERN_LOCAL_DNS_NAMESERVERS provides an explicit comma-separated override.
Values are normalized, deduplicated, and required to be valid non-loopback, non-unspecified IP addresses.
The embedded Compose bundle passes the resolved addresses to axnoded through AXNODED_DNS_NAMESERVERS.
axern local doctor reports runtime_dns as a required check.
Axern does not hardcode public DNS servers.
axnoded's strict runtime DNS validation remains unchanged.
This closes the known Docker loopback failure, but static resolver discovery does not prove that a resolver is reachable from the Node container or a nested sandbox.
Problem statement
Local DNS behavior can vary across:
macOS and Linux;
Docker Desktop and Docker Engine;
amd64 and arm64;
systemd-resolved stub and uplink configurations;
IPv4-only, IPv6-only, and dual-stack hosts;
VPN clients and corporate networks;
split-horizon or per-domain DNS;
proxies and restricted egress environments.
A syntactically valid resolver IP may still be unreachable from Docker or the nested workload. In addition, a flat nameserver list cannot fully represent every platform's split-DNS routing policy.
The user-facing goal is that axern local up either produces workloads with functional DNS or fails early with a precise, executable remediation. Users should not need to understand Docker's nested network namespaces.
Design principles
Preserve namespace correctness
Never inject container-local or host-local loopback resolvers into an isolated child namespace unless the runtime deliberately shares that namespace.
Keep ownership at the networking boundary
Local orchestration discovers platform inputs.
The runtime materializes workload DNS configuration.
Workloads do not depend directly on Docker, host resolver files, or private control-plane APIs.
Do not hardcode public DNS
Public resolvers can break private zones, VPNs, compliance requirements, and offline environments.
Prefer automatic behavior with an explicit escape hatch
Automatic discovery should handle normal installations.
AXERN_LOCAL_DNS_NAMESERVERS remains a stable, documented override for managed networks and diagnostics.
Verify from the relevant namespace
Host-side parsing is a precondition, not proof of runtime reachability.
Use the same runtime contract locally and in production
Avoid a Compose-only DNS bypass or a local-only private workload API.
Fail before the first user Run where practical
A required doctor failure is preferable to a workload startup timeout with an indirect OCI error.
Proposed work
Phase 1: connectivity-aware doctor checks
Extend axern local doctor so it distinguishes:
resolver discovery and syntax validation;
reachability from the Node container;
resolution from an isolated test sandbox using the same runtime path as a user Run.
The report should identify the failing layer and provide a direct recommendation. JSON output must expose stable check codes and structured details without leaking sensitive DNS query data.
Candidate checks:
runtime_dns_config: at least one normalized resolver is available;
runtime_dns_node: the Node container can query through the configured resolver set;
runtime_dns_sandbox: a short-lived isolated sandbox can resolve through the materialized runtime configuration.
The exact public check names should be reviewed before stabilization.
Phase 2: supported-platform behavior matrix
Document and test resolver discovery and propagation for:
macOS + Docker Desktop on amd64/arm64;
Linux + Docker Engine on amd64/arm64;
Linux with plain /etc/resolv.conf;
Linux with systemd-resolved stub plus uplink resolver file;
IPv4 and IPv6 resolver addresses;
VPN/split-DNS scenarios where practical in CI or a documented manual qualification environment.
For each platform, define:
discovery source;
precedence rules;
whether search domains and resolver options are preserved;
expected behavior when the source changes while the local stack is running;
the remediation shown by local doctor.
Phase 3: evaluate a managed DNS forwarder
Evaluate whether Axern should run or embed a small DNS forwarder reachable from Node and sandbox namespaces.
A forwarder may provide a stable workload-facing resolver while adapting upstream behavior to Docker Desktop, systemd-resolved, VPN, or platform-native DNS. The evaluation must cover:
split-horizon and per-domain routing support;
dynamic host/VPN resolver changes;
UDP and TCP DNS;
IPv4/IPv6 behavior;
cache correctness and negative caching;
DNSSEC expectations;
lifecycle, health checking, logs, and resource cost;
attack surface and whether untrusted workloads can abuse it;
behavior during local up, down, upgrade, and reset;
whether an existing maintained component is preferable to custom implementation.
Do not adopt a forwarder solely to avoid fixing resolver discovery. It should be introduced only if it materially improves transparent behavior for supported environments.
User experience requirements
Normal users should not need to set DNS environment variables.
axern local up should report the selected DNS strategy without exposing unnecessary host details.
axern local doctor must explain whether failure occurred during discovery, Node connectivity, or sandbox resolution.
Every required failure must include an actionable remediation, such as setting AXERN_LOCAL_DNS_NAMESERVERS and recreating the Node container.
Changing DNS configuration must preserve local data.
local status --output json and local doctor --output json should remain automation-friendly.
Documentation must cover ordinary networks, VPN/corporate DNS, and safe override examples in English and Simplified Chinese.
Security and privacy requirements
Reject loopback and unspecified resolver addresses unless a future networking design explicitly makes them reachable.
Do not silently fall back to a public resolver.
Do not log full private DNS query names by default.
Treat resolver addresses and search domains as operational metadata; avoid sending them to telemetry unless explicitly documented and approved.
Bound diagnostic timeouts and retries so a malicious or unavailable resolver cannot indefinitely block local up or doctor.
A managed forwarder, if adopted, must bind only to the required local/container networks and must not become an open resolver.
Acceptance criteria
Resolver discovery behavior and precedence are specified for every supported local platform.
local doctor differentiates configuration, Node reachability, and sandbox resolution failures.
A real DNS query is executed through the same DNS configuration used by user workloads.
Failure completes within a bounded timeout and gives an executable remediation.
Summary
Make local workload DNS a platform-aware, connectivity-verified runtime capability across supported Axern local environments.
PR #30 fixes the immediate release blocker by discovering non-loopback host resolver IPs, validating them, passing them through the embedded local bundle to axnoded, and exposing a required
runtime_dnsdoctor check. That is the correct near-term boundary: a resolver address that is valid in the outer Node container is not automatically valid inside a nested OCI sandbox.This issue tracks the remaining long-term product and architecture work. It does not block PR #30 or the current release candidate.
Related: #30
Background
The local Axern stack runs axnoded inside Docker. axnoded then creates nested OCI workloads with their own network namespace.
On a Docker user-defined network, the Node container commonly receives Docker's embedded resolver, such as
127.0.0.11. Copying that address into a nested sandbox is incorrect: loopback is scoped to the sandbox's own network namespace, so it cannot reach the embedded resolver in the outer container.axnoded intentionally rejects loopback and unspecified resolver addresses. Relaxing that validation would hide the namespace boundary and produce workloads that start successfully but cannot resolve names.
The orchestration/runtime networking layer must therefore materialize DNS configuration that is reachable from the child workload namespace.
Current behavior after PR #30
axern localdiscovers non-loopback resolver IPs from supported host resolver files.AXERN_LOCAL_DNS_NAMESERVERSprovides an explicit comma-separated override.AXNODED_DNS_NAMESERVERS.axern local doctorreportsruntime_dnsas a required check.This closes the known Docker loopback failure, but static resolver discovery does not prove that a resolver is reachable from the Node container or a nested sandbox.
Problem statement
Local DNS behavior can vary across:
A syntactically valid resolver IP may still be unreachable from Docker or the nested workload. In addition, a flat nameserver list cannot fully represent every platform's split-DNS routing policy.
The user-facing goal is that
axern local upeither produces workloads with functional DNS or fails early with a precise, executable remediation. Users should not need to understand Docker's nested network namespaces.Design principles
Preserve namespace correctness
Keep ownership at the networking boundary
Do not hardcode public DNS
Prefer automatic behavior with an explicit escape hatch
AXERN_LOCAL_DNS_NAMESERVERSremains a stable, documented override for managed networks and diagnostics.Verify from the relevant namespace
Use the same runtime contract locally and in production
Fail before the first user Run where practical
Proposed work
Phase 1: connectivity-aware doctor checks
Extend
axern local doctorso it distinguishes:The report should identify the failing layer and provide a direct recommendation. JSON output must expose stable check codes and structured details without leaking sensitive DNS query data.
Candidate checks:
runtime_dns_config: at least one normalized resolver is available;runtime_dns_node: the Node container can query through the configured resolver set;runtime_dns_sandbox: a short-lived isolated sandbox can resolve through the materialized runtime configuration.The exact public check names should be reviewed before stabilization.
Phase 2: supported-platform behavior matrix
Document and test resolver discovery and propagation for:
/etc/resolv.conf;For each platform, define:
local doctor.Phase 3: evaluate a managed DNS forwarder
Evaluate whether Axern should run or embed a small DNS forwarder reachable from Node and sandbox namespaces.
A forwarder may provide a stable workload-facing resolver while adapting upstream behavior to Docker Desktop, systemd-resolved, VPN, or platform-native DNS. The evaluation must cover:
local up,down,upgrade, and reset;Do not adopt a forwarder solely to avoid fixing resolver discovery. It should be introduced only if it materially improves transparent behavior for supported environments.
User experience requirements
axern local upshould report the selected DNS strategy without exposing unnecessary host details.axern local doctormust explain whether failure occurred during discovery, Node connectivity, or sandbox resolution.AXERN_LOCAL_DNS_NAMESERVERSand recreating the Node container.local status --output jsonandlocal doctor --output jsonshould remain automation-friendly.Security and privacy requirements
local upordoctor.Acceptance criteria
local doctordifferentiates configuration, Node reachability, and sandbox resolution failures.Test plan
Unit and component tests
Integration tests
local down/local upwithout data loss;Release qualification
On macOS/Linux and amd64/arm64, from a directory without Axern source:
axern local up;axern local doctor;local down, change the resolver input, and runlocal upagain;Non-goals
make quickstartflows.Delivery guidance
This work can be delivered incrementally: