Migrating a Nextcloud Instace to a New Server

Initial Notes

Starting here: https://docs.nextcloud.com/server/latest/admin_manual/maintenance/migrating.html?highl

Basically we'll setup the new server according to the install guide, and turn on maintenance mode of the old server in order to dump the db and filesystem and transfer them to the new server.

As of the time of writing this, Nextcloud stable is at version 19, and the new server being setup is a fresh Debian 10 (buster) install.

Preparing New Server

PHP Setup and PHP Modules


  • PHP (7.2, 7.3 or 7.4)
  • PHP module ctype
  • PHP module curl
  • PHP module dom
  • PHP module GD
  • PHP module hash (only on FreeBSD)
  • PHP module iconv
  • PHP module JSON
  • PHP module libxml (Linux package libxml2 must be >=2.7.0)
  • PHP module mbstring
  • PHP module openssl
  • PHP module posix
  • PHP module session
  • PHP module SimpleXML
  • PHP module XMLReader
  • PHP module XMLWriter
  • PHP module zip
  • PHP module zlib


  • PHP module fileinfo
  • PHP module bz2
  • PHP module intl
  • PHP module exif
  • PHP module imagick
  • PHP module pcntl
  • ffmpeg

php-common on Debian 10 pulls in many of these like php-ctype, php-xml, php-mbstring, php-fileinfo, php-exif, php-pcntl , etc. We'll also need to choose a DB module; in this case we'll be using MariaDB so the mysql driver is needed.

This is what I ended up needing to install:

php-gd \
php-json \
php-bz2 \
php-imagick \
php-bcmath \
ffmpeg \

Memory Cache

The old server is using redis so we'll stay with that.

sudo apt install redis-server php-redis

Installing and configuring redis is outside of the scope of this post; but this Digital Ocean guide is easy to run through. TLDR: make sure to set a password with the requirepass config directive, ensure remote access is turned off (if you're running it on the same server as the Nextcloud instance, and make systemd watch the process.

WARNING overcommit_memory is set to 0! Background save may fail under low memory condition. To fix this issue add 'vm.overcommit_memory = 1' to /etc/sysctl.conf and then reboot or run the command 'sysctl vm.overcommit_memory=1' for this to take effect.

echo 'vm.overcommit_memory = 1' >> /etc/sysctl.conf
sysctl vm.overcommit_memory=1

WARNING you have Transparent Huge Pages (THP) support enabled in your kernel. This will create latency and memory usage issues with Redis. To fix this issue run the command 'echo never > /sys/kernel/mm/transparent_hugepage/enabled' as root, and add it to your /etc/rc.local in order to retain the setting after a reboot. Redis must be restarted after THP is disabled.

echo "never" > /sys/kernel/mm/transparent_hugepage/enabled

WARNING: The TCP backlog setting of 511 cannot be enforced because /proc/sys/net/core/somaxconn is set to the lower value of 128.

The Nextcloud install guide recommends redis for everyhing but local cache:

'memcache.local' => '\OC\Memcache\APCu',
'memcache.distributed' => '\OC\Memcache\Redis',
'memcache.locking' => '\OC\Memcache\Redis',

but I was getting an error message in nextcloud.log about APCu not working:

nextcloud Memcache \\OC\\Memcache\\APCu not available for local cache

so ended up just sticking with redis for everything.

The redis setup with systemd on a fresh Debian 10 server was a mess and took some fiddling. Here are the relevant portions of configs having to do with redis, nextcloud config, and systemd service file:

Nextcloud config.php:
  'memcache.local' => '\OC\Memcache\Redis',
  'memcache.distributed' => '\OC\Memcache\Redis',
  'memcache.locking' => '\OC\Memcache\Redis',
  'redis' => [
    'host'     => '/var/run/redis/redis-server.sock',
    'dbindex'  => 0,
    'password' => 'kG34qzSTk6M3Wm1Dg6ZRw58oZMOBnxD6FrHi6qvV0aAgT1P2J3qB',
    'timeout'  => 1.5,
Redis conf file /etc/redis/redis.conf:
port 0
unixsocket /var/run/redis/redis-server.sock
unixsocketperm 770
daemonize yes
supervised systemd
pidfile /var/run/redis/redis-server.pid
Systemd redis Config File
ExecStart=/usr/bin/redis-server /etc/redis/redis.conf
ExecStop=/bin/kill -s TERM $MAINPID
ExecStartPost=/bin/sleep 1
#ExecStartPost=/bin/sh -c "echo $MAINPID > /var/run/redis/redis-server.pid"

Apache Setup

Hopefully we can just copy the config from the old server, but there are specific instructions in the install guide: https://docs.nextcloud.com/server/stable/admin_manual/installation/source_installation.html#apache-web-server-configuration

Apache Mods


  • rewrite
  • env
  • dir
  • mime


  • ssl

sudo a2enmod rewrite headers env dir mime ssl

Get Data from Old Server

Now that the new server is ready and setup to run Nextcloud, return to the old server and turn on maintenance mode:

In the web root of the old Nextcloud install run:

sudo -u www-data php occ maintenance:mode --on

Not sure if required, but after 10 minutes I also used a2dissite to temporarily disable the entire Nextcloud site while taking the DB and filesystem backups in the next step.