Debian: upgrade from Wheezy to Jessie

Posted by cippaciong on Mon 27 July 2015

Hello, in what we may call the first technical post of this brand new blog, we'll outline a simple and hopefully exhaustive guide on how to upgrade our box from Debian Wheezy (7.8) to Jessie (8.1). While following this article you will probabily want to take a look also at the official documentation which is very precise and detailed. let's start!

Confucius say: BACKUP!

What is the best way to start a whole system upgrade? Of course a whole system backup! Take a couple of minutes to think about all the services that are running on the server just to make sure you won't forget anything important to backup (like databases). In my case I was upgrading a server I share with some university friends which serves:

  • an ownCloud instance (using a PostgreSQL database)
  • a Mumble server
  • various websites hosted with nginx and sometimes php-fpm.

A backup of the entire filesystem will probably save all the important data (I'm thinking about all config files as well as websites and ownCloud data) and only databases would be cut out, but we'll cover them in a while.

System Backup

Don't wait any longer and perform a full system backup right now with this simple bash one-liner:

# rsync -aAXv --exclude={"/dev/*","/proc/*","/sys/*","/tmp/*","/run/*","/mnt/*","/media/*","/lost+found"} /* /media/backup/system_backup

In this way we are saving the entire system in the system_backup folder located in an external device mounted at /media/backup/. Obviously we want to exclude from the backup the directories populated at boot, which are worthless saving, as well as /mnt and /media to avoid saving huge external file collections or generating backup loops by including in the backup source the backup destination itself.

Database Backup

Now that the entire system is safe and sound on our secondary hard drive, it's time to backup our databases as well. As I said just a few lines above, on the system we are going to upgrade, there is a running ownCloud instance which is using a PostgreSQL database. Taking a backup of a Postgres db is a trivial operation thanks to the handy tool pg_dump, which is included in PostrgreSQL and can be found in the postgresql-client-common package on Debian. Once again, one line is enough to backup the whole db, just run:

PGPASSWORD="MySuperSafePassword" pg_dump owncloud -h localhost -U owncloud -f /media/backup/owncloud-sqlbkp_`date +"%Y%m%d"`.bak

Let'see what this command does. First of all we set the environmental variable PGPASSWORD as our database password, this will be read automatically by pg_dump to access the database. then we provide the following informations:

  • owncloud: is the name of the database we want to backup.
  • -h localhost: is the host name of the machine on which the server is running.
  • -U owncloud: is the name of the database user.
  • -f /media/backup/owncloud-sqlbkp_`date +"%Y%m%d"`.bak: is the destination file where we want to save our backup, in this case we use the date command to append today's date to the file name.

If you don't feel like writing your db password in clear text, you can skip the PGPASSWORD part and add the -W flag instead, in this way you will be asked to enter the password manually. This is undoubtedly more secure but less efficient if your intent is to automate the backup process using a script.

Upgrade, Upgrade, Upgrade! (cit. Ballmer)

Now that all the server data is stored in a safe place, we can start the upgrade process without worries about losing anything important. Although this was my first dist-upgrade, I have to say that it went much smoother than expected, thanks to the work of Debian developers and the very detailed upgrade wiki which ensures you don't forget any important step.

Adjust your sources.list

The first thing to do in order to dist-upgrade our Debian box, is to adjust repositories definitions stored in /etc/apt/sources.list, as well as the external repository defined in separate list files located at/etc/apt/sources.list.d (if you have any). In my case I had this situation:

  • All the standard Debian repos where stored in sources.list along with the additional wheezy-backports.
  • /etc/apt/sources.list.d/ contained three additional list files:
    • owncloud.list used for, guess what? Yep, the ownCloud repository for Debian 7.
    • fish.list which was added the day I wanted to try fish shell and then forgot about it, time to nuke it.
    • debian-testing.list used to enable the testing repo when I wanted to try Docker and I needed a kernel newer than the oldish one installed by default. Again, we won't need this anymore.

Now that we have a clear view on all the enabled repositories, we can update them to their "Jessie" version. First of all I completely removed the two unused repositories (fish.list and debian-testing.list), gave a quick apt-get update and then updated /etc/default/grub in order to reboot in the old, standard Debian kernel. I also decided to disable wheezy-backports entirely instead of switch to jessie-backports so that I could freely decide weather I did want to use them or not after the upgrade (Yes, I did). Regarding the owncloud repository, I preferred not to update it and uninstalled all the related packages instead (all the data and database were safely backed up anyway). This may seem strange at first but the reason behind this choice is that in those days a new version was released (ownCloud 8.1, just like Jessie :D) and I wanted to upgrade it separately, in order to have more control over the process. This is what I did:

  1. Uninstall all ownCloud packages with this command # apt-get purge $(dpkg -l | grep owncloud | cut -d " " -f 3 | xargs )
  2. Update your /etc/apt/sources.list.d/owncloud.list but leave it commented #deb /
  3. apt-get update

This is how my /etc/apt/sources.list file looked like instead:


deb jessie main non-free contrib
deb-src jessie main non-free contrib

deb jessie/updates main contrib non-free
deb-src jessie/updates main contrib non-free

# jessie-updates, previously known as 'volatile'
deb jessie-updates main contrib non-free
deb-src jessie-updates main contrib non-free

# jessie-backports
# deb jessie-backports main contrib non-free
Stop services

It's almost time to begin the actual upgrade process but before doing so, make sure you stop as many services as possible. You can get a glimpse of the running processes and their status running either sudo service --status-all or sudo chkconfig. In the end I stopped nginx, php5-fpm and postgresql.

# service nginx stop
# service php5-fpm stop
# service postgresql stop
Minimal System Upgrade
  • Backup: ✓
    • Files: ✓
    • Databases: ✓
  • Sources list: ✓
  • Services stopped: ✓

Seems like we are good to go for the long-awaited upgrade, just a last time check. Run sudo apt-get -o APT::Get::Trivial-Only=true dist-upgrade and make sure you have enough disk space to perform the upgrade comparing its output with the output from a command like df -h.

Now that everything is settled we can start the upgrade and we'll begin with a minimal system upgrade as suggested in the official documentation. sudo apt-get update && sudo apt-get upgrade

During the process we'll be ask to replace some configuration files with their new version. What I did was to take a quick look at the differences and then decide what to do. In all cases I chose to substitute the old files with the new ones and to restore only the parts I modified directly using vimdiff once the upgrade was complete. Apart from this you shouldn't be ask to do anything else manually and the upgrade should proceed smoothly.

Full System Upgrade

Once the minimal system upgrade is completed, don't reboot the machine yet and start the full upgrade right away: # apt-get dist-upgrade

Also in this case you shouldn't have particular problems and the process will run as the minimal upgrade. In the remote case that bad things happen, Google is your friend.

Final steps

If you reached so fare, it means that now you have an up-to-date and shiny Debian Jessie on your server and you are almost ready to reboot into it. Let's just follow the last important steps and we are done.


As I said, during the upgrade some of your configuration files may be replaced with a newer version. In the end you will have two versions of such files, the new one and the old one saved as $filename.ufc-old. Now you can use vimdiff to compare both of them and restore the config fields with their older values. I preferred to adopt this strategy because the changes where mostly new blocks or updated comments and the field values were more or less untouched.

Update your PostgreSQL cluster

Upgrading the postgresql package isn't enough to use the new version (9.4), you first need to upgrade your postgres cluster. Debian provides some useful scripts to accomplish that without particular hassle. First of all you can have a glance at your clusters (and their state) running $ pg_lsclusters which should show something like this:

Ver Cluster Port Status Owner    Data directory               Log file
9.4 main    5432 online postgres /var/lib/postgresql/9.4/main /var/log/postgresql/postgresql-9.4-main.log

The output shows some informations about the cluster:

  • PostgreSQL version of the cluster, here 9.4.
  • The cluster name, by default is main.
  • The port where your cluster is listening on: 5432.
  • The name of the process owner: posgtres.
  • Data and Log directories for this specific version.

Here you can see that there is only an active cluster using Postgres 9.4, in your case you will probably have also the 9.1 cluster. You can now upgrade your cluster running # pg_updatedbclusters. This will stop the 9.1 cluster and start the new one. If you made any change to postgresql.conf or pg_hba.conf or any other file, make sure they are still present in the new files located at /etc/postgresql/9.4/main/ then restart the service with sudo service postgresql restart. Now take some time to test that everything is working as expected and that the upgrade didn't introduce any error, then you can delete the old cluster if you want, running pg_dropcluset 9.1 main (remember to restart the service again after that).

Install the new kernel

This is the very last step. Now that every package is updated we can upgrade the kernel too. Let's start checking that we don't have a kernel metapackage installed yet running this command # dpkg -l "linux-image*" | grep ^ii | grep -i meta which should return an empty output. Then we can look for the most suitable metapackage running this other command apt-cache search linux-image- | grep -i meta | grep -v transition whose output is:

linux-image-586 - Linux for older PCs (meta-package)
linux-image-686-pae - Linux for modern PCs (meta-package)
linux-image-686-pae-dbg - Debugging symbols for Linux 686-pae configuration (meta-package)
linux-image-amd64 - Linux for 64-bit PCs (meta-package)

In my case I was upgrading an old x86 server so I installed the second one # apt-get install linux-image-686-pae.

Keep Calm and Reboot (on)

You are done, for real this time. You can now cross your finger and reboot your server. If everything went as expected you will find your brand new Debian Jessie under your hands. In my case I was a bit unlucky and I had a problem with those infamous Wistron Buttons giving an anonymous wistron_btns: Unknown key code 10 error, forcing me to fallback on the older kernel. In the end I found out that the problem was the Wi-Fi button (the so-called server is actually and old acer laptop) and managed to let it boot again blacklisting the relative module adding blacklist wistron_btns to /etc/modprobe.d/wistron_btns-blacklist.conf.


Now that you have upgraded your server to Debian Jessie, celebrate the success with a frost beer (or anything else if you are not a beer lover (shame on you!)).

--end log report--