Moving from Sury to nginx‑modules
The Sury nginx repo is gone. Ondřej closed the stable repo in April 2026 and that's that. The good news: migration is a single apt transaction. The small catch: Sury topped out at nginx 1.28 and we start at nginx 1.30, so nginx will upgrade and restart. Package names change (libnginx-mod-* becomes nginx-module-*) and include paths can differ, so read your config before you reload.
Read this first
Before you start
Check what Sury modules you have installed. Some we don't replace, and you need a plan for those before you pull the trigger.
$ dpkg -l | grep -E '^ii\s+libnginx-mod-' | awk '{print $2}'Modules we replace
These swap in automatically with apt upgrade:
libnginx-mod-http-brotli-filter→nginx-module-brotlilibnginx-mod-http-brotli-static→nginx-module-brotli-staticlibnginx-mod-http-geoip2→nginx-module-geoip2libnginx-mod-stream-geoip2→nginx-module-stream-geoip2libnginx-mod-http-headers-more-filter→nginx-module-headers-morelibnginx-mod-http-subs-filter→nginx-module-substitutionslibnginx-mod-http-cache-purge→nginx-module-cache-purgelibnginx-mod-http-fancyindex→nginx-module-fancyindexlibnginx-mod-http-dav-ext→nginx-module-dav-ext
Modules we don't replace
Still running any of these? Sort them out first or nginx won't start after the swap:
libnginx-mod-http-geoip: GeoIP v1. MaxMind killed that database in 2018. Move to nginx-module-geoip2 and a GeoLite2 database.libnginx-mod-http-lua/libnginx-mod-http-ndk: UseOpenResty. It's what you actually want anyway.libnginx-mod-http-echo: Just usereturn 200 "text";in your nginx config. You don't need a module for that.libnginx-mod-http-image-filter,perl,xslt: These come from the official nginx.org repository. Grab them there.libnginx-mod-http-uploadprogress,libnginx-mod-http-upstream-fair,libnginx-mod-http-auth-pam: Not available here. If you need one of these, open an issue on GitHub and bring a maintainer.
load_module directives for them first, or sort out replacements before switching.Back up your config
Optional, but do it anyway.
$ sudo tar czf /root/nginx-config-backup-$(date +%Y%m%d).tar.gz /etc/nginx/Run the migration
Removes Sury's nginx source, adds nginx.org and Blendbyte, upgrades everything in one shot.
If you also use Sury for PHP, only remove the nginx-specific source file. Don't touch the PHP one.
# Remove Sury's nginx source
# If you use Sury for PHP too, only remove the nginx-specific file
sudo rm -f /etc/apt/sources.list.d/sury-nginx.list
# Add nginx.org stable repo (replaces Sury's nginx binary)
curl https://nginx.org/keys/nginx_signing.key \
| gpg --dearmor \
| sudo tee /usr/share/keyrings/nginx-archive-keyring.gpg >/dev/null
DISTRO=$(. /etc/os-release && echo "$ID")
echo "deb [signed-by=/usr/share/keyrings/nginx-archive-keyring.gpg] \
http://nginx.org/packages/${DISTRO} $(lsb_release -cs) nginx" \
| sudo tee /etc/apt/sources.list.d/nginx.list
# Add Blendbyte
sudo install -d -m 0755 /etc/apt/keyrings
curl -fsSL https://apt.blendbyte.net/nginx/blendbyte-archive-keyring.gpg \
| sudo tee /etc/apt/keyrings/blendbyte.gpg >/dev/null
echo "deb [signed-by=/etc/apt/keyrings/blendbyte.gpg] https://apt.blendbyte.net/nginx $(lsb_release -cs) main" \
| sudo tee /etc/apt/sources.list.d/blendbyte.list
# Optional: pin to avoid conflicts with other module sources
cat <<EOF | sudo tee /etc/apt/preferences.d/blendbyte-nginx
Package: nginx-module-*
Pin: origin apt.blendbyte.net
Pin-Priority: 1001
EOF
# Run the upgrade (apt replaces Sury packages with ours in one transaction)
sudo apt update && sudo apt upgradeWant to see what apt will do before it does it? Run everything above except the last line, then simulate the upgrade. Nothing gets installed or removed:
$ sudo apt update && apt -s upgradeVerify everything's happy
$ sudo nginx -t && sudo systemctl reload nginx
$ sudo tail -20 /var/log/nginx/error.lognginx -t should say test is successful. Scan the error log for anything weird. If it's all clean, you're done. Go do something else.
Rolling back
There's no Sury repo to go back to, so rolling back really means getting your config working on nginx.org's nginx. If nginx -t fails, the error names the file and line. It's almost always a load_module line for a module we don't ship, or an include path that moved. Fix that line, test again, reload.
Lost track of what changed? Unpack the backup from step 2 next to the live config and diff the two. Swap in your backup's date:
$ sudo mkdir -p /root/nginx-old
$ sudo tar xzf /root/nginx-config-backup-YYYYMMDD.tar.gz -C /root/nginx-old
$ sudo diff -r /root/nginx-old/etc/nginx /etc/nginx