NixOS 25.11 – How to Upgrade

Recently the NixOS 25.11 release was announced. As my new server is based on NixOS it was time to do an upgrade and stay current. Moving from 25.05 to 25.11 turns out to be fairly straight forward, and you can uplift multiple versions without much pain or risk. I was also able to update directly from 24.11 to 25.11 in a single step for an old hacky desktop I was experimenting with.

Upgrading is very simple, first figure out which version you are on.

Then it’s just two command lines to do the upgrade.

A full reboot cycle is a good idea to make sure all is well, but shouldn’t be strictly required. The upgrade instructions are clear and easy to follow.

You’ll notice that I’ve selected the small channel, which is suggested for servers. It will not contain the some of the desktop components – but has the benefit of being updated sooner than the “full” version. Another server I had was using 25.11 full channel, and I used the same approach above to switch to the small channel.

NixOS has a very predictable upgrade cadence, twice a year in May and November. The downside is they very quickly deprecate the old version, 25.05 will stop getting regular updates at the end of December this year. Upgrading is so safe, and easy, there really isn’t any excuse to be back level.

You can run into some trouble if you have a very small boot drive, or haven’t done any “garbage collection” of older versions. I would recommend adding the following automatic updates and housekeeping tasks to your /etc/nixos/configuration/nix.

Depending on what has changed, you may get some warning when you do the update, typically stuff about a given setting having changed names or something. These are magically handled for you, but you should take the time to update your config to use the latest names to prevent future upgrade pain.

While we’re on the topic of NixOS configuration, I did learn something about the /etc/nixos/hardware-configuration.nix file. Typically this is set up once during the install, and you can mostly ignore it after that. However, you can re-generate that file using nixos-generate-config and it will update the file, but not overwrite your /etc/nixos/configuration.nix file. Handy if you have hardware changes like adding a USB drive you want to be permanently mounted.

However, as I found out, the nixos-generate-config command can be a “foot gun” and result in a non-clean booting system. The recommendation is to trust by verify, because capturing your hardware setup can be nuanced and you don’t want to end up having boot time problems you only detect much later.

Epson 1080UB: Farewell

The Epson 1080UB was my first “digital” projector, having had two CRT projectors previously. When I bought the 1080UB it had only just been released, initially shown at the September 2007 CEDIA expo and then re-announced at CES 2008. Unlike my CRT projectors which were bought used, this was a brand new unit and I was an early adopter. Quebec Acoustic had a great price: $2895 + GST – $200 mail in rebate.

The unit arrived in early January 2008. While it did take me a day to go from unboxing to a temporary setup, I was still thrilled by the purchase. Today there are so many high definition options out there, and viewing has become split between personal devices (phones, laptops) and larger displays (TVs) that there are many good choices at lots of different price points. Way back in 2008, cost, resolution, colour accuracy, fan noise, and ease of use were all dimensions you were trading off.

In the early days of owning the 1080UB I ran through a bunch of tweaks. First up was colour measurement, then colour calibration, and while there wasn’t any convergence I could change, I did go deep into deciding if mine was good enough or not. I also built a DIY ceiling mount and was able to take advantage of the long throw distance this projector supported – placing it above my 2nd row of seating and adding to the theater experience.

After many years of enjoyment, I replaced the OEM lamp with a generic one. I have no regrets doing this, as it got me a few more years enjoyment. I didn’t keep close track, but I believe that rarely pre-lamp swap the projector would turn off the lamp and run the fans in high mode. One consideration with these projectors is keeping them cool, and this means you have fans and airflow. You also want to avoid any dust getting inside the light path, but the light path is also what gets hot.

The manual covers air filter cleaning (or replacement). It seems Epson has long discontinued the replacement part – which is unfortunate. I did from time to time remove the filter and clean it (using a vacuum). Doing so did seem to help any shut-down (heat related?) problems, at least in the early days.

When it had problems, it was a simple enough matter to turn the projector off using the power switch on the back, wait 30 seconds and power it back on. We’d then resume watching for an hour or more afterwards. Again, cleaning the filter seemed to help reduce occurrences. I wonder if the filter just needs a deeper cleaning or replacement. The other high possibilities are a fan problem, or a temperature sensor.

Over time, the shut-downs became more frequent and the upgrade urge started to itch. Earlier this year I made the leap to a new (well, refurbished) upgrade and bought the Epson Pro Cinema 4050. Our theater is our primary viewing setup, so while I love to tinker with things – keeping the system easy to use and trouble free is important.

It was time to find this projector a new home. While it was having problems, it still has some good life in it and someone willing to tinker with it may get a lot of enjoyment from it. Off to Kijiji I went.

The used market for projectors is pretty weak, as I mentioned there are many great choices out there for new things – also many people don’t really care about quality and as long as it’s bright and big that’s good enough. I priced it 100x cheaper than it was new, it still took a week before someone was brave enough to take a risk on it.

The person who took it off my hands seemed like the right match. Someone wanting to try out big screen projection and doing so on a budget. I do hope this works well for them. When I set it up to check the bulb usage (1024hr) and reset it from ceiling mount to table mount, it powered up just fine – ran for a while without issues – and gave me a great image.

NixOS + Docker with MacVLAN (IPv4)

I continue to make use of the docker macvlan network support as it allows me to treat some of my containers as if they are virtual machines (VMs). Using this feature I can assign an IP address that is distinct from my host, but is still just a container running on the host. I’ve written about creating one, and expanding it.

As I’m now building out a new server and have selected NixOS as my base, I need to make some changes to how I’ve setup the docker macvlan. This blog post captures those changes.

While NixOS supports the declaration of containers, I’m not doing that right now by choice. It’ll make my migration easier and I can always go back and refactor. Thus there are just two things I need to include in my NixOS configuration:

  1. Enable docker support
  2. Modify the host network to route to the macvlan network

The first (enable docker support) is so very easy with NixOS. You need a single line added to your /etc/nixos/configuration.nix

You probably want to modify your user to be in the “docker” group allowing direct access to docker commands vs. needing to sudo each time.

There is a third thing we need to do, create the docker macvlan network. I don’t have this baked into my NixOS configuration because I was too lazy to write an idempotent version of doing it and figuring out where in the start up sequence to make it run. This turns out to be just a one line script:

Docker will persist this network configuration across reboots.

If you stop here, you will be able to create containers with their own IP address. I pass along these two docker command line options to create a container with it’s own IP:

The docker macvlan network I’ve defined has 4 IPs reserved, but you can specify a larger ip-range if you want when you create the docker mavlan network.

However, if you did stop here, you would not be able to reach the container running on 192.168.1.64 from the host. This is the second change to our Nix configuration (modify the host network to route to the macvlan network). In my original post I used a script to create the route from host to container, as this wasn’t persistent I needed to run that script after every boot.

One way to do a similar thing in NixOS is to create a systemd service. I was exploring this and did figure it out. However, I was wrong in my approach. While this worked, it wasn’t the best way to do it. NixOS has networking.macvlans which is a more NixOS-y way to solve the problem. The very helpful community helped me discover this.

If you dig into the implementation (createMacvlanDevice, configureAddrs), you can get some insight into how this maps onto basically the same thing my boot time script did.

This feels a lot less of a hack than using a script. Both work, but using the networking.macvlans approach is nice and clean. I should probably do the work to declare the docker macvlan inside my NixOS configuration to make this complete, but that’s a task for another day.