In-Place Upgrade Guide: Migrating a Debian 11 VPS to Debian 13

This document describes a practical, step-by-step procedure to upgrade a VPS from Debian 11 (bullseye) to Debian 13 (trixie) without reinstalling the system and while preserving existing data and configuration as much as possible.

Because Debian only supports sequential major upgrades, the officially supported path is:

  • Debian 11 → Debian 12 → Debian 13 and not directly 11 → 13.

The guide assumes:

  • You are running a VPS, accessed primarily via SSH.
  • You have root access (directly or via sudo).
  • You want to keep current services, data, and configurations intact, and are willing to perform post-upgrade validation.

⚠️ Strong recommendation: Always create a snapshot or full backup of the VPS before starting. A failed or partially completed upgrade is much easier to handle when you can roll back.


1. Upgrade Strategy Overview

The overall plan is:

  1. Baseline preparation on Debian 11

    • Fully update the existing Debian 11 system.
    • Clean unused packages.
    • Temporarily disable third-party APT repositories.
    • Ensure sufficient disk space and create backups/snapshots.
  2. Upgrade from Debian 11 → Debian 12 (bookworm)

    • Update APT sources from bullseye to bookworm.
    • Run apt upgrade and then apt full-upgrade.
    • Reboot into Debian 12 and verify essential services.
  3. Upgrade from Debian 12 → Debian 13 (trixie)

    • Fully update Debian 12 first.
    • Adjust APT sources from bookworm to trixie.
    • Run apt upgrade and apt full-upgrade.
    • Reboot into Debian 13 and perform thorough post-upgrade checks.
  4. Post-upgrade validation

    • Check systemd units, network, SSH, web services, and other daemons.
    • Review and merge configuration file changes.
    • Restore third-party repositories where appropriate.
    • Clean up obsolete packages.

2. Prerequisites and Safety Checklist

2.1 Confirm System Version and Architecture

Before you begin, confirm that you are indeed on Debian 11 and that your architecture is supported by Debian 13:

cat /etc/os-release
cat /etc/debian_version
dpkg --print-architecture
uname -a

Typical outputs:

  • /etc/os-release should mention bullseye or Debian GNU/Linux 11.
  • dpkg --print-architecture should return amd64 (64-bit x86).

❗ If the architecture is i386 (32-bit), Debian 13 does not provide full support for a pure 32-bit install. In that case, you should consider stopping at Debian 12 or performing a fresh install of a 64-bit system instead of upgrading to Debian 13.

2.2 Ensure Root Access and Out-of-Band Console

All commands in this guide assume root privileges. If you log in as a normal user:

sudo -i
# or
su -

Also, confirm that your VPS provider offers an out-of-band console (VNC, Serial Console, “Recovery” shell, etc.). This is critical in case the SSH daemon fails after an upgrade. It allows you to log in even if SSH is misconfigured.

2.3 Verify Disk Space

Run:

df -h

Ensure that the root filesystem (/) has at least 2–3 GB free space, preferably 5 GB+. If disk space is tight, clean up:

apt clean
apt autoremove

Remove large, obsolete files or logs if necessary.

2.4 Create Backups and/or Snapshots

The most robust protection is a VPS snapshot or full disk image via your hosting provider’s panel. Additionally, you may create local backups of key directories and databases.

Examples:

# Configuration backup
tar czf /root/etc-backup-$(date +%F).tar.gz /etc

# Example: web and home data (adjust paths to your environment)
tar czf /root/web-backup-$(date +%F).tar.gz /var/www /home 2>/dev/null

# Example: MySQL/MariaDB full database backup
mysqldump -uroot -p --all-databases | gzip > /root/all-db-$(date +%F).sql.gz

You may also copy these archives to another VPS or local machine using scp or rsync.

2.5 Use screen or tmux to Avoid SSH Dropouts

To minimize risk from SSH connection loss, run the upgrade inside a persistent terminal session:

