Proxmox VEX · LXC ContainersConfiguration
Container networking and storage
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
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:
| Option | Purpose |
|---|---|
bridge= | Bridge on the host |
ip=dhcp | DHCP on this interface |
ip=10.10.100.50/24 | Static IP with CIDR |
gw=10.10.100.1 | Default gateway |
tag=100 | VLAN tag (requires VLAN-aware bridge) |
firewall=1 | Enable container firewall |
rate=100 | Rate 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:
- The datacenter firewall, in
/etc/pve/firewall/cluster.fw. - The container’s firewall option,
firewall=1on thenet[n]entry. - The rules themselves, in
/etc/pve/firewall/<vmid>.fw.
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.
| Shape | Written as | Backed up by vzdump |
|---|---|---|
| Volume - PVE allocates it on a storage | mp0: local-zfs:32,mp=/data | Yes, unless backup=0 |
| Bind - a host directory | mp0: /srv/ct-data,mp=/data | No |
| Device - a host block device | mp0: /dev/disk/by-id/...,mp=/data | No |
# 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
| Backend | Use |
|---|---|
local-zfs (zfs subvolume) | Default; snapshots; performance |
local (directory) | Simple; no ZFS features |
local-lvm (LVM thin) | Thin provisioning; no native snapshots |
| NFS | Shared; no native snapshots from container’s POV |
| CephFS | Distributed shared filesystem |
| Ceph RBD (via krbd) | Block device inside container |
Production considerations
Verification
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=vmbr0when 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=1on the interface, so nothing is enforced and nothing says so. - Expecting
backup=0orbackup=1to 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
Q1. Which option enables VLAN tagging on a container network interface?
Q2. A container can have multiple network interfaces.
Q3. Which option excludes a volume mount point from backups?
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?
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.