Bridge network for containers

I’m struggling to get bridge networking work for an oci-containers. Below are the relevant config snippets. When I try to rebuild, I get the following error:

error: The option `virtualisation.oci-containers.containers.logitechmediaserver.hostBridge` does not exist. Definition values:
       - In `/home/shamus/etc/nixos/containers.nix': "br0"

My goal is to assign the container its own IP address, thereby eliminating any port. Is bridge networking the correct way to accomplish this?

networking.nix

  networking = {
    hostName = "NixOS";
    defaultGateway = "192.168.2.1";
    nameservers = [ "192.168.100.101" "192.168.100.100" ];

    useDHCP = false;
    bridges.br0.interfaces = [ "enp1s0" ];
    interfaces.br0.ipv4.addresses = [{
      address = "192.168.2.11";
      prefixLength = 24;
    }];
  };

containers.nix

  virtualisation.podman = {
    enable = true;
    autoPrune.enable = true;
    dockerCompat = true;
  };
  
  virtualisation.oci-containers = {
    containers = {
      logitechmediaserver = {
        autoStart = true;
        image = "lmscommunity/logitechmediaserver:stable";
        privateNetwork = true;
        hostBridge = "br0";
        localAddress = "192.168.2.12/24";
        volumes = [
          "/etc/localtime:/etc/localtime:ro"
          "/etc/timezone:/etc/timezone:ro"
        ];
      };
    };
  };

No, it is not. This is not nixos specific, but there is a lot of documentation regarding container networking available online.

Macvlan might be what you need, depending on why you want to assign the container an ip. But you have to read up on it, otherwise it’s quick and easy to lock yourself out of your machine :slight_smile:

Thank you for your suggestion. Doing some research, it looks like macvlans might be closer to what I’m trying to do. Taking a step back, I’m attempting to declaratively configure a container to emulate Docker’s “network_mode: host”. The reason for not simply opening specific ports is that there are services like Airplay inside the container that make this very hard to confine.

That being said I tried the following for macvlans, but continue to get errors:

networkings.nix

  networking = {
    hostName = "NixOS";
    defaultGateway = "192.168.2.1";
    nameservers = [ "192.168.100.101" "192.168.100.100" ];

    useDHCP = false;
    interfaces.enp1s0.ipv4.addresses = [ {
      address = "192.168.2.11";
      prefixLength = 24;
    } ];
  };

containers.nix

virtualisation.podman = {
    enable = true;
    autoPrune.enable = true;
    dockerCompat = true;
  };
  
  virtualisation.oci-containers = {
    containers = {
      logitechmediaserver = {
        autoStart = true;
        image = "lmscommunity/logitechmediaserver:stable";
        macvlans = [ "enp1s0" ];
        localAddress = "192.168.2.12/24";
        volumes = [
          "/etc/localtime:/etc/localtime:ro"
          "/etc/timezone:/etc/timezone:ro"
        ];
      };
    };
  };

The hostBridge option is one from nixos-containers and systemd-nspawn configuration, and doesn’t apply for oci-containers.

From a quick glance over the Search results there doesn’t seem to be a direct equivalent there, but you might be able to do something via the extraOptions escape hatch.

Perhaps there’s an option there you can pass to take over a vnic that you prepare beforehand in the host using systemd-networkd?

As I said before, the networking setup isn’t NixOS specific, and it might be easier to understand this setup outside of NixOS (one less layer of abstractions).

I’m not sure below is of any use, but here it goes…

I use macvlan as a part of my network segmentation. I have one host running many containers which interact with other machines on different networks, so each service is in their own network (each on their own vlan). This way I get really fine-grained control over access, as everything is routed through my firewall.

So for my use case, to use macvlan in particular, you need a few things setup:

  • a sub-interface for the vlan
  • a bridge which has the vlan sub-interface as a member
  • a container network (podman network create -d macvlan -o parent=bridge-interface-name-replace-me --add-all-other-options-needed-for-your-setip generic-name-replace-me)

With that setup, I then create containers who are in the container network, like below:

$ podman container create \
--label io.containers.autoupdate=registry \
--name gitea \
--ip=192.168.0.68 \
--dns=192.168.0.1 \
--network generic-name-replace-me \
-v /path/to/data:/data \
-v /path/to/config/:/etc/gitea \
-v /etc/timezone:/etc/timezone:ro \
-v /etc/localtime:/etc/localtime:ro \
--memory 1024m \
--cpus=1 \
codeberg.org/forgejo/forgejo:1.20
1 Like