apt update
apt install -y screen

screen
# Inside screen, proceed with all subsequent steps.

If the SSH connection drops, you can reconnect and attach the session with screen -r.


3. Preparation on Debian 11

3.1 Update and Clean the Current System

First, ensure that Debian 11 is fully updated to the latest point release:

apt update
apt full-upgrade
apt --purge autoremove
apt clean

Check if any packages are on “hold”, which might block upgrades:

apt-mark showhold

If you see held packages, review them. If possible, unhold them before performing a dist-upgrade:

apt-mark unhold PACKAGE_NAME

Only keep packages on hold if you fully understand the implications.

3.2 Review and Temporarily Disable Third-Party APT Repositories

List your APT sources:

cat /etc/apt/sources.list
ls /etc/apt/sources.list.d

For the duration of the OS upgrade, you should:

  • Keep only official Debian repositories (or trusted mirrors which mirror Debian).
  • Comment out or remove all third-party repositories (e.g., Docker, MariaDB, NodeSource, vendor-specific or cloud provider-specific repos).

To edit:

nano /etc/apt/sources.list
nano /etc/apt/sources.list.d/third-party.list   # example

Comment out non-Debian entries by adding # at the beginning of lines. You will re-enable or reconfigure these repositories after the distribution upgrade, once Debian 13 is running.


4. Upgrade from Debian 11 (bullseye) to Debian 12 (bookworm)

Debian officially supports upgrades from bullseye → bookworm. This is the first major step.

4.1 Backup APT Sources and Switch bullseye to bookworm

Backup your APT configuration:

cp /etc/apt/sources.list /etc/apt/sources.list.bak
cp -r /etc/apt/sources.list.d /etc/apt/sources.list.d.bak

Then replace bullseye with bookworm in all Debian APT entries:

