Networking
Bridge networking (default)#
The container gets its own IP address on a virtual network (usually 10.88.0.0/16).
podman run -d -p 7878:7878 --name radarr ghcr.io/daemonless/radarr:latestMaps a container port to a host port. Requires pf configuration:
# /etc/pf.conf
rdr-anchor "cni-rdr/*"
nat-anchor "cni-rdr/*"
table <cni-nat>
nat on $ext_if inet from <cni-nat> to any -> ($ext_if)
nat on $ext_if inet from 10.88.0.0/16 to any -> ($ext_if)
sysctl net.pf.filter_local=1
echo 'net.pf.filter_local=1' >> /etc/sysctl.conf
pfctl -f /etc/pf.confHost networking#
The container shares the host's network stack directly — no separate IP address, and -p port mapping has no effect (the app listens on the host IP directly).
podman run -d --network=host --name unifi ghcr.io/daemonless/unifi:latestUse it for apps needing L2 network discovery (UniFi adopting APs, SmokePing), avoiding NAT overhead, or a simpler setup without pf configuration.
VNET (virtual network stack)#
VNET gives the jail a private, isolated network stack:
podman run -d --name gitea \
--annotation 'org.freebsd.jail.vnet=new' \
ghcr.io/daemonless/gitea:latestGood for apps managing their own network interfaces or routing (WireGuard, Gitea) and for higher isolation than bridge mode. Standard -p port mapping isn't supported by stock ocijail with VNET — access via the container's internal IP instead. Requires VNET kernel support (default in FreeBSD 13+).
Container-to-container communication#
Multi-container apps (like Immich) need services to find each other, and FreeBSD has some limitations here compared to Linux.
Option 1 — host networking (recommended). All containers share the host network and communicate via localhost:
services:
app:
network_mode: host
environment:
- DB_HOSTNAME=localhost
- REDIS_HOSTNAME=localhostOption 2 — DNS resolution (cni-dnsname). Lets containers resolve each other by name (e.g. postgres, redis) — required for multi-container apps like Immich and Mealie under podman-compose. cni-dnsname isn't in the official FreeBSD ports tree yet; Daemonless maintains a port at daemonless/freebsd-ports:
git clone https://github.com/daemonless/freebsd-ports.git /usr/local/daemonless-ports
cd /usr/local/daemonless-ports/net/cni-dnsname
make install cleanVerify: ls /usr/local/libexec/cni/dnsname should exist. Once installed, containers resolve each other by name (ping immich_postgres, curl http://immich_server:2283).
Option 3 — static IPs. Look up or assign container IPs directly:
podman inspect -f '{{.NetworkSettings.IPAddress}}' radarrComparison summary#
| Feature | Bridge (default) | Host | VNET |
|---|---|---|---|
| IP address | Private (10.88.x.x) | Shared with host | Private (10.88.x.x) |
| Port mapping | Supported (-p) |
Not needed | Not supported |
| Isolation | High | Low | Very high |
| Best for | Most apps | Network discovery | VPNs / high isolation |
| pf required | Yes | No | Yes |
Immich is the fleet's reference example for host networking across four services.