evices on your network — each with its own MAC address, IP address, and no NAT or port mapping required. If you want a container to live on a specific VLAN and be reachable like any other host on that subnet, macvlan is the right tool.
The tricky part isn’t Docker — it’s making sure VLAN tagging is correct all the way from your switch to the host interface. Get that wrong and the container will appear to be running while nothing can actually reach it.
What Is a Macvlan Network?
A macvlan network tells Docker to give a container its own virtual MAC address and bind it directly to a physical (or virtual) network interface on the host. From your router and switch’s perspective, the container looks like a separate device plugged into the network.
This is different from the default Docker bridge networking, where containers share the host’s IP and use NAT to talk to the outside world. With macvlan, there’s no NAT, no port mapping, and no proxy — the container gets a real IP on your subnet.
That makes it ideal for:
- Wake-on-LAN tools that need to send magic packets on a specific VLAN
- Network scanners or monitoring tools that need to originate from the correct subnet
- IoT management containers that need to be isolated on a dedicated VLAN
- Any container where you need a predictable, static IP that behaves like a real host
Here’s the honest tradeoff: macvlan containers cannot communicate with the host by default. If your container needs to talk to the machine it’s running on, you’ll need a macvlan shim interface (a second macvlan on the host side) — which is outside the scope of this guide but worth knowing before you start.
If you’re running Docker inside a Proxmox VM, make sure your VM’s network interface is configured to pass VLAN tags through. See how to configure VLANs in Proxmox for that part of the setup.
Macvlan Network Configuration Steps
There are three steps: create the VLAN subinterface on the host, create the Docker macvlan network using that interface, then attach a container to it with a static IP.
1. Create the VLAN Subinterface on the Host
Docker macvlan needs a network interface to bind to. If your container is going on VLAN 240, you need a VLAN-tagged subinterface for VLAN 240 on your host — not just the raw physical interface.
On Ubuntu/Debian systems using Netplan, open your Netplan config file:
sudo nano /etc/netplan/00-installer-config.yaml
Add a VLAN subinterface under your existing interface. Here’s an example where ens18 is the physical interface and VLAN 240 is being added:
network:
version: 2
ethernets:
ens18:
dhcp4: true
vlans:
ens18.240:
id: 240
link: ens18
dhcp4: false
The dhcp4: false on the VLAN interface is intentional — Docker will manage the addressing, not the host. Save the file and apply the config:
sudo netplan apply
Confirm the subinterface came up:
ip link show ens18.240
You should see the interface listed with state UP. If it’s missing or shows DOWN, double-check that VLAN 240 is allowed on the upstream switch port (trunk port) connected to this host. This is the most common place things break — the subinterface looks fine on the host but the switch is dropping the tagged traffic.
If you’re running Docker inside a Proxmox VM and haven’t set up VLAN-aware networking on the bridge yet, the Proxmox VE IP address and network configuration guide covers the bridge setup side of things.
2. Create the Docker Macvlan Network
Now create a Docker macvlan network that uses the VLAN subinterface as its parent. Replace the subnet, gateway, parent interface, and network name to match your environment:
sudo docker network create \
-d macvlan \
--subnet=10.2.40.0/24 \
--gateway=10.2.40.1 \
-o parent=ens18.240 \
vlan240_macvlan
What each flag does:
--subnet— The IP range for this network. Should match your VLAN 240 subnet exactly.--gateway— Your router’s IP on this VLAN. Docker doesn’t use this for routing decisions, but it’s required for the network definition.-o parent— The host interface Docker will attach to. This must be the VLAN subinterface (ens18.240), not the raw physical interface (ens18).- The final argument is the network name — call it whatever makes sense for your setup.
Confirm it was created:
docker network ls
You should see vlan240_macvlan listed with driver macvlan.
One thing to keep in mind: the IP addresses you assign to containers on this network need to come from your VLAN 240 subnet, and they should not overlap with your DHCP pool. Either assign IPs outside the DHCP range or add static reservations in your router. If two devices on the VLAN end up with the same IP, both will have connectivity issues and it’s annoying to debug.
3. Attach a Container to the Macvlan Network with a Static IP
In Docker Compose, reference the macvlan network as external (since you created it manually in step 2) and assign a static IP to the container:
services:
upsnap:
image: ghcr.io/seriousm4x/upsnap:latest
networks:
vlan240_macvlan:
ipv4_address: 10.2.40.200
networks:
vlan240_macvlan:
external: true
The external: true tells Docker Compose not to try creating the network — it already exists. The ipv4_address pins the container to a specific IP on the VLAN.
Bring it up:
docker compose up -d
Then verify the container got the right IP:
docker inspect upsnap | grep IPAddress
From another device on VLAN 240, try pinging 10.2.40.200. If it responds, you’re done. If it doesn’t, work back through the chain: is the subinterface up, is the macvlan network using the right parent, is the switch port trunking VLAN 240?
Once your containers are running, backing up your Docker containers is worth doing before you make further network changes — macvlan config changes sometimes require recreating containers.
A Note on VLAN Tagging End-to-End
The most common reason macvlan setups fail silently is a gap in the VLAN tag chain. Every hop needs to be configured:
- Your router/firewall — VLAN 240 needs to exist as a routed interface or VLAN interface. If you’re using pfSense or OPNsense, check out how to set up a VLAN in pfSense for the firewall side.
- Your switch — The port connecting to your Docker host must be a trunk port that allows VLAN 240.
- Your host interface — The VLAN subinterface (step 1 above) must be up and passing tagged traffic.
- The Docker network — Must use the VLAN subinterface as the parent, not the raw physical interface.
If you’re on Unifi and setting this up alongside a guest or IoT VLAN, setting up a guest network VLAN on Unifi walks through the switch and access point configuration.
Missing any one of these and the container appears online while being completely unreachable — which is exactly as frustrating as it sounds.
FAQ
What is Docker macvlan used for?
Docker macvlan gives containers their own MAC address and IP address on your physical network, eliminating the need for NAT or port mapping. It’s most useful when a container needs to appear as a real device on a specific subnet — common for Wake-on-LAN tools, network scanners, and IoT management containers that need to be on a dedicated VLAN.
Can a Docker macvlan container communicate with the host?
Not by default. Macvlan isolates the container from the host at the network level, so the container can talk to other devices on the VLAN but not the machine it’s running on. To work around this, you can create a macvlan interface on the host side as well (sometimes called a shim interface), which gives the host an IP on the macvlan network.
What’s the difference between macvlan and bridge networking in Docker?
With bridge networking, containers share the host’s IP and use NAT to reach the outside world. With macvlan, each container gets its own IP directly on your physical network — no NAT, no port forwarding. Macvlan behaves more like adding a new device to your network, while bridge networking behaves more like a software router sitting between the container and your LAN.
Why is my macvlan container unreachable even though Docker shows it running?
The most likely cause is a VLAN tagging gap somewhere in the chain. Check that: (1) the VLAN subinterface on the host is up (ip link show), (2) the Docker macvlan network is using the subinterface as parent — not the raw physical interface, (3) the upstream switch port is configured as a trunk that allows your VLAN, and (4) the IP you assigned isn’t conflicting with another device on that VLAN.
Do I need to set up the VLAN subinterface every time the host reboots?
If you configured it in Netplan (as shown in step 1), it will persist across reboots automatically. Netplan applies configurations at boot, so ens18.240 will come back up every time. If you created it manually with ip link, it won’t persist — use Netplan or a systemd-networkd config to make it permanent.
Can I run multiple containers on the same macvlan network?
Yes. Once the macvlan network is created, you can attach as many containers as you want to it — each gets its own static IP on the VLAN subnet. Just make sure each IP is unique and outside your DHCP pool.
Does macvlan work inside a Proxmox VM?
Yes, but the VM’s virtual network interface needs to be configured to pass VLAN tags. In Proxmox, this means the bridge the VM uses must be VLAN-aware, and the VM’s interface should either be on a trunk or have the specific VLAN tag set. See the Proxmox VLAN configuration guide for the full setup. If you’re just getting started with Docker in Proxmox, setting up Docker in Proxmox via a VM is worth reading first.
