Configuration de MySQL et importation de dump dans Dockerfile

j'essaye de configurer un fichier Dockerfile pour mon projet de lampe, mais j'ai quelques problèmes quand je démarre MySQL. J'ai les lignes suivantes sur mon fichier Dockerfile:

VOLUME ["/etc/mysql", "/var/lib/mysql"]
ADD dump.sql /tmp/dump.sql
RUN /usr/bin/mysqld_safe & sleep 5s
RUN mysql -u root -e "CREATE DATABASE mydb"
RUN mysql -u root mydb < /tmp/dump.sql

mais je continue à avoir cette erreur:

ERROR 2002 (HY000): Can't connect to local MySQL server through socket '/var/run/mysqld/mysqld.sock' (111)

des idées sur la façon de configurer la création de base de données et l'importation de dump pendant une construction Dockerfile?

97
demandé sur Vini.g.fer 2014-09-18 22:37:27

5 réponses

chaque instruction RUN dans une instruction Dockerfile est exécutée dans une couche différente (comme expliqué dans la documentation de RUN ).

dans votre Dockerfile , vous avez trois instructions RUN . Le problème est que MySQL server n'est démarré que dans le premier. Dans les autres, Aucun MySQL n'est en cours d'exécution, c'est pourquoi vous obtenez votre erreur de connexion avec le client mysql .

Pour résoudre ce problème, vous avez 2 solutions.

Solution 1: utiliser une ligne RUN

RUN /bin/bash -c "/usr/bin/mysqld_safe --skip-grant-tables &" && \
  sleep 5 && \
  mysql -u root -e "CREATE DATABASE mydb" && \
  mysql -u root mydb < /tmp/dump.sql

Solution 2: Utiliser un script

créer un script exécutable init_db.sh :

#!/bin/bash
/usr/bin/mysqld_safe --skip-grant-tables &
sleep 5
mysql -u root -e "CREATE DATABASE mydb"
mysql -u root mydb < /tmp/dump.sql

ajoutez ces lignes à votre Dockerfile :

ADD init_db.sh /tmp/init_db.sh
RUN /tmp/init_db.sh
96
répondu Kuhess 2017-09-28 08:23:33

la dernière version de l'officiel mysql image du docker vous permet d'importer des données au démarrage. Voici mon menu fixe-composer.yml

data:
  build: docker/data/.
mysql:
  image: mysql
  ports:
    - "3307:3306"
  environment:
    MYSQL_ROOT_PASSWORD: 1234
  volumes:
    - ./docker/data:/docker-entrypoint-initdb.d
  volumes_from:
    - data

ici, j'ai mes données-dump.sql sous docker/data qui est relatif au dossier de l'docker-composer est en cours d'exécution. Je monte ce fichier sql dans ce répertoire /docker-entrypoint-initdb.d sur le conteneur.

