Docker macvlan Networking on Synology
Give Docker containers on a Synology NAS their own LAN IP addresses with macvlan, or use host networking behind a Cloudflare Tunnel.
On this page
By default, Docker containers on a Synology NAS share the NAS's IP address and need port mappings. A macvlan network gives each container its own address on the LAN, which suits services that expect to own standard ports or be discovered on the network, such as controllers, DNS servers, or anything using broadcast. This page also covers the simpler alternative: host networking behind a Cloudflare Tunnel.
On DSM 7.2 and later, the Docker package is called Container Manager. Run the commands below over SSH as an administrator, with sudo or from a root shell.
Find the Parent Interface
macvlan attaches containers to a physical interface. On Synology, that interface's name depends on whether Open vSwitch is enabled (Virtual Machine Manager turns it on):
ip -br link| Setup | Typical parent |
|---|---|
| Single NIC, no Open vSwitch | eth0 |
| Bonded NICs, no Open vSwitch | bond0 |
| Open vSwitch enabled | ovs_eth0 or ovs_bond0 |
Create the macvlan Network
Reserve a block of LAN addresses for containers that your DHCP server won't hand out. In this example, the LAN is 192.0.2.0/24, the router is 192.0.2.1, and containers get addresses from 192.0.2.192/27 (.192–.223):
docker network create -d macvlan \
--subnet=192.0.2.0/24 \
--gateway=192.0.2.1 \
--ip-range=192.0.2.192/27 \
-o parent=ovs_bond0 \
macvlanWarning
If the --ip-range overlaps your DHCP pool, containers and DHCP clients can end up with the same address. Exclude the range on the router first.
Run a Container on the macvlan Network
Attach a container to the network and, optionally, pin its address:
docker run -d --name <CONTAINER> --restart unless-stopped \
--network macvlan --ip 192.0.2.200 \
<IMAGE>The container is now reachable from other LAN devices at 192.0.2.200 on whatever ports it listens on, with no -p mappings needed.
Let the NAS Reach Its macvlan Containers
The Linux kernel doesn't let a host talk to its own macvlan children through the parent interface. Other LAN devices can reach the containers, but the NAS itself can't. If the NAS needs to reach them, for example so a reverse proxy on the NAS can forward to them, add a macvlan "shim" interface on the host with a spare address and route the container range through it:
ip link add macvlan-shim link ovs_bond0 type macvlan mode bridge
ip addr add 192.0.2.223/32 dev macvlan-shim
ip link set macvlan-shim up
ip route add 192.0.2.192/27 dev macvlan-shimUse an address inside the reserved range that no container uses. These commands don't survive a reboot. On DSM, add them as a Triggered Task that runs as root at Boot-up in Control Panel → Task Scheduler.
Host Networking with a Tunnel
If a service only needs to be reachable from the internet, skip macvlan. Run the service and cloudflared with --network host and point the tunnel at 127.0.0.1. Use a high port so nothing collides with DSM's own web services on 80 and 443.
For example, to publish a shared folder as a static website with Caddy on port 50080:
docker run -d --name caddy --restart unless-stopped --network host \
-v /volume1/docker/caddy/Caddyfile:/etc/caddy/Caddyfile:ro \
-v /volume1/docker/caddy/data:/data \
-v /volume1/<SHARED_FOLDER>:/srv:ro \
caddy:latest/volume1/docker/caddy/Caddyfile:
{
http_port 50080
auto_https off
}
http://files.example.com {
root * /srv
file_server
}Then add an ingress rule to the tunnel's config.yml (or a public hostname in the dashboard) that sends the hostname to Caddy:
ingress:
- hostname: files.example.com
service: http://127.0.0.1:50080
- service: http_status:404Cloudflare terminates HTTPS at its edge, which is why Caddy serves plain HTTP with auto_https off. See Run a Cloudflare Tunnel in Docker for the full cloudflared setup.
Sources
This article is in the public domain (CC0 1.0), code samples included. Use it however helps you.