AIM
to transfer a running docker installation to another server (also running nextcloud in docker)
Support >
Appliances (Docker, Snappy, VM, NCP, AIO) documentation docker-compose
PRECONDITIONS
the two servers shall be running the same version of nextcloud. And with the same structure (here nextcloud, mysql, redis, apache…)
TESTED WITH
Installation 1 > Docker on Synology DSM migrated to
Installation 2 > Docker on Ubuntu Server running on proxmox
TESTED WITH
Nextcloud Hub 9 (30.0.6)
First generate a working installation of nextcloud on your Installation 2
Here is an example of a working docker compose file running under ubuntu server on a proxmox
First, create the required directories on your Installation 2
cd docker
mkdir nextcloud
cd nextcloud
mkdir config
mkdir custom_apps
mkdir data
mkdir db
mkdir html
mkdir redis
And now use this example of a docker compose (e.g. via portainer) to get the containers up and running. Setup a admin user (this will be overwritten, so just anything to have the setup completed)
---
version: '3'
services:
nextcloud:
image: nextcloud
container_name: nextcloud
restart: unless-stopped
networks:
- cloud
depends_on:
- mariadb
- redis
ports:
- 8081:80
volumes:
- /home/ubuntu/docker/nextcloud/html:/var/www/html
- /home/ubuntu/docker/nextcloud/custom_apps:/var/www/html/custom_apps
- /home/ubuntu/docker/nextcloud/config:/var/www/html/config
- /home/ubuntu/docker/nextcloud/data:/var/www/html/data
environment:
- PUID=1000
- PGID=1000
- TZ=Europe/Zurich
- MYSQL_DATABASE=nextcloud
- MYSQL_USER=nextcloud
- MYSQL_PASSWORD=XXXXXXXXX
- MYSQL_HOST=nextclouddb
- REDIS_HOST=redis
mariadb:
image: mariadb
container_name: Nextclouddb
restart: unless-stopped
command: --transaction-isolation=READ-COMMITTED --binlog-format=ROW
networks:
- cloud
volumes:
- /home/ubuntu/docker/nextcloud/db:/var/lib/mysql
environment:
- PUID=1000
- PGID=1000
- TZ=Europe/Zurich
- MYSQL_RANDOM_ROOT_PASSWORD=true
- MYSQL_PASSWORD=XXXXXXXXX
- MYSQL_DATABASE=nextcloud
- MYSQL_USER=nextcloud
redis:
image: redis:alpine
container_name: redis
volumes:
- /home/ubuntu/docker/nextcloud/redis:/data
networks:
- cloud
cron:
image: nextcloud:apache
container_name: Nextcloud-CRON
# logging:
# driver: none
restart: always
networks:
- cloud
volumes:
- /home/ubuntu/docker/nextcloud/config:/var/www/html/config:rw
- /home/ubuntu/docker/nextcloud/html:/var/www/html:rw
- /home/ubuntu/docker/nextcloud/custom_apps:/var/www/html/custom_apps:rw
- /home/ubuntu/docker/nextcloud/data:/var/www/html/data:rw
entrypoint: /cron.sh
depends_on:
mariadb:
condition: service_started
redis:
condition: service_started
networks:
cloud:
name: cloud
driver: bridge
Deploy docker and create a dummy admin user. Stop the nextcloud container after setting up the admin account since we will be overwriting the database.
In the meantime, create backups from Installation 1
Create dabase-backup in OLD installation using the mariadb-dump command in the console of the database docker. Stop the nextcloud container in Installation 1 so that the database will not be overwritten. The database container of Installation 1 is still running. Open a terminal in this container and create a dump of the existing database.
mariadb-dump --single-transaction -u nextcloud -pXXXXXXXXX nextcloud > nextcloud-sqlbkp_`date +"%Y%m%d"`.bak
Check that the .bak file is generated. This can be copied from the mountlocation “db”
The database being “done”, it is time to look at the actual user data stored in the folder “data”. From the Installation 1 download the user data as zip to your PC. In this case (Synology), go to DSM, navigate to the folder and download as zip to your PC
We are now done with Installation 1. Now starts the import and copy into the Installation 2 which is assumed to be up and running (see above)
Connect to Installation 2 Server via ssh and create a storage for old files
mkdir /home/ubuntu/old
From your PC, transfer the created backups to the Installation 2
Copy the backup and the data to the folder old
scp .\Downloads\data.zip ubuntu@192.168.1.64:/home/ubuntu/old/
scp .\Downloads\nextcloud-sqlbkp_20250215.bak ubuntu@192.168.1.64:/home/ubuntu/old
copy the backup into the docker database folder…we will use this file to overwrite the databse of Installation 2
sudo cp old/nextcloud-sqlbkp_20250215.bak docker/nextcloud/db/
…and correct the file ownership if needed (here changed from root to 999) as in the other files
sudo chown 999:systemd-journal nextcloud-sqlbkp_20250215.bak
Open terminal of database docker (nextclouddb) on the Installation 2
Enter the following commands at the command prompt inside the docker container Nextclouddb
# delete old database
mariadb -u nextcloud -pXXXXXXXXX -e "DROP DATABASE nextcloud"
mariadb -u nextcloud -pXXXXXXXXX -e "CREATE DATABASE nextcloud"
# import new database
cd /var/lib/mysql/
mariadb -u nextcloud -pXXXXXXXXX nextcloud < nextcloud-sqlbkp_20250215.bak
Now the database has been overwritten. The user files will be copied over. The data.zip should be already on your Installation 2 as outlined above.
Overwrite the contents of data.zip
Unzip, move and check permissions.
cd old
# unzip
sudo 7z x data.zip
# move / copy with rsync
sudo rsync -a data/ ../docker/nextcloud/data/
# change permissions of copied files to user www-data
sudo chown www-data:www-data data -R
Note permissions of the new installation
user www-data:www-data is owner of files except of db
On the INstallation 2 open config.php and enable update via web
'upgrade.disable-web' => true,
Now, very important - from outside docker (on ssh terminal ) execute occ upgrade as user www-data. NOTE this can not be executed from within the docker container nextcloud, it has to be external (i.e. from a terminal on the server) otherwise the users don’t match and the upgrade will not proceed.
docker exec --user www-data nextcloud php occ upgrade
Now you should be able to login to new server with all the user and data from the old server