Si vous êtes intéressé à voir comment cela fonctionne, jetez un oeil à leur docker-entrypoint.sh sur GitHub. Ils ont ajouté ce bloc pour permettre l'importation de données

    echo
    for f in /docker-entrypoint-initdb.d/*; do
        case "$f" in
            *.sh)  echo ""151910920": running $f"; . "$f" ;;
            *.sql) echo ""151910920": running $f"; "${mysql[@]}" < "$f" && echo ;;
            *)     echo ""151910920": ignoring $f" ;;
        esac
        echo
    done

une note supplémentaire, si vous voulez que les données persistent même après que le conteneur mysql est arrêté et enlevé, vous devez avoir un conteneur de données séparé comme vous voyez dans le docker-composer.yml. Le contenu du conteneur de données Dockerfile est très simple.

FROM n3ziniuka5/ubuntu-oracle-jdk:14.04-JDK8

VOLUME /var/lib/mysql

CMD ["true"]

le conteneur de données n'a même pas besoin d'être dans start état de la persistance.

142
répondu Rajiv 2016-09-27 14:06:43

ce que j'ai fait était de télécharger mon SQL dump dans un dossier" db-dump", et je l'ai monté:

mysql:
 image: mysql:5.6
 environment:
   MYSQL_ROOT_PASSWORD: pass
 ports:
   - 3306:3306
 volumes:
   - ./db-dump:/docker-entrypoint-initdb.d

quand j'exécute docker-compose up pour la première fois, le dump est restauré dans le db.

30
répondu Petru 2015-11-17 13:25:12

j'ai utilisé docker-entrypoint-initdb.d approche (grâce à @Kuhess) Mais dans mon cas, je veux créer ma base de données sur la base de certains paramètres que j'ai définis .j'ai donc fait ces

1) je commence par définir .fichier env quelque chose comme ça dans mon menu fixe racine du répertoire du projet

MYSQL_DATABASE=my_db_name
MYSQL_USER=user_test
MYSQL_PASSWORD=test
MYSQL_ROOT_PASSWORD=test
MYSQL_PORT=3306

2) puis je définirai ma composition de docker.fichier yml. J'ai donc utilisé la directive args pour définir mes variables d'environnement et je les ai pris .fichier env

version: '2'
services:
### MySQL Container
    mysql:
        build:
            context: ./mysql
            args:
                - MYSQL_DATABASE=${MYSQL_DATABASE}
                - MYSQL_USER=${MYSQL_USER}
                - MYSQL_PASSWORD=${MYSQL_PASSWORD}
                - MYSQL_ROOT_PASSWORD=${MYSQL_ROOT_PASSWORD}
        ports:
            - "${MYSQL_PORT}:3306"

3) puis je définis un dossier mysql qui inclut un fichier Dockerfile. Donc le fichier Dockerfile est ce

FROM mysql:5.7
RUN chown -R mysql:root /var/lib/mysql/

ARG MYSQL_DATABASE
ARG MYSQL_USER
ARG MYSQL_PASSWORD
ARG MYSQL_ROOT_PASSWORD

ENV MYSQL_DATABASE=$MYSQL_DATABASE
ENV MYSQL_USER=$MYSQL_USER
ENV MYSQL_PASSWORD=$MYSQL_PASSWORD
ENV MYSQL_ROOT_PASSWORD=$MYSQL_ROOT_PASSWORD

ADD data.sql /etc/mysql/data.sql
RUN sed -i 's/MYSQL_DATABASE/'$MYSQL_DATABASE'/g' /etc/mysql/data.sql
RUN cp /etc/mysql/data.sql /docker-entrypoint-initdb.d

EXPOSE 3306

4) maintenant j'utilise mysqldump pour vider ma base de données et mettre les données.sql à l'intérieur de mysql dossier

mysqldump -h <server name> -u<user> -p <db name> > data.sql

le fichier est juste un fichier de dump sql normal mais j'ajoute 2 lignes au début pour que le fichier ressemble à ceci

--
-- Create a database using `MYSQL_DATABASE` placeholder
--
CREATE DATABASE IF NOT EXISTS `MYSQL_DATABASE`;
USE `MYSQL_DATABASE`;

-- Rest of queries
DROP TABLE IF EXISTS `x`;
CREATE TABLE `x` (..)
LOCK TABLES `x` WRITE;
INSERT INTO `x` VALUES ...;
...
...
...

donc ce qui se passe est que j'ai utilisé" RUN sed-i 's/MYSQL_DATABASE/'$MYSQL_DATABASE'/g' /etc/mysql/data.sql "commande pour remplacer le placeholder MYSQL_DATABASE avec le nom de mon DB dans lequel je l'ai placé .fichier env.

|- docker-compose.yml
|- .env
|- mysql
     |- Dockerfile
     |- data.sql

Maintenant, vous êtes prêt à construire et exécuter votre conteneur

7
répondu Saman Shafigh 2017-04-04 00:57:58

Voici une version de travail utilisant v3 de docker-compose.yml . La clé est la volumes directive:

mysql:
  image: mysql:5.6
  ports:
    - "3306:3306"
  environment:
    MYSQL_ROOT_PASSWORD: root
    MYSQL_USER: theusername
    MYSQL_PASSWORD: thepw
    MYSQL_DATABASE: mydb
  volumes:
    - ./data:/docker-entrypoint-initdb.d

dans le répertoire que j'ai mon docker-compose.yml j'ai un data dir qui contient .sql dump files. C'est sympa parce que vous pouvez avoir un fichier .sql dump par table.

j'ai simplement exécuter docker-compose up et je suis bon pour aller. Les données persistent automatiquement entre les arrêts. Si vous vous voulez supprimer les données et "aspirer" nouveau .sql les fichiers courent docker-compose down puis docker-compose up .

si quelqu'un sait comment obtenir le mysql docker pour re-traiter les fichiers dans /docker-entrypoint-initdb.d sans supprimer le volume, s'il vous plaît laisser un commentaire et je vais mettre à jour cette réponse.

0
répondu rynop 2018-08-29 19:30:14