sed -i 's/bullseye/bookworm/g' /etc/apt/sources.list
sed -i 's/bullseye/bookworm/g' /etc/apt/sources.list.d/*.list 2>/dev/null || true

Now edit /etc/apt/sources.list to ensure it uses the recommended components, including non-free-firmware introduced for newer firmware packages. A typical configuration looks like:

deb http://deb.debian.org/debian bookworm main contrib non-free non-free-firmware
deb http://deb.debian.org/debian-security bookworm-security main contrib non-free non-free-firmware
deb http://deb.debian.org/debian bookworm-updates main contrib non-free non-free-firmware

Adjust the mirror URL to match your preferred or local mirror.

4.2 Update Package Lists

Run:

apt update

If you encounter errors (404, GPG errors, missing components), correct your sources.list or temporarily comment out problematic entries and rerun apt update.

4.3 Run a Regular Upgrade

Perform a standard upgrade first:

apt upgrade

During this process, dpkg may prompt you about configuration files (e.g., /etc/ssh/sshd_config, /etc/nginx/nginx.conf):

  • For critical remote access components like SSH, it is usually safer to choose “keep the local version currently installed” to avoid accidentally locking yourself out.
  • For other services, you may decide case-by-case. If you are not sure, keeping the local version is generally safer. You can later compare with the new default config file (often saved as .dpkg-dist).

4.4 Run a Full Distribution Upgrade

Once apt upgrade finishes:

apt full-upgrade

This will install new kernel versions, upgrade major libraries, and potentially remove obsolete packages.

4.5 Reboot into Debian 12

Reboot the VPS:

reboot

Reconnect via SSH and confirm that you are now on Debian 12:

cat /etc/os-release
cat /etc/debian_version

At this point, verify that essential services (SSH, web server, database, VPN/proxy, etc.) are running and functioning as expected.


5. Upgrade from Debian 12 (bookworm) to Debian 13 (trixie)

Once you have a stable Debian 12 system, you can proceed to Debian 13. Again, this is done in place using APT.

5.1 Fully Update Debian 12

Before modifying sources, bring Debian 12 to its latest point release:

apt update
apt full-upgrade
apt --purge autoremove
apt clean

Verify your system:

cat /etc/os-release
cat /etc/debian_version

You should see bookworm and a 12.x version.

5.2 Backup APT Sources and Switch bookworm to trixie

Again, backup:

cp /etc/apt/sources.list /etc/apt/sources.list.bookworm.bak
cp -r /etc/apt/sources.list.d /etc/apt/sources.list.d.bookworm.bak

Then replace bookworm with trixie:

sed -i 's/bookworm/trixie/g' /etc/apt/sources.list
sed -i 's/bookworm/trixie/g' /etc/apt/sources.list.d/*.list 2>/dev/null || true

Edit /etc/apt/sources.list to ensure it is consistent and complete:

deb http://deb.debian.org/debian trixie main contrib non-free non-free-firmware
deb http://deb.debian.org/debian-security trixie-security main contrib non-free non-free-firmware
deb http://deb.debian.org/debian trixie-updates main contrib non-free non-free-firmware

If you previously added special repositories such as bookworm-backports, update them accordingly or comment them out until you confirm their availability for trixie.

5.3 Update Package Lists

Run:

apt update

Resolve any errors before proceeding. Check for:

  • Typographical errors in suite names (trixie, not trixy etc.).
  • Unsupported components for some mirrors.
  • Third-party entries that lack trixie support (temporarily comment them out).

5.4 Run a Regular Upgrade

Execute:

apt upgrade

As before, respond carefully to prompts about configuration files:

  • For SSH and core networking, prefer keeping the local version unless you know exactly what the new configuration changes.
  • For other services, it is acceptable to keep local configs and later compare with .dpkg-dist templates.

5.5 Run a Full Distribution Upgrade

Then perform the full upgrade:

apt full-upgrade

This step will:

  • Install the new Debian 13 kernel (e.g., a 6.12-series LTS kernel).
  • Replace or remove packages that are no longer supported.
  • Pull in updated versions of core libraries and tools.

5.6 Reboot into Debian 13

Reboot:

reboot

Then confirm the new OS version:

cat /etc/os-release
cat /etc/debian_version

You should now see Debian GNU/Linux 13 (trixie).


6. Post-Upgrade Validation and Recovery Steps

After you have booted into Debian 13, you should carefully validate the system’s health.

6.1 Check Systemd Units

Check if any services failed to start:

systemctl --failed

For each failed unit, inspect logs to identify the cause:

systemctl status SERVICE_NAME
journalctl -u SERVICE_NAME

Common issues include:

  • Configuration syntax no longer valid for the new version.
  • Missing modules, plugins, or libraries after the upgrade.
  • Third-party software incompatible with Debian 13.

6.2 Validate Critical Services

Step through the services you depend on most:

  • SSH (obviously, if you are connected, it is working, but check logs for errors or deprecations).

  • Web server(s):

    systemctl status nginx
    # or
    systemctl status apache2
  • Database server(s):

    systemctl status mysql
    systemctl status mariadb
    systemctl status postgresql
  • Proxy / VPN / tunnel / reverse proxy services (e.g., xray, caddy, etc.).

Check externally, if possible, that websites, APIs, and other exposed services are reachable and behave correctly.

6.3 Review Configuration File Changes

When dpkg asked about configuration files during the upgrades, and you chose to keep your local versions, it often saved the new default configs with suffixes like:

  • *.dpkg-dist
  • *.dpkg-new

For example:

  • /etc/ssh/sshd_config vs /etc/ssh/sshd_config.dpkg-dist
  • /etc/nginx/nginx.conf vs /etc/nginx/nginx.conf.dpkg-dist

You should compare and merge differences where appropriate:

diff -u /etc/ssh/sshd_config /etc/ssh/sshd_config.dpkg-dist
diff -u /etc/nginx/nginx.conf /etc/nginx/nginx.conf.dpkg-dist

In some cases, new defaults introduce important security options or syntax changes that you may wish to adopt.

6.4 Restore Third-Party Repositories (Carefully)

Once the base system is stable:

  1. Revisit /etc/apt/sources.list.d and re-enable third-party .list files one by one.

  2. After enabling each repository, run:

    apt update
  3. Observe whether the repository provides packages for trixie. If not:

    • Check the vendor’s documentation to see if they recommend using the bookworm repo on trixie for now, or
    • Consider switching to Debian’s own packages or an alternative.

Do not leave broken or partially working third-party repositories enabled; they can cause dependency problems in future upgrades.

6.5 Final Clean-Up

When everything appears to be functioning:

apt --purge autoremove
apt clean

Optionally, confirm your kernel version and general system status:

uname -r
systemctl list-unit-files --state=enabled,failed

7. Practical Notes on “Keeping System Contents Unchanged”

An in-place upgrade is designed to preserve data and configuration, but certain changes are unavoidable:

  • User data and application data (e.g., /home, /var/www, database data directories) are not removed by default. They should remain intact unless explicitly modified.

  • Configuration files are preserved by default if you choose “keep the local version currently installed” when prompted. However:

    • Some configuration syntaxes or defaults may change between major versions.
    • Services may fail to start until configs are adjusted.
  • Obsolete packages may be removed automatically during apt full-upgrade. If specific legacy packages are required, you may need to find alternatives or updated versions.

For this reason, the combination of:

  • A full snapshot/backup,
  • Use of screen/tmux,
  • Careful review of upgrade prompts,
  • And systematic post-upgrade testing

is essential to make the process as safe and reversible as possible.


8. Command Cheat Sheet

This condensed cheat sheet summarizes the main commands in order. Use it only as a quick reference; for explanations and context, refer to previous sections.

8.1 Debian 11 → 12

# 1. Preparation on Debian 11
sudo -i
apt update
apt full-upgrade
apt --purge autoremove
apt clean

# Disable third-party repos (edit /etc/apt/sources.list and /etc/apt/sources.list.d/*.list)

# 2. Switch bullseye → bookworm
cp /etc/apt/sources.list /etc/apt/sources.list.bak
cp -r /etc/apt/sources.list.d /etc/apt/sources.list.d.bak

sed -i 's/bullseye/bookworm/g' /etc/apt/sources.list
sed -i 's/bullseye/bookworm/g' /etc/apt/sources.list.d/*.list 2>/dev/null || true

# Ensure sources.list has bookworm main contrib non-free non-free-firmware

apt update
apt upgrade
apt full-upgrade
reboot

8.2 Debian 12 → 13

# 3. Preparation on Debian 12
sudo -i
apt update
apt full-upgrade
apt --purge autoremove
apt clean

# 4. Switch bookworm → trixie
cp /etc/apt/sources.list /etc/apt/sources.list.bookworm.bak
cp -r /etc/apt/sources.list.d /etc/apt/sources.list.d.bookworm.bak

sed -i 's/bookworm/trixie/g' /etc/apt/sources.list
sed -i 's/bookworm/trixie/g' /etc/apt/sources.list.d/*.list 2>/dev/null || true

# Ensure sources.list has trixie main contrib non-free non-free-firmware

apt update
apt upgrade
apt full-upgrade
reboot

8.3 Post-Upgrade Checks

# Confirm version
cat /etc/os-release
cat /etc/debian_version

# Check failed services
systemctl --failed

# Service diagnostics
systemctl status SERVICE_NAME
journalctl -u SERVICE_NAME

# Clean-up
apt --purge autoremove
apt clean

With these steps completed and verified, your VPS should now be running Debian 13 (trixie) with your original data and configurations preserved as much as realistically possible, and with a clear upgrade path for future maintenance.

Debian Upgrade Guide

Author

Shayne Wong

Publish Date

12 - 04 - 2025

License

Shayne Wong

Avatar
Shayne Wong

All time is no time when it is past.