Setting a Static IP for Ethernet

alright, nice, i will see if i can add it to the docker file. would that work?

Hi,

Adding the script to your Dockerfile totally works.

If your original CMD was myapp arg1 arg2 arg3, then modify the script (named it start.sh for now) to end with

myapp "$@"

And change your Dockerfile to include it:

COPY start.sh /root/start.sh
RUN chmod +x /root/start.sh
CMD [ "/root/start.sh", "arg1", "arg2", "arg3" ]

You can then set (or not) the environment variables per device to change the IP.

1 Like

hi, @TJvV sorry to open this again, but it looks like it stopped working. this method was running fine, but now after boot, it runs, shows the ip’s but the reverts back to a single ip address.

any idea why?

after boot
image

after 1 min
image

this is the current setup

 if [[ -n "${MY_IP_ENV_VAR}" && -n "${MY_IFACE_ENV_VAR}" ]]; then
    echo "Setting Network IP and IFACE from device variables... "
    echo "setting  "${MY_IFACE_ENV_VAR}" ip: ${MY_IP_ENV_VAR}"
    ip address add "${MY_IP_ENV_VAR}" dev "${MY_IFACE_ENV_VAR}"
 fi

echo "adding stream multicast IP to list"
ip address add "${MULTICAST_IP_ENV_VAR}" dev "${MY_IFACE_ENV_VAR}" autojoin

with MY_IP_ENV_VAR = 192.168.2.23/16
MY_IFACE_ENV_VAR = eth0
MULTICAST_IP_ENV_VAR = 234.0.0.59/32

eth1 - 192.168.1.23 (on local network)
This is also happening on a number of devices with the same setup

Sorry for taking so long to get back to this; I will look into this tonight.

In the meantime, did anything change in your setup?
Maybe you updated to a newer version, maybe the configuration in your router changed?

hi @TJvV , not a problem! yes i did, i ended up using nmcli, but i haven’t fully tested it yet. i had trouble setting the multicast ip as it looks like it clashed with the device which was casting on this address (a camera rtsp stream), so that part is commented out.

if [[ -n "${MY_IP_ENV_VAR}" && -n "${MY_IFACE_ENV_VAR}" ]]; then
    echo "Setting Network IP and IFACE from device variables... "
    echo "setting  "${MY_IFACE_ENV_VAR}" ip: ${MY_IP_ENV_VAR}"
    echo "Adding IPs to list"
    #add the IP to list
    nmcli dev mod "${MY_IFACE_ENV_VAR}" ipv4.addresses "${MY_IP_ENV_VAR}"
    # add multicast
    #echo "adding stream multicast IP to list"
    #nmcli dev mod "${MY_IFACE_ENV_VAR}" ipv4.addresses "${MULTICAST_IP_ENV_VAR}"
    # add gateway and DNS
    nmcli dev mod "${MY_IFACE_ENV_VAR}" ipv4.gateway "${MY_GATEWAY_IP_VAR}"
    nmcli dev mod "${MY_IFACE_ENV_VAR}" ipv4.dns "8.8.8.8"
 
   # Change the addressing from DHCP to static.
    nmcli dev mod "${MY_IFACE_ENV_VAR}" ipv4.method manual
    # To save the changes, run the command
    nmcli con up "${MY_IFACE_CON_VAR}"
 fi

echo "IP list"
nmcli -p d

Hi,

It took a little longer to get around to this than hoped.
As far as I can tell, running it from nmcli instead of ip should work just fine.
At least it seems to do so for me.

The multicast bit is new to me.
It feels like this isn’t supported by the default busybox implementation of ip though.
This would’ve been covered by ip maddr, but that isn’t accepted as a known option/command.
EDIT: this IS supported when running a bullseye version of the image.

I did however notice in your script that you are modifying your device.
When you change the method to manual, you also tell it to discard the IP address you got from DHCP. When you bring up your connection however, you overwrite those changes to the device and go back to just the DHCP.

If you take out the last 2 commands (ipv4.method and con up), you should be good.

Just so we’re on the same page, I’m trying this on a raspberry pi 4, with BalenaOS 2.108.18+rev2 development image.
My Dockerfile is

FROM balenalib/raspberrypi4-64-python

RUN install_packages network-manager

COPY start.sh /root/start.sh
RUN chmod +x /root/start.sh

ENV DBUS_SYSTEM_BUS_ADDRESS=unix:path=/host/run/dbus/system_bus_socket
ENV MY_IP_ENV_VAR=192.168.1.240/24
ENV MY_IFACE_ENV_VAR=eth0
ENV MY_IFACE_CON_VAR="Wired connection 1"
ENV MY_GATEWAY_IP_VAR=192.168.1.1
ENV MULTICAST_IP_ENV_VAR=234.0.0.59/32

CMD ["/root/start.sh", "balena-idle"]

The start.sh:

#!/bin/bash

if [[ -n "${MY_IP_ENV_VAR}" && -n "${MY_IFACE_ENV_VAR}" ]]; then
    echo "Setting Network IP and IFACE from device variables... "
    echo "setting  "${MY_IFACE_ENV_VAR}" ip: ${MY_IP_ENV_VAR}"
    echo "Adding IPs to list"
    #add the IP to list
    nmcli dev mod "${MY_IFACE_ENV_VAR}" ipv4.addresses "${MY_IP_ENV_VAR}"
    # add multicast
    #echo "adding stream multicast IP to list"
    #nmcli dev mod "${MY_IFACE_ENV_VAR}" ipv4.addresses "${MULTICAST_IP_ENV_VAR}"
    # add gateway and DNS
    nmcli dev mod "${MY_IFACE_ENV_VAR}" ipv4.gateway "${MY_GATEWAY_IP_VAR}"
    nmcli dev mod "${MY_IFACE_ENV_VAR}" ipv4.dns "8.8.8.8"

   # Change the addressing from DHCP to static.
# TJvV: Disabled this to keep DHCP assisgned IP    
    # nmcli dev mod "${MY_IFACE_ENV_VAR}" ipv4.method manual
    # To save the changes, run the command
# TJvV: Disabled this to not overwrite the changes we just made
    # nmcli con up "${MY_IFACE_CON_VAR}"
 fi

echo "IP list"
nmcli -p d

$@

I will see if I can dig up some more info regarding the multicast bit.

EDIT: if you enable your nmcli command for the multicast address, it will simply overwrite the previously set address; if you want them both, you will need to specify both:

nmcli dev mod "${MY_IFACE_ENV_VAR}" ipv4.addresses "${MY_IP_ENV_VAR}","${MULTICAST_IP_ENV_VAR}"
1 Like

Hello,

I’m trying to set a static IP address for a raspberry pi 4. I’ve been following the tutorial here but it is always ignored and it goes back to DHCP.
Also, testing the nmcli and ip address commands here mentioned, I have managed to manually set an IP, but I always have two IPs, the one provided by DHCP and the manual one.
How can I configure it so that it will always set only one IP on startup, the static IP address?
I am running several containers in the device.
This is my connection file:

[connection]
id=my-ethernet
type=ethernet
interface-name=eth0
permissions=
secondaries=

[ethernet]
mac-address-blacklist=

[ipv4]
address1=192.168.1.99/24,192.168.1.1
dns=192.168.1.1;8.8.4.4;
dns-search=
method=manual

[ipv6]
addr-gen-mode=stable-privacy
dns-search=
method=auto

Forget my comment, when removing the .ignore extension in my mac, it was just hiding the extension, not actually removing it.
Now I need to figure out how to make this remotely