Skip to main content
RunBook Academy

Proxmox VEX · LXC ContainersConfiguration

Container networking and storage

Intermediate⏱ ~22 minpct

What you'll learn

  • Configure container network interfaces with bridges, VLANs, and VNets
  • Use the container firewall
  • Mount host paths, NFS, and CephFS inside a container
  • Choose the right storage backend for container workloads
  • Trace a container network path from the guest interface to the physical NIC

Prerequisites

Verified against Proxmox VE 9.2.4 · Proxmox Backup Server 4.2.5 · Ceph Squid / Tentacle · Debian 13 (Trixie) · Linux kernel 7.0 (PVE 9.2 default) · 2026-08-12

Not yet marked complete on this device.

Why this matters in production

Most production container problems are networking or storage problems. Configuring these correctly from the start avoids pain later.

Container networking

Containers can have one or more network interfaces. Each attaches to a bridge on the host.

pct create 200 local:vztmpl/debian-12-standard_12.2-1_amd64.tar.zst --hostname web-ct --net0 name=eth0,bridge=vmbr0,ip=dhcp --cores 2 --memory 1024 --rootfs local-zfs:8

Network options:

OptionPurpose
bridge=Bridge on the host
ip=dhcpDHCP on this interface
ip=10.10.100.50/24Static IP with CIDR
gw=10.10.100.1Default gateway
tag=100VLAN tag (requires VLAN-aware bridge)
firewall=1Enable container firewall
rate=100Rate limit in Mbps

Multiple interfaces

Containers can have multiple NICs for separation:

pct set 200 --net1 name=eth1,bridge=vmbr1,ip=10.20.0.50/24

SDN VNets

Use the VNet name as the bridge:

pct set 200 --net0 name=eth0,bridge=vn-web,ip=dhcp

Container firewall

The container firewall is a separate object from the host firewall, with its own enable flag, its own rule set and its own default policies. Enabling one does not enable the other, and this catches people repeatedly.

Three switches must all be on for a container rule to have any effect:

  1. The datacenter firewall, in /etc/pve/firewall/cluster.fw.
  2. The container’s firewall option, firewall=1 on the net[n] entry.
  3. The rules themselves, in /etc/pve/firewall/<vmid>.fw.
Configuration changecheck all three layers before writing a rule
set -euo pipefail
CTID=200

# 1. Cluster level
grep -E '^enable' /etc/pve/firewall/cluster.fw 2>/dev/null \
|| echo 'cluster firewall not enabled'

# 2. Is the flag set on the interface itself?
pct config "$CTID" | grep -E '^net[0-9]+:' | grep -o 'firewall=[01]' \
|| echo 'firewall= not set on any interface (defaults to off)'

# 3. The rules
cat "/etc/pve/firewall/$CTID.fw" 2>/dev/null || echo 'no rules file'

Container storage

Root filesystem

Every container has a rootfs (rootfs=local-zfs:8). It is a ZFS subvolume, directory, or LVM volume.

Mount points come in three shapes

The value in the first position of mp[n] selects between three quite different things, and the difference decides what vzdump protects.

ShapeWritten asBacked up by vzdump
Volume - PVE allocates it on a storagemp0: local-zfs:32,mp=/dataYes, unless backup=0
Bind - a host directorymp0: /srv/ct-data,mp=/dataNo
Device - a host block devicemp0: /dev/disk/by-id/...,mp=/dataNo
# A volume mount point: 32 GiB allocated on local-zfs, included in backups.
pct set 200 --mp0 local-zfs:32,mp=/data

# A bind mount point: an existing host directory, NOT in backups.
pct set 200 --mp1 /srv/ct-data,mp=/srv-data

There is no nfsmount= sub-option, and no way to bind an NFS export directly. The correct pattern is to mount the export on the host - through a PVE storage definition, or in the host’s /etc/fstab - and then bind the resulting host path into the container.

The full treatment of the ownership arithmetic, the idmap= option and the shared=1 migration trap is in bind mounts and mount points. The short version to carry into any design conversation: a bind mount is a statement that something other than vzdump protects that data, and if you cannot name what, use a volume mount point instead.

Backup behaviour

Mount points can be:

  • backup=1 (default): included in vzdump backups.
  • backup=0: excluded. Useful for ephemeral data or externally-managed storage.

backup applies to volume mount points only. Setting it on a bind mount point changes nothing - the content was never in scope - and the fact that PVE accepts the option without complaint is how a lot of people acquire a false sense of coverage.

Storage backends

BackendUse
local-zfs (zfs subvolume)Default; snapshots; performance
local (directory)Simple; no ZFS features
local-lvm (LVM thin)Thin provisioning; no native snapshots
NFSShared; no native snapshots from container’s POV
CephFSDistributed shared filesystem
Ceph RBD (via krbd)Block device inside container

Production considerations

Verification

Read-only / Safedoes this container's networking and storage actually work
set -euo pipefail
CTID=200

echo '--- network ---'
pct exec "$CTID" -- ip -br addr show
pct exec "$CTID" -- ip route show default
pct exec "$CTID" -- getent hosts deb.debian.org || echo 'DNS RESOLUTION FAILS'

echo '--- the host end of the veth ---'
ip -br link show | grep "veth$CTID" || echo 'NO VETH ON HOST'

echo '--- mounts, and whether they are real ---'
pct exec "$CTID" -- findmnt -no TARGET,SOURCE,FSTYPE \
| grep -vE '^/(proc|sys|dev|run)'

echo '--- can the service account actually write ---'
pct exec "$CTID" -- runuser -u www-data -- \
sh -c 'touch /data/.wtest && rm /data/.wtest && echo "write OK"' \
|| echo 'WRITE FAILED - check ownership and the ID mapping'

The DNS check is there because it is the single most common container networking failure and the one least likely to be caught by pinging an IP. A container with a correct address, a correct route and no working resolver behaves like a container with a network problem, and every layer-3 test you run will pass.

Common mistakes

  • Using bridge=vmbr0 when the production design uses a separate storage or backup bridge.
  • Mounting host paths with permissions that conflict with the unprivileged UID mapping.
  • Forgetting to rate-limit tenant containers.
  • Writing firewall rules without setting firewall=1 on the interface, so nothing is enforced and nothing says so.
  • Expecting backup=0 or backup=1 to mean anything on a bind mount point.
  • Letting the same bridge name mean different networks on different nodes.

Key takeaways

  • Containers attach to bridges through a veth pair; the host end is a real interface you can inspect, filter and rate-limit.
  • Multiple NICs allow traffic separation.
  • Mount points come in three shapes and only one of them is backed up.
  • The container firewall needs three switches on, and a rule set that is not being enforced looks identical to one that is.

Knowledge check

Knowledge check · 5 questions

  1. Q1. Which option enables VLAN tagging on a container network interface?

  2. Q2. A container can have multiple network interfaces.

  3. Q3. Which option excludes a volume mount point from backups?

  4. Q4. A container has a complete, correct firewall rule set in /etc/pve/firewall/200.fw, and traffic that should be blocked passes freely. What is the most likely cause?

  5. Q5. Which statements about the host end of a container’s network interface are correct? Select all that apply.

Passing score: 75%. Answers are checked in this browser.