Static IP Addresses, DHCP Ranges, and Non-Interactive Network Configuration Commands

This topic started out as a question, then after doing some digging ended up figuring it out. Going to post it anyway in case anybody has any input that would work just as well or better.

I will be launching several containers across multiple environments, would like to assign static IPv4 addresses to many of them, while also allotting a range for DHCP to pick up as needed anywhere that I do not specify addresses.

One of the first steps:
Running lxc network edit lxdbr0 and specifying ipv4.address and ipv4.dhcp.ranges.
Using as an example:

root@lab001:~# lxc network show lxdbr0
  ipv4.nat: "true"
  ipv6.address: <ip>
  ipv6.nat: "true"
description: ""
name: lxdbr0
type: bridge
- /1.0/profiles/default
managed: true
status: Created
- none

Launching a container without specifying IP address results in assigning within the range.

Setting a static address for a container can be done with a new one in init before starting, or stopping it first, then updating the network on it, then starting it:

lxc init <image> <container_name>
lxc network attach lxdbr0 <container_name> eth0 eth0
lxc config device set <container_name> eth0 ipv4.address
lxc start <container_name>

It gets interesting when introducing multiple levels of nested containers, although the intention here is that containers within one level can communicate with each other. I had to be sure to not introduce conflicting addresses at different levels. For example, I chose to change lab001 above to only specify ipv4.address and to not specify a dhcp range to open up more flexibility of options with the nested containers within it. I ended up setting both address and range in the 1st level nested container, and chose to reserve a different subnet for each level of nested containers beyond that to help establish a separation across nesting levels, while maintaining connections within each one.

The plan is usually to plug these changes into a script or tool that will automatically run them, basically non-interactive configuration, which means that while the above steps that edit the network (lxdbr0) are useful for learning purposes and to run as needed, they probably cannot be readily used like that in automation, so I turned to the lxd docs:

A non-interactive replacement for lxc network edit can be:

lxc network set lxdbr0 ipv4.address
lxc network set lxdbr0 ipv4.dhcp.ranges

Another is putting it directly in the preseed yaml.

This is probably common knowledge among many here, either way just throwing it in as a bit of information for anybody that may find it useful. It always helps to reference the docs, it often helps to search through past discussions in here, and sometimes helps to google it before asking about it.

The above worked well for me, although input is welcome if there are other ways or any additional useful options when customizing or otherwise altering addresses and networks.


A reboot will help refresh network configuration updates, although shouldn’t be necessary if taking the network device down, updating configuration, then bringing the network device up:

ip link set eth0 down

Apply network configuration changes.

ip link set eth0 up


ip link set lxdbr0 down

Apply network configuration changes.

ip link set lxdbr0 up

May need some confirmation on just one or both of those, I haven’t tested it yet.


It looks like only lxdbr0 needs to go down and up again with the network configuration changes specific to that one. After experimenting with lxc network attach and lxc config device set, it resulted in containers losing the ability to ping internet locations, the attempt was to set specific addresses to bypass DHCP, not sure yet what may have broken the outside connection, possibly changes to eth0 per container. It might be better to have a better understanding of only one feature at a time, those changes were made at the same time as setting network config ipv4.address and ipv4.dhcp.ranges. Back to the docs and the experimentation continues.