Networking in docker can be confusing. Containers can connect to one or more docker networks (not to be confused with your home LAN network) at any given time. As in the cover image for this post, the IP address of your docker (bridge) networks will start with
172. Traditionally, the default bridge network which is first created when you install docker will be
172.17.0.0/16, however you can create any other subnet within the
172.x.0.0/xx range you like for your own, custom bridge networks.
There are three main types of docker network you will encounter:
The Host Network
As the name suggests, the Host network uses exactly the same IP as the host machine. This is used when the container should (or needs to) be on the same IP address as the host, or needs some settings only available through the host network. This however comes with limitations such as the inability to specify custom port mapping for your container, which can be important if certain host-machine ports are already in use.
Example: I have a container which uses ports I know are not already in use (e.g. port 3000). For simplicity, I can specify the container to use the host network without the need to publish ports in docker-compose or docker run, and the container will be available at
The Bridge Network (click to jump to the how-to section on this page)
Probably the most commonly used. As already mentioned, a default bridge network is created when you install docker. However when using docker-compose, if you create a container without specifying a network, docker will automatically create a new bridge network for your container. This creates a network with an IP in the 172.x.x.x range, and assigns your container IP(s) automatically (unless specified in your container creation process).
Some people are content putting all their containers on the one, default bridge network. Sounds a bit like the one about putting all your eggs in one basket doesn't it? For security, it's recommended that you only use the same network for containers which require it.
Example: I am using Bitwarden as my password manager. There is lots of sensitive data on it, and it has a higher level of built-in security than say Homer. If someone manages to hack into Homer and it is on the same bridge network as my Bitwarden instance, it immediately becomes a lot easier for the hacker to attack Bitwarden. Hence, I keep Bitwarden on its own bridge network
network_mode: bridgevariable) is now a legacy hold-over, and is generally not recommended for use.
The Macvlan (click to jump to the how-to section on this page)
This type of network must be created by the user (either manually via SSH or as part of a
docker-compose.yml setup) and can technically create a network on any private IP subnet, including that of your host's LAN.
Example: if your host is the only machine on a particular subnet and has an IP of 192.168.1.2, the macvlan can be on the same 192.168.1.0/24 subnet and use any unused IP from 192.168.1.3 upwards to 1.254.
This also comes with limitations, mainly that the macvlan network cannot by default communicate with the host machine. If a container requires a macvlan and communication with the host machine, then it must also connect to a second network which will be a bridge network.
Example: I want to use an adblocker such as Adguard or Pihole. I want my NAS to be able to make use of this adblocker, and I want the adblocker to act as my DHCP server.
If I use a host or bridge network for this container, the IP used to access the container will be the same as my NAS, and would cause a whole lot of issues with routing.
I want the container to be on its own, separate IP. For this reason, I create a macvlan network.
But why would I also need it to communicate with the host? Well, Adguard can be secured using SSL, however in some setups/cases it will use a domain certificate requested through and provided by the host. This means it also needs to communicate with the host machine. As the macvlan does not have any connection to the host machine, you must also connect it to a bridge network so that adguard can make this connection.
Again there are a number of ways you can do this:
- with the Synology Docker GUI
- with Portainer (a container itself and overall extremely helpful)
- with SSH
I prefer using SSH. I've had bad experiences with Portainer in the past creating (and then not being able to delete) invalid networks. I flat out don't like the docker GUI. So I now solely use the SSH method.
Bridge Network Creation
- Log in to your SSH session
- Input the following:
docker network create --subnet=172.xx.0.0/24 --gateway=172.xx.0.1 [networknamegoeshere]
For instance, I want to create a network called 'NetMcNetFace' on the 126.96.36.199 network:
/24after the IP subnet specifies how many IP addresses are available, and is called the CIDR.
/24allows you to use all the way from
188.8.131.52. The higher the CIDR number, the fewer the IPs allowed - for instance
184.108.40.206/29would allow you to use
220.127.116.11. More info can be found here
Remember that any networks you set up which require internet access, and which are NOT on the same subnet as your NAS/machine will need to be unblocked in your machine's firewall settings
MacVlan Network Creation
To create a macvlan network it's a little different, we need to specify the driver (
parent (when creating a bridge network, as no driver is specified, it defaults to 'bridge'). From ssh:
docker network create -d macvlan --subnet=xxx.xxx.0.0/24 --gateway=xxx.xxx.0.1 -o parent=[yourHostNetworkAdapter] [networknamegoeshere]
You'll notice there's a bit more going on towards the end here too - you need to specify a parent network. On linux in SSH, this can be achieved by typing
into your SSH session, which will return a bunch of information looking a bit like this:
What we're searching for is the IP address of your NAS or host machine - normally
192.168.0.x. Mine is
192.168.1.2 which corresponds to the
We then use this as our parent network. So if I wanted a container which was accessible from the same subnet as my router (192.168.1.0), I create a macvlan network called MyMacVlan at 192.168.1.0:
docker network create -d macvlan --subnet=192.168.1.0/24 --gateway=192.168.1.1 -o parent=ovs_eth1 MyMacVlan
remember, all commands and information typed into the cli are case sensitive
DSM 7 update:
After upgrading my NAS to DSM 7, I found that the Open vSwitch settings needed for Virtual Machine Manager (which I use for Home Assistant) were conflicting with the macvlan network, and stopping all connectivity to the NAS on that network interface (my LAN 2). The error in question read
network dm-1234567890 is already using parent interface ovs_eth1. I cannot for the life of me identify it this network, nor remove it with a
docker network prune command.
I raised this with Synology, however they're saying that macvlan networks are not supported on Synology Diskstations (even though it's available through the package they publish) and there's nothing they can do to help.
It also looks like this issue has been around for some people for a while,
Specifying a network in docker-compose
As previously shown you can specify a network for a particular container or group of containers to join. To do this, you must specify the networks in the first column, and then specify the network to join in the service:
You'll notice that although we specified two networks at the top of our docker-compose file (
AnotherBridgeNetwork) we only connected our radarr service to
MyMacVlan. This doesn't break anything, but you will receive a notification in your terminal window after the compose has run that a network was specified but not used.
We can go one step further and specify an IP address for our container to join. This means instead of it being randomly assigned every time the container is recreated, it will always have the same IP. When we're sharing the same subnet as the other devices on our router, or we need it to always be accessible at the same IP, this is important.
##############NETWORKS############## networks: MyMacVlan: external: true AnotherBridgeNetwork: external: true ##############NETWORKS############## services: radarr: #movie search and organizing agent image: ghcr.io/linuxserver/radarr container_name: radarr networks: MyMacVlan: ipv4_address: 192.168.1.100
This can be done with either macvlan or bridge networks. In general it is not recommended to assign specific container IPs unless there is a very good reason to, as in some cases it can break the set up.
Finally and alternatively, you could even create the macvlan network in the docker-compose file. If we use the same parameters as the one we created above, it would look something like this:
networks: MyMacVlan: name: MyMacVlan driver: MyMacVlan driver_opts: parent: ovs_eth1 ipam: config: - subnet: 192.168.1.0/24 gateway: 192.168.1.1
The benefit of adding it like this to your docker-compose is that you don't need to create (or then destroy) the network separately to creating the container, as your compose file will do it all for you.
Removing docker networks
In most cases it's easy to remove a docker network. It's even easier with Portainer, but if you don't use or have that:
Make sure that no containers are using the network
You can do this by inspecting a network, for instance
docker network inspect newnetwork returns:
"Containers" you can see there's nothing listed. If there were, you would see something like this:
Note how you can now see the container ID, name, endpoint etc.
If you do have a container listed, then typing
docker network disconnect [network name] [container name] will do it, so:
docker network disconnect newnetwork CFddns
removes the 'CFddns' container from the 'newnetwork' container.
note that in SSH you won't get any confirmation that the command has been successful
Removing/deleting a docker network
Now that your network is no longer being used, you can remove it using the following:
docker network rm [docker network name]
If you run this command when a container is still connected to the network in question, you'll get an error back, but it shouldn't cause any harm to your system.
Removing all unused networks in one go
To do this, you can use the following command:
docker network prune
This is a handy tool for simply removing everything you no longer need, and can be applied to volumes (
docker volume prune) images etc.