When running Docker on a Proxmox host, many administrators run into a frustrating and often misunderstood networking issue:
The Proxmox host cannot ping or connect to Docker containers that use a macvlan network — even though other machines on the LAN can.
This behavior isn’t a bug — it’s by design. But with a few well-placed systemd scripts, you can fix it cleanly and persistently. Here’s how.
The Problem: Macvlan Isolation by Design
Docker’s macvlan network driver gives containers direct access to the LAN. Each container gets its own MAC and IP address, and behaves like a first-class network citizen.
But here’s the catch:
The host that creates the macvlan network can’t communicate with its own containers — not even via ping.
This is a known limitation of the Linux macvlan driver: the macvlan interface is logically separate from the host’s network stack.
The Goal
Allow the Proxmox host to communicate with Docker containers on macvlan networks without hacks, hanging boots, or fragile scripting.
Solution: systemd + Macvlan Shim Interfaces
Rather than trying to force it through /etc/network/interfaces with post-up scripts (which can lead to race conditions with Docker), we create a dedicated systemd service that:
- Waits for networking and Docker to be ready.
- Creates macvlan shim interfaces on the host.
- Adds IP routes to Docker containers on macvlan networks.
- Cleans up on shutdown or service stop.
Step-by-Step Setup
1. Create the Shim Setup Script
Create /usr/local/bin/macvlan-setup.sh:
#!/bin/bash
set -e
# macvlan1-shim on vmbr0
ip link show macvlan1-shim >/dev/null 2>&1 || ip link add macvlan1-shim link vmbr0 type macvlan mode bridge
ip addr show dev macvlan1-shim | grep -q 10.0.1.254 || ip addr add 10.0.1.254/32 dev macvlan1-shim
ip link set macvlan1-shim up
# macvlan100-shim on vmbr1
ip link show macvlan100-shim >/dev/null 2>&1 || ip link add macvlan100-shim link vmbr1 type macvlan mode bridge
ip addr show dev macvlan100-shim | grep -q 10.0.100.254 || ip addr add 10.0.100.254/32 dev macvlan100-shim
ip link set macvlan100-shim up
# Add routes to Docker containers
/usr/local/bin/macvlan1-routes.sh || true
/usr/local/bin/macvlan100-routes.sh || true
exit 0
Make it executable:
chmod +x /usr/local/bin/macvlan-setup.sh
2. Create the Cleanup Script
Create /usr/local/bin/macvlan-cleanup.sh:
#!/bin/bash
ip link delete macvlan1-shim 2>/dev/null || true
ip link delete macvlan100-shim 2>/dev/null || true
Make it executable:
chmod +x /usr/local/bin/macvlan-cleanup.sh
3. Create Route Scripts
Each route script should inspect Docker networks and add routes to container IPs. Example /usr/local/bin/macvlan100-routes.sh:
#!/bin/bash
docker network inspect macvlan100 -f '{{range .Containers}}{{.IPv4Address}}{{"\n"}}{{end}}' \
| cut -d/ -f1 \
| while read ip; do
ip route add "$ip" dev macvlan100-shim 2>/dev/null
done
Repeat for macvlan1-routes.sh with the appropriate network name and shim.
Make them executable:
chmod +x /usr/local/bin/macvlan*-routes.sh
4. Create the systemd Service
Create /etc/systemd/system/macvlan-setup.service:
[Unit]
Description=Setup Docker Macvlan Shim Interfaces and Routes
After=docker.service network-online.target
Wants=network-online.target
[Service]
Type=oneshot
ExecStart=/usr/local/bin/macvlan-setup.sh
ExecStop=/usr/local/bin/macvlan-cleanup.sh
RemainAfterExit=true
[Install]
WantedBy=multi-user.target
Reload and enable:
systemctl daemon-reload
systemctl enable macvlan-setup.service
systemctl start macvlan-setup.service
Testing
After starting the service:
ip link show macvlan1-shim
ip link show macvlan100-shim
ping 10.0.100.X # Ping one of your Docker containers
To test cleanup:
systemctl stop macvlan-setup.service
ip link show macvlan100-shim # Should show "Device not found"
Wrap-Up
You’ve now turned a frustrating Docker + Proxmox networking quirk into a clean, automated, and robust solution, fully managed by systemd.
| Component | Purpose |
|---|---|
macvlan-setup.sh | Creates shim interfaces and adds routes |
macvlan-cleanup.sh | Removes shims cleanly |
macvlan*-routes.sh | Dynamically routes to Docker containers |
systemd unit | Ensures correct boot order and clean management |
This not only fixes ping/connectivity issues, but does so in a way that:
- Survives reboots
- Plays nice with Docker and networking startup order
- Can be extended or monitored