Dans le précédent billet, nous avons créé un service « mysql », ainsi qu’une base de données pour notre site web.
Maintenant, nous allons utiliser ce service pour importer une base de données que nous aurons préalablement « dumpée » (comprendre exportée), depuis un autre serveur avec une autre instance mysql.
Pour cela, nous devons nous connecter au serveur déjà existant, récupérer notre base de données, puis l’importer dans notre instance mysql sous docker.
Si nous avons bien lu notre docker-compose, nous savons qu’en dehors de docker, (et sur une machine linux) les bases de données sont stockées dans /var/lib/mysql/ suivi du nom de notre base de données.
Si nous sommes curieux, nous regardons les fichiers qui composent notre base…
user@Serveur:~$ sudo ls -alH /var/lib/mysql/personal/
total 10936
drwxr-x--- 2 systemd-coredump systemd-coredump 4096 janv. 5 10:58 .
drwxr-xr-x 6 systemd-coredump docker 4096 janv. 5 10:54 ..
-rw-r----- 1 systemd-coredump systemd-coredump 65 janv. 5 10:54 db.opt
-rw-r----- 1 systemd-coredump systemd-coredump 8688 janv. 5 10:58 wp_commentmeta.frm
-rw-r----- 1 systemd-coredump systemd-coredump 131072 janv. 5 12:28 wp_commentmeta.ibd
-rw-r----- 1 systemd-coredump systemd-coredump 13380 janv. 5 10:58 wp_comments.frm
-rw-r----- 1 systemd-coredump systemd-coredump 180224 janv. 5 12:28 wp_comments.ibd
-rw-r----- 1 systemd-coredump systemd-coredump 13176 janv. 5 10:58 wp_links.frm
-rw-r----- 1 systemd-coredump systemd-coredump 114688 janv. 5 10:58 wp_links.ibd
-rw-r----- 1 systemd-coredump systemd-coredump 8698 janv. 5 10:58 wp_options.frm
-rw-r----- 1 systemd-coredump systemd-coredump 9437184 janv. 5 12:29 wp_options.ibd
-rw-r----- 1 systemd-coredump systemd-coredump 8682 janv. 5 10:58 wp_postmeta.frm
-rw-r----- 1 systemd-coredump systemd-coredump 131072 janv. 5 12:42 wp_postmeta.ibd
-rw-r----- 1 systemd-coredump systemd-coredump 13684 janv. 5 10:58 wp_posts.frm
-rw-r----- 1 systemd-coredump systemd-coredump 212992 janv. 5 12:42 wp_posts.ibd
-rw-r----- 1 systemd-coredump systemd-coredump 8682 janv. 5 10:58 wp_termmeta.frm
-rw-r----- 1 systemd-coredump systemd-coredump 131072 janv. 5 10:58 wp_termmeta.ibd
-rw-r----- 1 systemd-coredump systemd-coredump 8666 janv. 5 10:58 wp_term_relationships.frm
-rw-r----- 1 systemd-coredump systemd-coredump 114688 janv. 5 12:39 wp_term_relationships.ibd
-rw-r----- 1 systemd-coredump systemd-coredump 8668 janv. 5 10:58 wp_terms.frm
-rw-r----- 1 systemd-coredump systemd-coredump 131072 janv. 5 12:29 wp_terms.ibd
-rw-r----- 1 systemd-coredump systemd-coredump 8768 janv. 5 10:58 wp_term_taxonomy.frm
-rw-r----- 1 systemd-coredump systemd-coredump 131072 janv. 5 12:42 wp_term_taxonomy.ibd
-rw-r----- 1 systemd-coredump systemd-coredump 8684 janv. 5 10:58 wp_usermeta.frm
-rw-r----- 1 systemd-coredump systemd-coredump 131072 janv. 5 12:27 wp_usermeta.ibd
-rw-r----- 1 systemd-coredump systemd-coredump 13064 janv. 5 10:58 wp_users.frm
-rw-r----- 1 systemd-coredump systemd-coredump 147456 janv. 5 10:58 wp_users.ibd
Nous sommes loin du fichier db.sql a quoi nous nous attendions.
Bien qu’il soit en théorie possible de récupérer ce dossier et le copier tel quel dans notre nouveau répertoire, ce n’est pas propre, nous risquerions avoir des problèmes de configurations…
A la place, il est recommandé d’exporter la base en fichier SQL, puis l’importer.
Export de base de données
Pour cela, sur notre ancien serveur, nous allons utiliser l’outil mysqldump:
user@serveur:~$ mysqldump --user=mon_user --password=mon_password --databases nom_de_la_base > fichier_destination.sql
Ou dans notre cas:
user@serveur:~$ mysqldump --user=user --password=resuperpass --databases personal > personal.sql
Après quelques instants, dépendant de la taille de votre base de données, vous vous retrouverez avec un export complet, nommé personal.sql
Export de base de données
Ok, première étape remplie. Il reste maintenant à importer cette base. Nous allons la copier dans le répertoire « databases » de notre serveur docker, puis nous allons lancer une commande à l’intérieur de celui-ci.
D’abord, regardons ce qui tourne:
user@Serveur:~$ docker container ls
CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES
987197b788c0 phpmyadmin/phpmyadmin "/docker-entrypoint.…" 4 hours ago Up 4 hours 0.0.0.0:9090->80/tcp phpmyadmin
42f4b9abed48 wordpress "docker-entrypoint.s…" 4 hours ago Up 4 hours 0.0.0.0:9990->80/tcp wordpress
b86ec4a52ac4 mysql:5.7 "docker-entrypoint.s…" 4 hours ago Up 4 hours 3306/tcp, 33060/tcp mysql
0d292b1f3d64 bastilimbach/docker-magicmirror:latest "./docker-entrypoint…" 44 hours ago Up 19 hours magic_mirror
aed1613b36de homeassistant/home-assistant:latest "/bin/entry.sh pytho…" 3 weeks ago Up 19 hours home-assistant
10a93d1c35ab b6753551581f "nginx -g 'daemon of…" 8 weeks ago Up 19 hours weewx-web
6cb1e4d0f8cd mrnonoss/weewx "/home/weewx/bin/wee…" 8 weeks ago Up 19 hours weewx-core
d413b2d14cae pihole/pihole:latest "/s6-init" 2 months ago Up 19 hours (healthy) pihole
On remarque que le conteneur mysql a un ID b86ec4a52ac4. Nous allons nous connecter à l’interieur du container et obtenir un bash:
user@Serveur:$ docker exec -ti b86ec4a52ac4 /bin/bash
root@b86ec4a52ac4:/#
Nous avons demandé a docker d’executer la commande /bin/bash à l’intérieur du container ID b86ec4a52ac4 et ce, en mode interactif (-ti) pour que nous puissions garder la main.
Au lieu d’utiliser l’ID du container, nous pourrions aussi utiliser son nom, à savoir mysql.
Vous constaterez que notre prompt a changé, il est passé de:
- user@Serveur:$
- a
- root@b86ec4a52ac4:/#
J’en profite pour vous faire part d’une petite information de sécurité que je ne vois pas souvent mentionnée.
Le daemon docker nécessite des droits super-utilisateurs. De ce fait, si aucun utilisateur n’est spécifié dans le dockerfile de votre image, l’utilisateur par défaut est « root ». Attention, il s’agit du même root que celui de votre hôte. Donc en cas de container non securisé, il est possible d’escalader jusque votre ordinateur en mode super-utilisateur…
Fin de parenthèse. Nous voici donc maintenant à l’intérieur du container. Allons voir si notre dump est la:
root@b86ec4a52ac4:/# ls -alH /var/lib/mysql/
Si il y est bien, il ne reste plus qu’à procéder à l’import:
root@b86ec4a52ac4:/# mysql --user=root --password=superpass < /var/lib/mysql/personal.sql
Et….. Paf… Une erreur:
ERROR 2006 (HY000) at line 377: MySQL server has gone away
Il semble que nous ayons un problème de « time out ». Il va falloir modifier quelques configurations.
La version docker de mysql présente un fichier de configuration spécifique situé dans /etc/mysql/conf.d/docker.cnf.
C’est ici que nous allons ajouter les options.
Pour rester dans « l’esprit docker », nous allons devoir créer ce fichier sur notre machine hôte et demander a docker de « monter » ce fichier dans le container, à la place de l’autre.
Nous allons créer un sous répertoire « conf » sur notre hôte, puis un fichier texte « docker.cnf » à l’interieur.
Le fichier de base ne contient que trois lignes:
root@b86ec4a52ac4:/# cat /etc/mysql/conf.d/docker.cnf
[mysqld]
skip-host-cache
skip-name-resolve
Nous allons ajouter une ligne permettant de définir un time-out et en profiter pour définir une taille de paquets maximum afin d’éviter d’autres erreurs:
wait_timeout = 600
max_allowed_packet = 64M
Il nous faudra aussi modifier notre docker-compose.yml pour ajouter une ligne dans notre configuration des volumes du service mysql:
................
mysql:
image: mysql:5.7
container_name: mysql
volumes:
- ${PWD}/databases:/var/lib/mysql/
- ${PWD}/conf/docker.cnf:/etc/mysql/conf.d/docker.cnf
environment:
MYSQL_ROOT_PASSWORD: superpass #change
MYSQL_USER: user #change
MYSQL_PASSWORD: resuperpass #change
MYSQL_DATABASE: personal #change
................
Enfin, il nous reste a exécuter le docker-compose.yml:
docker-compose up
Ce qui aura pour effet de recréer les containers, en prenant les modifications en compte.
Plus qu’à relancer l’import:
docker exec -ti mysql /bin/bash
root@b86ec4a52ac4:/# mysql --user=root --password=superpass < /var/lib/mysql/personal.sql
Ceci fait, nous allons bien évidemment penser a effacer nos bash_history sur les différentes machines (et dans le container), car nos mots de passes sont visibles en clair:
history -c
Congrats !! On a réussi 🙂
PS: Tout n’a pas toujours été aussi rose… l’erreur {Couldn’t execute ‘SHOW VARIABLES LIKE ‘gtid\_mode »: Table ‘performance_schema.session_variables’ doesn’t exist} est survenue.
J’ai du faire un upgrade, puis redémarrer le serveur:
mysql_upgrade -u root -p --force
systemctl restart mysqld