Configure container networking: host network, private network, veth, zones, bridges, and port forwarding.
sdme containers share the host network by default. This tutorial covers all available network modes, from full isolation to multi-container networking.
See also the architecture documentation for implementation details.
With no network flags, containers share the host's network namespace. They see the same interfaces, addresses, and routes. Services bind to the same ports as the host.
This is the simplest mode but means port conflicts are possible. Use --network-zone or --network-veth to avoid them.
sudo sdme new --name mybox -r ubuntu --private-network
The container gets its own network namespace with only a loopback interface. No external connectivity, no internet. Useful for fully isolated workloads that don't need networking.
sudo sdme new --name mybox -r ubuntu --network-veth
Creates a virtual ethernet link between the host and the container. The container gets an interface named host0 with an IP assigned via DHCP. The container can reach the host and the internet.
sdme automatically enables systemd-networkd inside the container so the host0 interface gets configured via DHCP. No manual setup needed.
--network-veth implies --private-network.
Port forwarding maps a host port to a container port. It requires a network interface, so you must use --network-veth, --network-bridge, or --network-zone alongside --port.
sudo sdme new --name myweb -r nginx --network-veth --port 8080:80
This forwards host port 8080 to container port 80. Format:
--port HOST:CONTAINER --port HOST:CONTAINER/tcp --port HOST:CONTAINER/udp
Multiple --port flags can be used. TCP is the default protocol.
Port forwarding creates nftables DNAT rules for incoming traffic. It works for connections from other machines on the network and from the host via its external IP, but not via localhost (127.0.0.1). To reach a container from the host, use the container's IP directly; find it with sdme ps.
Zones are the easiest way to set up multi-container networking. Zone names are arbitrary strings. Containers on the same zone share a bridge and can communicate with each other by IP or hostname.
sudo sdme new --name http-server -r nginx --network-zone=myzone
sudo sdme new --name http-client -r ubuntu --network-zone=myzone
Both containers get DHCP addresses on the zone bridge. sdme automatically:
systemd-networkd inside each containersystemd-resolved and configures LLMNR/mDNS (local hostname discovery) so containers can discover each other by nameFrom inside http-client, you can reach http-server by name:
curl http://http-server
Port forwarding works with zones. Use sdme ps to find the container's IP:
sudo sdme new --name myweb -r nginx --network-zone=myzone --port 8080:80
sudo sdme ps
--network-zone implies --private-network.
Bridges connect containers to a manually configured host bridge. Unlike zones, you must create and configure the bridge yourself.
Create a bridge on the host:
sudo ip link add sdmebr0 type bridge
sudo ip addr add 10.99.0.1/24 dev sdmebr0
sudo ip link set sdmebr0 up
Create containers on the bridge:
sudo sdme create --name server -r nginx --network-bridge=sdmebr0
Containers on a bridge need static IP configuration. Write a networkd config to the container's overlayfs upper layer before starting:
sudo tee /var/lib/sdme/containers/server/upper/etc/systemd/network/10-bridge.network <<EOF
[Match]
Name=host0
[Network]
Address=10.99.0.2/24
DNS=10.99.0.1
EOF
sudo sdme start server
--network-bridge implies --private-network.
Zones are simpler than bridges for most use cases. Use bridges when you need to integrate containers with an existing host bridge or require static IP assignments.
By default, sdme masks systemd-resolved.service inside containers that use host networking. This prevents the container's resolved from conflicting with the host's DNS on port 53.
When using --network-veth, --network-zone, or --network-bridge, sdme automatically unmasks resolved and symlinks /etc/resolv.conf to the resolved stub so DNS works inside the container.
Zones additionally configure LLMNR/mDNS for inter-container hostname discovery.
You can override the masking behavior with --masked-services:
Mask resolved explicitly (even with a zone):
sudo sdme new --name mybox -r ubuntu --network-zone=myzone --masked-services systemd-resolved.service
Disable all masking:
sudo sdme new --name mybox -r ubuntu --masked-services=''
The default masked services are controlled by the default_create_masked_services config key.
Mode Flag Internet Multi-container Setup --------------- ------------------ -------- --------------- ---------- Host (default) (none) Yes Shared ports None Private --private-network No No None Veth --network-veth Yes No None Zone --network-zone=X Yes Yes (auto DNS) None Bridge --network-bridge=X Yes Yes (manual IP) Host bridge
Port forwarding (--port) works with veth, zone, and bridge modes for external access. From the host, use the container's IP directly.