Manuellement exporter/importer des données d'un Nextcloud à l'autre
Suite à une question sur le forum CHATONS, j'ai écrit cette petite description de mon expérience.
Use case : On a deux instances de Nextcloud qui tournent :
old
, dont on veut se débarassernew
, qui va accueillir les utilisateurices d'old. Dans mon cas,new
était vide.
J'avais plusieurs types de données à migrer :
- Les fichiers des utilisateurices. Facile, Nextcloud propose des outils faits pour manipuler directement les fichiers.
- Les données de leurs apps. Les apps en question, sur mon instance, étaient Calendar, Cospend et Deck.
Ce "tuto" n'est pas forcément la meilleure marche à suivre, mais elle a fonctionné pour moi. Restez prudent·es si vous le suivez, faites des backups et vérifiez tout bien !
Avant toute opération casse-gueule, on fait des backups !
1. Récréer les users🔗
Dans l'interface admin de new
, j'ai recréé les utilisateurices à la main. Deux personnes en ont profité pour changer de login, ce qui a son importance dans la suite.
2. Transférer les fichiers🔗
Copie🔗
Le dossier data
de Nextcloud a cette arborescence :
<root_dir>/data/
<root_dir>/data/<user1>/
<root_dir>/data/<user1>/cache/
<root_dir>/data/<user1>/files/
<root_dir>/data/<user1>/files_trashbin/
<root_dir>/data/<user1>/files/_versions/
<root_dir>/data/<user2>/
<root_dir>/data/<user2>/...
...
Dans mon cas, je ne voulais garder que les fichiers actuels, pas les vieilles versions ni la pouvelle. Je n'ai donc copié que les files/
.
Mes deux instances de Nextcloud étaient sur la même machine, j'ai donc fait une série de :
$ rsync -a <old_dir>/data/<old_username>/files/ <new_dir>/data/<new_username>/files/
…copiant ainsi le contenu du premier dossier dans le deuxième (rsync
a ce comportement si on laisse le /
à la fin du premier dossier, ce qui est déroutant mais pratique).
Pensez à bien donner les fichiers au user php de new
, par exemple :
$ chown -R nextcloud <new>/data
Mise à jour dans new
🔗
Pour demander à Nextcloud de rescanner les dossiers à la recherche de nouveaux fichiers, il faut utiliser son utilitaire occ
:
# Générique, avec le user utilisé par nextcloud
$ occ files:scan --all
# Docker
$ sudo docker exec <image_name> occ files:scan --all
# NixOS
$ sudo nextcloud-occ files:scan --all
On peut déjà vérifier à cette étape dans l'interface web que les fichiers ont bien été reconnus.
3. Inclure les données des applications🔗
Il arrive que des applications stockent des fichiers dans les dossiers des users, auquel cas tout est normalement pris en charge, car on vient de les copier, et qu'en base de données, c'est leur chemin relatif qui est stocké. Il n'a pas changé normalement.
Export SQL🔗
On va d'abord exporter les données d'old
. Dans mon cas, l'ancienne instance était une instance Docker, avec PostgreSQL, j'ai donc utilisé cette commande :
$ docker exec -it <nextcloud_db> pgdumpall -U nextcloud > ~/dump.nextcloud.sql
Laïus COPY
vs INSERT
🔗
Par défaut, PostgreSQL utilise la commande COPY
pour ses exports, spécifique à cette base de données.
Elle est plus rapide, mais ne met pas à jour les SEQUENCE
S, ces compteurs qui "retiennent" à quel id on en est pour chaque PRIMARY KEY AUTOINCREMENT
, ce qui demande de les mettre ensuite à jour automatiquement
C'est sûrement une bien meilleure idée que d'utiliser l'option --inserts
, qui exporte les données avec des commandes INSERT
.
Je n'ai pas testé, mais je recommande fortement de commencer par essayer avec cette option.
Sinon, il faut se préparer à faire des ALTER SEQUENCE <seq_name> RESTART with <new_start>
, où <seq_name>
est le nom de la table associée avec le suffixe _seq
, et où <new_start>
est l'id maximal de la table + 1.
Galère les COPY
, quoi.
On préfèrera donc
$ docker exec -it <nextcloud_db> pgdumpall --inserts -U nextcloud > ~/dump.nextcloud.sql
Sous laïus🔗
Attention par contre, INSERT
pourrait vous poser d'autres problèmes :
je pense qu'il va refuser l'insertion d'une ligne qui fait référence à une ligne d'une autre table qui n'existe pas encore. Pour chaque app, il faudra commencer par insérer les données de tables qui ne référencent pas les autres tables.
Exemple : oc_calendarobjects_props
contient une colonne objectid
et une colonne calendarid
, elle doit donc être remplie après les tables oc_calendarobjects
et oc_calendars
.
Normalement, l'export SQL doit insérer les données dans le bon ordre. Je pense que si vous préservez l'ordre des insertions, tout ira pour le mieux 😇
Sélection des données de l'export🔗
Les tables SQL relatives à un module sont préfixées du nom du module :
Calendar :
oc_calendar_appt_bookings → vide chez moi
oc_calendar_appt_configs → vide chez moi
oc_calendar_invitations
oc_calendar_reminders
oc_calendar_resources
oc_calendar_resources_md
oc_calendar_rooms → vide chez moi
oc_calendar_rooms_md → vide chez moi
oc_calendarchanges
oc_calendarobjects
oc_calendarobjects_props
oc_calendars
oc_calendarsubscriptions → vide chez moi
Cospend :
oc_cospend_bill_owers
oc_cospend_bills
oc_cospend_categories
oc_cospend_currencies
oc_cospend_members
oc_cospend_paymentmodes
oc_cospend_projects
oc_cospend_shares
Deck :
oc_deck_assigned_labels
oc_deck_assigned_users
oc_deck_attachment
oc_deck_board_acl
oc_deck_boards
oc_deck_cards
oc_deck_labels
oc_deck_stacks
Ce n'est que ces tables que j'ai gérées. Selon les applications que vous voulez transférer, à vous de chercher les tables associées.
De l'export SQL, on ne gardera que les INSERT
des tables sélectionnées, tout le reste
(CREATE
, ALTER
, etc) est à mettre à la poubelle.
Votre new
s'est déjà occupé de tout ça.
(optionnel) Renommage des users dans l'export🔗
Dans mon cas, des personnes en avaient profité pour changer leur username. Dans Nextcloud, c'est le username qui sert d'id aux users. C'est donc ce username qui est présent dans toutes les clés étrangères.
Dans ce cas, il faut donc chercher toutes les clés étrangères qui référencent la table oc_users
et renommer toute instance de <old_username>
par <new_username>
Préparation tables de destination🔗
Je vous ne le souhaite vraiment pas, mais peut-être que votre new
a déjà des données à ne pas supprimer dans toutes ces tables.
Si ce n'est pas le cas, pensez à bien vider les tables de destination.
(optionnel) Changement des ids🔗
Avant toute opération casse-gueule, on fait des backups !
Si c'est le cas, vous allez très sûrement avoir des conflits d'ids (qui doivent être uniques) entre les vieilles et les nouvelles données. Dans ce cas, une solution (très casse-gueule, mais je ne crois pas qu'il y ait le choix) est d'incrémenter manuellement tous les ids dans l'export. C'est casse-gueule car il faudra aussi incrémenter ces mêmes ids dans toutes les tables qui y font référence.
Exemple :
Si les ids d'oc_calendarobjects
ont été incrémentés de 300, il va falloir incrémenter toutes les références à ces ids dans la colonne objectid
des tables associées (oc_calendarobjects_props
, oc_calendar_reminders
, et j'en oublie peut-être)
Import du SQL dans new
🔗
Dans la base de données PostgreSQL de new
, on va importer les données de notre export SQL modifié comme décrit précédemment.
# Générique
$ sudo -u nextcloud psql nextcloud -f file.sql
Vérifier que tout va bien🔗
Vérifiez que vous pouvez visualiser les données, en créer de nouvelles (créez une liste Deck, un agenda, un évènement, une carte dans une liste Deck, une entrée dans Cospend, etc.)
Et ça devrait être bon (j'espère !)