I think, there is no way to have avahi assigning you a static IP address (an IP address looks something like 192.168.0.23 for IPv4 or 2001:DB8:F001:BEEF::23 for IPv6).
What you are probably talking about is the domain name, avahi is announcing to the network (raspberrypi.local). This domain name is resolved (translated) somewhere in the network to an IP address, because this IP address is the number your net is using to deliver the IP packets to the target.
The translation domain name => IP address is usually done by a Domain Name System Server (DNS Server). There usually is no DNS Server in a simple home network. Sometimes your Wifi router is doing some DNS stuff. But in your case, you are doing the name resolving stuff with avahi.
This is how avahi works:
The avahi daemon on your RPi is choosing some link local IP address (say 169.254.0.1, you should see this in your ifconfig output, link local addresses are always beginning with 169.254) and then it is sendig messages through the net, announcing: 169.254.0.1 should now be called raspberrypi.local.
These kind of messages are received by other avahi daemons or by zeroconf daemons on Macs. zeroconf will write on it's list: 169.254.0.1 is now called raspberrypi.local.
If you type ssh raspberrypi.local
on your Mac, zeroconf will replace raspberrypi.local with 169.254.0.1 and ssh is talking to the correct machine.
It could be, that your RPi is selecting another IP address after a few hours (maybe because nobody talks to it?). And it seems like your Mac is not listening to the annunciation of the new address because it is sleeping, or there is a communication problem between avahi and zeroconf.
Solution:
I would recommend, not to rely on avahi / zeroconf as it is not 100% predictable. I am assuming that your network consists of a router and some devices (at least Mac and RPi). The router is a wifi router where your Mac is connected via wifi and the RPi is connected via ethernet cable. With this network you somehow need to make sure that the IP address of your RPi is always the same. After that, you can somehow map the IP to a domain name.
At first the IP address: You most probably have a DHCP server in your wifi router (this is a standard functionality of home wifi routers). The DHCP server is assigning dynamic IP addresses to the devices in your network. But only to the devices asking for one. To allow all the devices in your network to talk to each other, they all are in the same subnet. The subnet is most probably 192.168.0.0/24 or 192.168.1.0/24. This means, all addresses in your network are starting with 192.168.0. or 192.168.1. and only the part after the last point is changing. (Note: This is a different subnet than avahi and zeroconf are using. Every device can be in different subnets). To know the subnet, look at the first three parts of the IP address of your router, your Mac and/or your RPi.
To know where to reach your RPi from your Mac, you can do (for example) one of these four things:
Setup a static IPv4 address on your RPi in /etc/network/interfaces
or in NetworkManager. This address should be outside the range of addresses, your DHCP server (in your Wifi router) is using so that no other device will get the same address, sometimes you can configure this range. But the address needs also to be within the subnet, your Mac is in. The /etc/network/interfaces
would look like
iface eth0 inet static
address 192.168.1.23
netmask 255.255.255.0
gateway 192.168.1.1
gateway would be the address of your router, netmask the same as here, address: the same as the address of your router but with a different number after the last point. Remove other sections starting with iface eth0 inet
.
- Setup the DHCP server to assign always the same IP address to your RPi. It will identify the RPi with its MAC address. You will have to enter it in the config interface of your router. You can find the RPi's MAC addres in the output of
ifconfig
look for a number like b8:27:eb:XX:XX:XX in the eth0
section.
Setup a static IPv6 address on your RPi and on your Mac. This is my favorite option, as you don't have to care about DHCP ranges. But you will need a router that understands IPv6 and if you are using a switch, it needs to be a dumb link layer switch, or if it is a managed switch, it needs to understand IPv6.
- Generate IPv6 Unique Local Address (ULA) with this tool or make one up. It will look like fdxx:xxxx:xxxx::/48.
Add a number after the last colon (fdxx:xxxx:xxxx::23) and put it in your RPiS' /etc/network/interfaces
file after the other stuff:
iface eth0 inet6 static
address fdxx:xxxx:xxxx::23
netmask 64
Add another number after the last colon (fdxx:xxxx:xxxx::42) and configure that in your Mac. I don't know how as I am not a Mac user. But most probably there is a /private/etc/network/interfaces
file, or you can add a IPv6 ULA via the Network configuration UI.
- Tell your network's router to assign a domain name to your RPi (it will identify the RPi with its MAC address, assign a dynamic IP address via DHCP and resolve the domain name to this address). Not all routers have that functionality.
Assign a name to the fixed IP address, you configured in points 1, 2 or 3:
On your mac, you can add the ip address together with a name to your /private/etc/hosts
file like
192.168.1.23 raspberrypi.local
or for the IPv6 address:
fdxx:xxxx:xxxx::23 raspberrypi.local
This would be enough to use raspberrypi.local
to talk to your RPi with different programs. To simplify your life further more with SSH, you can also create a SSH config file in your user directory in USERDIR/.ssh/config
. For the IPv4 address it would look like
Host raspberrypi.local
HostName 192.168.1.23
Port 22
User pi
IdentityFile ~/.ssh/id_rsa
or for the IPv6 address like
Host raspberrypi.local
HostName fdxx:xxxx:xxxx::23
AddressFamily inet6
User pi
IdentityFile ~/.ssh/id_rsa
you can omit the IdentityFile
lines. Those are pointing to your SSH key. But if you use it and add the content of your Macs~/.ssh/id_rsa.pub
file to your RPi's ~/.ssh/authorized_keys
file, you can ssh to you RPi without entering a username or password, just:
ssh raspberrypi.local