Migrate CentOS 7 to NixOS

Feb 25, 2023 tech post

I’ve been using NixOS as my workstation since 2020 and it works great for coding with modern VSCode, collaborating on Teams/Slack, and more. I started out using it with VMware on macOS and now I run it on my PC directly. I also have a micro CentOS 7 box on DigitalOcean that I created a few years ago. It handles static assets like images and videos for my website, and works together with Dropbox, Rclone, and Imgproxy. However, with the end-of-life date for CentOS 7 set for June 30, 2024, I decided to switch to NixOS.

The first step was to create a NixOS droplet on DigitalOcean. Since there was no existing image to use on DigitalOcean, I followed the steps in NixOS in the Cloud, Step-by-Step: Part 1 to build my own image.

Next, I had to rebuild the tasks/services on the new droplet. To my surprise, this process was much smoother than I expected. Here are the tasks/services I had on the old CentOS 7 server:

  • A cronjob with Rclone to sync Dropbox files
  • Nginx with Let’s Encrypt (using Certbot) to handle SSL and HTTP requests
  • Imgproxy running as a Docker container to optimize images on the fly


It was a cron file under /etc/cron.d/, I switched to using systemd-timer, which was recommended in the NixOS world.

For me it seems more clear to manage the cron task with systemd timer. To list the timers:

$ systemctl list-timers

To run the task manually:

$ systemctl start sync-blog-static

Nginx & Certbot

I used Let’s Encrypt to create and renew the SSL, then Nginx to handle the SSL requests and serve the assets. In CentOS I manged those by editing Nginx config or executing Certbot command manually. In NixOS, managing these was surprisingly smooth.

When I ran nixos-rebuild switch, Nix generated the Nginx config and created another systemd timer to automatically renew the SSL later.

Imgproxy container

I recently introduced Imgproxy to handle all image asset access. I deployed it with a simple Docker command before, but it was hard to track updates without other tools like Ansible. During the migration, I discovered that it was more popular to use Podman on NixOS, so I tried it and eventually switched to it.

All of these tasks were included in the new Nix configuration.nix, along with other tasks like SSH config and firewall management. I can now manage everything on my droplet in a declarative fashion.

Overall, I would say that NixOS works perfectly for desktop and personal services. However, it may still be too difficult to introduce to a team for production use as it can be hard to learn and find proper documentation.