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

Laisser un commentaire