web dev & more!

Automating Manual Nextcloud Upgrades

Published: June 21, 2023

I know it’s been a long time since I’ve posted here but I have a good reason, I swear. I’ve been busy on another big project for the past several months that I hope to announce soon.

But until then, let’s talk about what a pain it has been for me to upgrade Nextcloud.

What is Nextcloud?

Nextcloud is an open source cloud solution. It allows users to sync files to a central location that can then be accessed from computers or mobile devices anywhere. Along with file sync functionality, it also provides a calendar, contacts, task management, and various other features like video chat that can be included through apps installed on the system. Think of it like a Google or Microsoft account but instead of being run on Big Tech’s Cloud©, it can be run on a computer in your home.

But why?

The advantages of running one’s own Nextcloud instance are plentiful. One reason is to have access to a nearly unlimited amount of storage data. The roughly 11TB of capacity at my disposal dwarfs the free tier limit of 15GB allotted from Google Drive. I could pay Google for more storage space but then I would always be beholden to their terms and conditions, which means I could be locked out of my account at any point and lose access to my data. With Nextcloud, I control my data.

homelab noun
hōmlab

A collection of computers used for learning about about system administration that typically pushes the operator to insanity or poverty.

Nothing is free

But it’s not all fun and games. For instance, having my own Nextcloud instance means that I have to operate and maintain the server that powers it. That means applying updates to the underlying server as well as the Nextcloud server software. And while Nextcloud itself is consistent and reliable, the included update process is not. For me, it frequently fails when performing updates via the provided administrative web interface. This may not be the case for others (I suspect it has something to do with my installation or configuration) but it so reliably fails me, that I’ve completely given up on using the web updater and instead prefer to upgrade the server software manually. This process is involved and time consuming. To get an idea of how to upgrade Nextcloud manually, see this list of steps I have to take each time I want to apply an update:

Nextcloud Manual Upgrade

  1. SSH into the server
  1. Navigate to Nextcloud directory:
    cd /var/www/
  1. Download next release:
    wget https://download.nextcloud.com/server/releases/latest.tar.bz2
  1. Unpack release to /var/www/nextcloud/:
    tar -xjf nextcloud...tar.bz2
  1. Stop web server:
    service nginx stop
  1. Disable background jobs by commenting out last line cron job:
    crontab -u www-data -e
  1. Backup old Nextcloud installation by moving it:
    mv /var/www/current-nextcloud-install/ /var/www/old-nextcloud-install/
  1. Move new release into current installation directory:
    mv /var/www/nextcloud/ /var/www/current-nextcloud-install/
  1. Copy old installation configuration:
    cp /var/www/old-nextcloud-install/config/config.php /var/www/current-nextcloud-install/config/config.php
  1. Copy old apps to new installation:
    cp -r /var/www/old-nextcloud-install/apps/ /var/www/current-nextcloud-install/ I’ve previously used this handy command to see which apps are in need of being installed:
    diff -q /var/www/old-nextcloud-install/apps/ /var/www/current-nextcloud-install/apps/ | grep "Only in"
  1. Fix ownership of the application:
    chown -R www-data:www-data /var/www/current-nextcloud-install/
  1. Fix directory permissions:
    find /var/www/current-nextcloud-install/ -type d -exec chmod 750 {} \;
  1. Fix file permissions:
    find /var/www/current-nextcloud-install/ -type f -exec chmod 640 {} \;
  1. Restart the web server:
    service nginx start
  1. Run Nextcloud upgrade script as www-data user:
    sudo -u www-data php /var/www/current-nextcloud-install/occ upgrade
  1. Re-enable background jobs in cron by uncommenting last line:
    crontab -u www-data -e

Whew! While none of these steps are particularly difficult on their own, they become a pain when combined. Especially since Nextcloud doesn’t support skipping versions. If your installation falls behind by a couple version, prepare to do this multiple times before you’re caught up 😩.

Automation to the Rescue

Over the years of operating my homelab, I’ve learned many things. The most important takeaway is that maintaining server infrastructure manually is a colossal waste of time. If you have to do something more than once, it should be automated.

XKCD comic about automation. At the top, it reads **I spend a lof of time on this task. I should write a program automating it!** followed by line graphs outlining theory and reality. Theory shows automation saving time while reality depicts the ongoing development and neverending struggle of maintaining the automation program.

https://xkcd.com/1319/

Because Nextcloud is updated so frequently, I decided to automate it all with Ansible! I’ve written about automation with Ansible before so if you’re unfamiliar, check out my other posts. I could always go back to trying to update Nextcloud via the web interface but at this point, I’ve lost all hope it will ever succeed. Instead, I’ve taken the manual upgrade steps and put them into an Ansible role. If you’re want thee. If you have to do something more than once, it should be automated. code, I’ve updated my Ansible Proxmox Automation repository on GitHub. That repository contains the full playbook (books/update-nextcloud.yml), which performs a backup of the container before beginning the upgrade; as well as the role (roles/nextcloud/tasks/main.yml) which runs through the manual upgrade steps. If you don’t like GitHub, I’ve provided a generalized role that achieves the same results as the manual upgrade steps below:

Note! The playbook that calls this role must include a vars_prompt to accept the URL for the archive to download. Otherwise, you’d have to change the playbook each time.

- name: Unpack remote release file to /var/www/nextcloud/
  unarchive:
    remote_src: true
    src: '{{ release }}'
    dest: /var/www/

- name: Stop webserver
  service:
   name: nginx
   state: stopped

- name: Remove cron
  cron:
    name: cloudcron
    user: www-data
    state: absent

- name: Move old install
  copy: 
    src: /var/www/current/
    dest: /var/www/old/
    remote_src: true
    follow: true

- name: Remove old install folder
  file:
    path: /var/www/current/
    state: absent

- name: Move new install
  copy:
    src: /var/www/nextcloud/
    dest: /var/www/current/
    remote_src: true

- name: Copy config from old install to new
  copy: 
    src: /var/www/old/config/config.php
    dest: /var/www/current/config/config.php
    remote_src: true

- name: Copy apps from old install to new
  copy:
    src: /var/www/old/apps/
    dest: /var/www/current/apps/
    remote_src: true

- name: Fix ownership
  file: 
    path: /var/www/current/
    owner: www-data
    group: www-data
    recurse: yes
    state: directory
    follow: false

- name: Fix directory permissions
  command: find /var/www/current/ -type d -exec chmod 750 {} ;

- name: Fix file permissions
  command: find /var/www/current/ -type f -exec chmod 640 {} ;

- name: Start webserver
  service:
    name: nginx
    state: started

- name: Run nextcloud upgrade CLI
  command: sudo -u www-data php /var/www/current/occ upgrade

- name: Add cron
  cron:
    name: cloudcron
    user: www-data
    job: 'php -f /var/www/current/cron.php'
    minute: '*/5'
    state: present

For all you other homelabbers out there, I hope this saves you some time so you can get back to tinkering and enjoy yourself instead of beating your head against the wall.

Some issues I’ve encountered

  • Symlinks - I used to symlink my data directory but apparently Nextcloud hasn’t allowed that since many versions before I was doing it. Its easy enough to get around this by specifying the data/ directory within the Nextcloud configuration file.

  • Broken installation after upgrade - I’ve had a few installations that are broken after upgrading where not even the occ command line interface will run. In my experience, this is due to apps being copied over. Removing the apps/ directory, copying in the fresh version from the archive, and continuing the upgrade has typically resolved this issue.

  • PHP - Newer versions of Nextcloud (26+)require newer versions of PHP (8.0+). This role does not account for that.