My Raspberry pi deploy of Nextcloud was too slow for my taste. The SD card (while large) was slow and the spinning disk supplemental drive did not handle all of the functionality I was hoping for. As a solve, I set up an old computer with an always-on VM for my new Nextcloud server. The following instructions include the information goes along with my video on this subject.
Video iFrame
Common Issues And Introductory Comments
If you're migrating Nextcloud and are facing a vague "Internal Server Error", There are major causes for this:
- The database cannot connect - you will need your old Nextcloud DB admin credentials
- The Nextcloud version you are downloading is not exactly the same as your current instance so the software is incompatible
- There is a final possibility that your file permissions are incorrect
This document is a step-by-step guide to help avoid these pitfalls but there are A LOT of steps, so be careful!
As an additional word of warning I'm upgrading PHP and doing a manual NC upgrade, which is not normally recommended. These instructions might be of some use to people who are conducting a PHP upgrade. Most likely, the only person who will ever use them is small business IT personnel.
Covered in the Video
- VM config overview (not covered in blog entry)
- Quick security setup
- Packages and dependencies
- Web server setup (most of this is unique to me)
- Deploy fresh instance of Nextcloud
- Import your data
- Import your database
- Run manual Nextcloud Upgrade
- Test (not covered in blog entry)
Prerequisites
The video walks through VirtualBox setup instructions (for newbies & not covered here).
All instructions assume that you are using Ubuntu. Some of these instructions later in the document require PPA's:
- You will need to first put your current Nextcloud into Maintenance mode (
sudo -u www-data php occ maintenance:mode --on
)- Note: I need to run this from inside my Nextcloud directory but your mileage may vary
- Back up your database into a .sql files
mysqldump -u username -p databasename > filename-$(date +%F).sql
- Back up your
data
directory PRESERVE THE TIMESTAMPS either with rsync or tarball.- I used rsync
rsync -Aax /source-directory /destination-directory
- This did not work over local network for me due to missing permissions in the new Nextcloud directory so my "destination-directory" was a flash drive
- Tarball will not be covered in this document
- I used rsync
- Back up your Nextcloud config.php files
cp /source-directory/Nextcloud/config/config.php
<-- source-directory- I cannot stress enough how important this little file is. It is as important as your data and your database. DO NOT LOSE IT!
- Prepare your new server with Security updates
Your server should have at least 1 GB of RAM and a current modern single core (Ryzen or Intel / alternatively 4x ARM Cortex 7-series CPUs will serve as well).
Preparing Your Server - Easy
This section includes basic security setup. Most of this guide will not work with at least security patches installed but I will include steps for firewall setup below as well.
System Set-Up
Install Ubuntu and use a strong password with at least 12 characters from a random password generator. Normally I go much tougher because I do use a password manager that can generate these passwords (https://youtu.be/l0N-xzG53j0).
sudo apt update && sudo apt upgrade -y
I used a local machine from my network. You will not need to grab this IP address if you are using a VPS like Digital Ocean or Vultr
sudo apt install net-tools -y
ifconfig
Grab this IP address so you can SSH in from anywhere in your local network! Log in via SSH and we can move on to the next part.
System Log-In Security
UFW Firewall
Since I'm on local, I had some trouble with port 80 (another server is running on my network). I also needed to pick another port because my local ISP will not allow port 80 connections. For me this means:
sudo ufw allow 8080
The above will be port 80 for 99% of you, like the following:
sudo ufw allow 80
sudo ufw allow 443
sudo ufw allow 22
Important! If you miss your SSH port (22 in this case), you will lock yourself out of your server. It is generally recommended that you change your SSH port because 22 is common for brute-force attacks. I just use a 256 character long random password, and keep 22 open.
sudo ufw enable
sudo ufw status
Now you should see all correct ports listed as enabled by your firewall. All other connections will default to deny.
If you make a mistake and enable a port that should not be, you can always run ufw deny [insert-port-number]
Permissions Limitation
A common attack with those brute force hackers is to use root
as the default username. It is a good idea to disable direct log on as root:
sudo nano /etc/ssh/sshd_config
Change the line that says PermitRootLogin
to:
PermitRootLogin no
Exit the document and enter the command:
sudo service sshd restart
Install Required Packages
My Nextcloud install required PHP 8.0 because 8.2 was not supported by the Nextcloud team, yet. This meant that I needed to install via a PPA:
sudo add-apt-repository ppa:ondrej/php
The above will vary for you depending on when you find my guide and video.
Next you can install the webserver and database.
sudo apt update
sudo apt install apache2 mariadb-server libapache2-mod-php8.0 -y
sudo apt upgrade
Now that PHP, the web server (Apache2), and your database are installed you can gather additional required packages.
sudo apt install php8.0-gd php8.0-mysql php8.0-curl php8.0-mbstring php8.0-xml php8.0-zip php8.0-intl php8.0-bcmath php8.0-gmp php8.0-imagick -y
sudo apt-get install php8.0-apcu php8.0-fpm -y
Remember that the php versions listed above will depend on which PHP version you have installed and I am using 8.0. Also, sometimes these packages change to drop the version number, if you get an error with php8.x-[package]
try each package individual and drop the 8.x
part if one of them gives you an error.
Now we have a solid foundation of required packages to install Nextcloud!
Web Server Setup - EASY (but partially custom for my use-case)
This section is unique to my set-up because I can't use port 80 with my local ISP. I tenatively recommend that you skip my Apache2 instructions and seek an independent guide for this section for this reason. Additionally, I install my Nextcloud server into /var/www/html/nextcloud
which does seem to cause some problems. If you follow this guide nearly verbatim, be sure to follow the subsection regarding .htaccess below to prevent access control issues.
sudo nano /etc/apache2/ports.conf
In the above I changed port 80 to 8080. You should not need to do this.
sudo nano /etc/apache2/sites-available/000-default.conf
Set target directory to:
/var/www/html/nextcloud
I also changed port 80 to port 8080 under virtualhost in the above document because of my unique scenario.
Now you can restart Apache2:
sudo systemctl restart apache2
Now the Web Server is set up and configured for local ISP's without port 80 access.
Resolve .htaccess Error
The error will say something about .htaccess which is very critical because it controls who can see which files in Nextcloud. This will be an issue with my instructions because I direct my webserver to point to /var/www/html/nextcloud
rather than setting it to /var/www/nextcloud
.
To eliminate the .htaccess error, navigate to:
nano /etc/apache2/apache2.conf
Change AllowOverride None
to AllowOverride All
:
<Directory /var/www/>
Options Indexes FollowSymLinks
AllowOverride None
Require all granted
</Directory>
To:
AllowOverride All
Hopefully this part helps some random people on the internet. The error drove me up a wall.
Edit php.ini to Allow Proper Files (DO NOT SKIP)
NextCloud requires a couple tweaks to the php.ini
file to prevent errors and to make sure you can upload normal size user files. Edit the php.ini file:
sudo nano /etc/php/8.0/apache2/php.ini
Allow Nextcloud to use at least 512 MB of RAM by changing the following entry:
; Maximum amount of memory a script may consume
; http://php.net/memory-limit
memory_limit = 128M
To:
memory_limit = 1024M
Allow uploads greater than 2MB by changing the following entry:
; Maximum allowed size for uploaded files.
; http://php.net/upload-max-filesize
upload_max_filesize = 2M
To:
upload_max_filesize = 2G
Allow uploads of more than a handful of files at once by changing the following entry:
; Maximum number of files that can be uploaded via a single request
max_file_uploads = 20
To:
max_file_uploads = 120
This section should eliminate some of the errors you would normally see in a vanilla NextCloud setup.
Deploy Nextcloud - VERY EASY
Yes, this seems like a lot so far but the groundwork has been laid and now we just have to deploy Nextcloud before we can do the data and database migrations.
Navigate to:
cd /var/www/html
Now download and unpack the latest Nextcloud. At time of install, 23.0.0 was the latest available for me:
curl https://download.nextcloud.com/server/releases/nextcloud-23.0.0.tar.bz2 | sudo tar -jxv
Again, the above will vary for you depending on when you find my guide and video. At time of blog publication we are on version 23.0.3.
Migrate in Nextcloud Data and Config Files - HARD
This is considered the hard part because there are a ton of very detail-oriented steps that can trip users up. Even I got tripped up in my own video. Unlike the previous sections, the little steps aren't really standard web-server instructions. There are a few steps in here that are unnecessary, but I left them in because
- They are in the video so users can follow along
- They help me stay focused on where I am in the setup process
For my migration I had the config.php file, data directory information, and database on a USB thumb drive. You can also use tarball for this process and migrate over the network if your Nextcloud drive has enough space.
Create Data Folder with Correct Permissions
Now we can begin migrating the data into Nextcloud. First we need a directory to add our files to:
sudo mkdir -p /var/www/html/nextcloud/data
Set www-data as data folder owner:
sudo chown -R www-data:www-data /var/www/html/nextcloud/
The NextCloud folder still has improper permissions, so now we can correct this by navigating outside of the Nextcloud directory:
cd /var/www/html/
And setting appropriate read/write permissions for the entire directory:
find nextcloud/ -type d -exec chmod 750 {} \;
find nextcloud/ -type f -exec chmod 640 {} \;
Make the Old data Directory Available to the New System
This instance shows how to do this with a USB drive. You can follow suit by connecting it to the system and creating a mount directory (the following path is optional but should work on a fresh Ubuntu instance):
sudo mkdir /media/usb
Then mounting the drive to that folder (sdb1
) was my case but this will vary for you):
sudo mount -t ext4 /dev/[sdb1] /media/usb
Migrate Important Files
Migrate Config File
Your old Nextcloud config.php file is critical to get the new system running like the old. It has important information like the keys to your database in it, from the flash drive, migrate it into the ../nextcloud/config
folder:
cp /media/usb/[your-path]/config/config.php /var/www/html/nextcloud/config/
Update the file permissions of the config.php document:
sudo chown -R www-data:www-data /var/www/html/nextcloud/config/config.php
Now we need to allow connections from our desired domains by editing the array in the trusted domains
section in the config.php
file:
nano /var/www/html/nextcloud/config/config.php
Just set the domain how you want it. This can also be a URL from a domain you have purchased. In the video I allowed connections from my URL and from my local network since it is running from my home at 192.168.1.27:8080
which will not work for you. This just illustrates that you can permit connections from multiple domain entries.
Migrate Data Folder Files
Your entire old data folder needs to be moved over. The files alone are not sufficient. You will need to preserve your timestamps and can use tarball if you wish. The following rsync command preserved my timestamps but there may be another command that guarantees to preserve this information:
rsync -Aax /media/usb/[your-path]/data/* /var/www/html/nextcloud/data
This will take a while to complete. For the video I broke the next section into a "part 2" but will leave it in the appropriate section here. Once the transfer is complete, you need to give www-data user permissions to access the files. Run the following commands based on the paths I used during setup above:
cd /var/www/html/
find nextcloud/ -type d -exec chmod 750 {} \;
find nextcloud/ -type f -exec chmod 640 {} \;
Import Old Database
It's best to log in as root to do a database import. For the instructions here I am using example usernames and example passwords. Users that are doing a migration MUST know their usernames and passwords. If you do not know these automatically, they are published in plain text in the config.php
file in the Nextcloud you are migrating (the file I said was super important at the beginning of this post):
- Database user is
dbuser
- Database name is
dbname
- Database password is
dbpassword
Hopefully this illustrates the importance of the config.php
file for a Nextcloud migration. This little file contains all of the most critical information.
Now promote yourself to superuser to make this easier:
sudo su
The following step is unnecessary but I like having my database in my database folder. The intermediate step is useful because most Linux users don't always have complete file paths memorized such as /etc/mysql/db-import-file
; instead, we typically navigate and call db-import-file
from the local directory:
cp /media/usb/[path]/ncdb64-dump.sql /etc/mysql/
Now log into the database
mysql -u root -p
If you have another database with the same name as what you are importing, drop it (this will delete the old database):
DROP DATABASE Nextcloud;
Create the new database that matches the old database name:
CREATE DATABASE Nextcloud;
The following are example commands to create a user that matches your old database user:
CREATE USER 'nc-admin'@'localhost' IDENTIFIED BY 'PASSWORD';
Grant the new database user all permissions:
GRANT ALL PRIVILEGES ON **.** TO 'nc-admin'@'localhost' WITH GRANT OPTION;
Now:
FLUSH PRIVILEGES;
EXIT
The database is now created and you can import your old database:
mysql -h localhost -u root -p Nextcloud < /etc/mysql/ncdb64-dump.sql
The hard part is now over so we can recap briefly what this major section does.
How The Migration Fits Together
It may be difficult to understand what we have done in this "Migrate in Nextcloud Data and Config Files" section so this is a quick recap:
- We created and prepared the
data
directory within thenextcloud
superdirectory - We migrated the config.php file - This file allows the Nextcloud software (scripts in the
/var/www/html/nextcloud/
directory and it's subdirectories) to access the database - We migrated the old
data
directory over - There are files in here that the database needs AND any missing files will cause errors in Nextcloud since the database will not be able to find them - We migrated and imported the database - This allows the web front-end to find your files. Every file in nextcloud needs to be accounted for within the database
These are all of the core components to get a functional Nextcloud system. Unfortunately they will not talk to each other yet because the system scripts are different versions from the database and data
directory files.
The web upgrade system will not work to get them onto the same version but the manual update does synchronize the system files.
Finalization - Upgrade Nextcloud (Easy)
Note before you read this section, php8.0
is likely out of date at your time of installation. When you are running your OCC
commands, be sure to use whichever PHP version is installed on your system.
Now that everything is in its place we need to call on the Nextcloud update script. This will get all of our software synced up and ready to go. To do this, navigate to:
cd /var/www/html/nextcloud/
Now, call occ
as the www-data
user. I could not get this to run with the full path, I had to be in the Nextcloud folder to get it to run:
sudo -u www-data php8.0 --define apc.enable_cli=1 occ upgrade
Now we can turn maintenance mode off by navigating into the following file and setting maintenance
from true
to false
:
nano /var/www/html/nextcloud/config/config.php
Alternatively you can toggle maintenance mode off with the following command:
sudo -u www-data php8.0 /var/www/html/nextcloud/occ maintenance:mode --off
Now everything should be running just fine. For good measure you can restart your webserver by running the following command:
systemctl restart apache2
And your system should be ready for testing!
Final Thoughts
Migrating a Nextcloud instance was an extremely in-depth project to tackle. It serves as a reminder that Open Source projects meet their financial targets off consulting instead of licenses. A 2 hour consult during this setup likely would have saved me 20 hours of time.
I do want to thank the Nextcloud team and their contributors on the Nextcloud forums. They provided the hint that you can perform a manual upgrade once all of your files, config, and database files have been migrated. Without that tidbit, I likely never would have completed the migration.
No regerts. This process helped me to better understand Nextcloud which makes me far less concerned about future migrations.