Overview

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:latest

Maps 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.conf

Host 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:latest

Use 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:latest

Good 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=localhost

Option 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 clean

Verify: 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}}' radarr

Comparison 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
Deploying a multi-container stack?

Immich is the fleet's reference example for host networking across four services.

Updated

Was this page helpful?