docker-compose: full networks support not implemented

I’ve been experimenting with using docker-compose to create an app with macvlan support (uses a modified balena-engine fork that reinstates macvlan support).

The problem is that once deployed to the device, the macvlan device is not working. I suspect that this is because the parent: eth0 configuration is not being carried across from the docker-compose.yml file:

version: '2'
services:
  macvlantest0:
    build: ./macvlan-test
    privileged: true
    networks:
      macvlan0:
        ipv4_address: 192.168.1.200
networks:
  macvlan0:
    driver: macvlan
    driver_opts:
      parent: eth0
    ipam:
      config:
        - subnet: 192.168.1.0/24
          ip_range: 192.168.1.0/24
          gateway: 192.168.1.254

A macvlan device 1_macvlan0 is created on the target, but if I run balena network inspect 1_macvlan0 then I can see that the options.parent field is blank:

"Options": {},

If I manually create a network device on the target then it works:
balena network create -d macvlan --subnet=192.168.2.0/24 --gateway=192.168.2.254 -o parent=eth0 macvlan1

The parent device is configured successfully and I can get macvlan mode working on this device.

So it looks like there is some problem with translating the docker-compose.yml macvlan network configuration into the macvlan device on the target, but no fundamental problem with using macvlan because it can be added manually.

One thing I have noticed is a vague message about the networks field in the docker-compose.yml file being limited on Balena: https://www.balena.io/docs/reference/supervisor/docker-compose/

networks: “Only support specifying network names”

Is docker-compose in Balena limited in functionality compared to standard Docker? Can we not use the networks field in the same way?

Many thanks

You are correct. The supervisor will only create networks you list using the default network driver (bridge), this work would have to be done in order to allow passing network options to balena-engine.

If you want to work around that. I think you could have your app run a init container that is depended on by the rest of your app and have that do the manual creation of the network as you did using the balena-engine cli.

Hi Robert,

That’s great to have confirmation, thanks a lot. I’m happy with the init container method, since I’ve already been able to confirm that it works when the macvlan network is created by hand.

Many thanks for the prompt & helpful reply.

Hi Robert,

If you want to work around that. I think you could have your app run a init container that is depended on by the rest of your app and have that do the manual creation of the network as you did using the balena-engine cli.

Is there a recommended way for the init container to be able to call balena network create? I presume the docker/balena command is only available on the host, and I can’t see any dbus API that allows you to do a balena network create -d macvlan from a container.

Thanks

The approach would be to install balenaEngine in your container and define the io.balena.features.balena-socket label to 'true' for that container in your docker-compose.yml, which will bind mount the engine’s socket into the container.

We don’t currently support the complete set of networks options and have to filter out unsupported options because it would be easy to brick a remote device with incompatible configuration.