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 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 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 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 http-server -r nginx --network-zone=myzone
sudo sdme new 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 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 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 mybox -r ubuntu --network-zone=myzone --masked-services systemd-resolved.service
Disable all masking:
sudo sdme new 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.