Como posso inicializar um database MySQL com esquema em um contêiner Docker?

Eu estou tentando criar um contêiner com um database MySQL e adicionar um esquema para esses database.

Meu Dockerfile atual é:

FROM mysql MAINTAINER (me)  # Copy the database schema to the /data directory COPY files/epcis_schema.sql /data/epcis_schema.sql # Change the working directory WORKDIR data CMD mysql -u $MYSQL_USER -p $MYSQL_PASSWORD $MYSQL_DATABASE < epcis_schema.sql 

Para criar o container, estou seguindo a documentação fornecida no Docker e executando este comando:

 docker run --name ${CONTAINER_NAME} -e MYSQL_ROOT_PASSWORD=${DB_ROOT_PASSWORD} -e MYSQL_USER=${DB_USER} -e MYSQL_PASSWORD=${DB_USER_PASSWORD} -e MYSQL_DATABASE=${DB_NAME} -d mvpgomes/epcisdb 

Mas quando eu executo este comando o Container não é criado e no status Container é possível ver que o CMD não foi executado com sucesso, na verdade apenas o comando mysql é executado.

De qualquer forma, existe uma maneira de inicializar o database com o esquema ou eu preciso executar essas operações manualmente?

Sinto muito por esta resposta super longa, mas você tem um pequeno caminho para chegar onde quer. Eu diria que normalmente você não colocaria o armazenamento para o database no mesmo contêiner que o próprio database, você montaria um volume de host para que os dados persistissem no host do docker ou talvez um contêiner pudesse ser usado para mantenha os dados (/ var / lib / mysql). Além disso, eu sou novo no mysql, então, isso pode não ser super eficiente. Dito isto…

Eu acho que pode haver alguns problemas aqui. O Dockerfile é usado para criar uma imagem. Você precisa executar a etapa de criação. No mínimo, no diretório que contém o Dockerfile, você faria algo como:

 docker build . 

O Dockerfile descreve a imagem para criar. Eu não sei muito sobre o mysql (eu sou um fanboy postgres), mas, eu fiz uma pesquisa em torno das interwebs para ‘como faço para inicializar um container docker mysql’. Primeiro eu criei um novo diretório para trabalhar, chamei-o de mdir, então criei um diretório de arquivos que eu coloquei um arquivo epcis_schema.sql que cria um database e uma única tabela:

 create database test; use test; CREATE TABLE testtab ( id INTEGER AUTO_INCREMENT, name TEXT, PRIMARY KEY (id) ) COMMENT='this is my test table'; 

Então eu criei um script chamado init_db no diretório de arquivos:

 #!/bin/bash # Initialize MySQL database. # ADD this file into the container via Dockerfile. # Assuming you specify a VOLUME ["/var/lib/mysql"] or `-v /var/lib/mysql` on the `docker run` command… # Once built, do eg `docker run your_image /path/to/docker-mysql-initialize.sh` # Again, make sure MySQL is persisting data outside the container for this to have any effect. set -e set -x mysql_install_db # Start the MySQL daemon in the background. /usr/sbin/mysqld & mysql_pid=$! until mysqladmin ping >/dev/null 2>&1; do echo -n "."; sleep 0.2 done # Permit root login without password from outside container. mysql -e "GRANT ALL ON *.* TO root@'%' IDENTIFIED BY '' WITH GRANT OPTION" # create the default database from the ADDed file. mysql < /tmp/epcis_schema.sql # Tell the MySQL daemon to shutdown. mysqladmin shutdown # Wait for the MySQL daemon to exit. wait $mysql_pid # create a tar file with the database as it currently exists tar czvf default_mysql.tar.gz /var/lib/mysql # the tarfile contains the initialized state of the database. # when the container is started, if the database is empty (/var/lib/mysql) # then it is unpacked from default_mysql.tar.gz from # the ENTRYPOINT /tmp/run_db script 

(a maior parte deste script foi levantada a partir daqui: https://gist.github.com/pda/9697520 )

Aqui está o script files / run_db que eu criei:

 # start db set -e set -x # first, if the /var/lib/mysql directory is empty, unpack it from our predefined db [ "$(ls -A /var/lib/mysql)" ] && echo "Running with existing database in /var/lib/mysql" || ( echo 'Populate initial db'; tar xpzvf default_mysql.tar.gz ) /usr/sbin/mysqld 

Finalmente, o Dockerfile para ligar todos eles:

 FROM mysql MAINTAINER (me)  # Copy the database schema to the /data directory ADD files/run_db files/init_db files/epcis_schema.sql /tmp/ # init_db will create the default # database from epcis_schema.sql, then # stop mysqld, and finally copy the /var/lib/mysql directory # to default_mysql_db.tar.gz RUN /tmp/init_db # run_db starts mysqld, but first it checks # to see if the /var/lib/mysql directory is empty, if # it is it is seeded with default_mysql_db.tar.gz before # the mysql is fired up ENTRYPOINT "/tmp/run_db" 

Então, eu cd'ed para o meu diretório mdir (que tem o Dockerfile junto com o diretório de arquivos). Eu então corro o comando:

 docker build --no-cache . 

Você deve ver a saída assim:

 Sending build context to Docker daemon 7.168 kB Sending build context to Docker daemon Step 0 : FROM mysql ---> 461d07d927e6 Step 1 : MAINTAINER (me)  ---> Running in 963e8de55299 ---> 2fd67c825c34 Removing intermediate container 963e8de55299 Step 2 : ADD files/run_db files/init_db files/epcis_schema.sql /tmp/ ---> 81871189374b Removing intermediate container 3221afd8695a Step 3 : RUN /tmp/init_db ---> Running in 8dbdf74b2a79 + mysql_install_db 2015-03-19 16:40:39 12 [Note] InnoDB: Using atomics to ref count buffer pool pages ... /var/lib/mysql/ib_logfile0 ---> 885ec2f1a7d5 Removing intermediate container 8dbdf74b2a79 Step 4 : ENTRYPOINT "/tmp/run_db" ---> Running in 717ed52ba665 ---> 7f6d5215fe8d Removing intermediate container 717ed52ba665 Successfully built 7f6d5215fe8d 

Agora você tem uma imagem '7f6d5215fe8d'. Eu poderia rodar esta imagem:

 docker run -d 7f6d5215fe8d 

e a imagem começa, vejo uma string de instância:

 4b377ac7397ff5880bc9218abe6d7eadd49505d50efb5063d6fab796ee157bd3 

Eu poderia então "pará-lo" e reiniciá-lo.

 docker stop 4b377 docker start 4b377 

Se você observar os logs, a primeira linha conterá:

 docker logs 4b377 Populate initial db var/lib/mysql/ ... 

Então, no final dos logs:

 Running with existing database in /var/lib/mysql 

Estas são as mensagens do script / tmp / run_db, a primeira indica que o database foi descompactado da versão salva (inicial), a segunda indica que o database já estava lá, então a cópia existente foi usada.

Aqui está um ls -lR da estrutura de diretórios que eu descrevi acima. Note que o init_db e o run_db são scripts com o bit de execução definido:

 gregs-air:~ gfausak$ ls -Rl mdir total 8 -rw-r--r-- 1 gfausak wheel 534 Mar 19 11:13 Dockerfile drwxr-xr-x 5 gfausak staff 170 Mar 19 11:24 files mdir/files: total 24 -rw-r--r-- 1 gfausak staff 126 Mar 19 11:14 epcis_schema.sql -rwxr-xr-x 1 gfausak staff 1226 Mar 19 11:16 init_db -rwxr-xr-x 1 gfausak staff 284 Mar 19 11:23 run_db 

Eu tive esse mesmo problema em que eu queria inicializar o esquema da minha instância do MySQL Docker, mas tive dificuldades para fazer isso funcionar depois de fazer alguns Googling e seguir os exemplos dos outros. Aqui está como eu resolvi isso.

1) Despeje seu esquema do MySQL em um arquivo.

 mysqldump -h  -u  -p --no-data  > schema.sql 

2) Use o comando ADD para adicionar seu arquivo de esquema ao diretório /docker-entrypoint-initdb.d no contêiner Docker. O arquivo docker-entrypoint.sh executará todos os arquivos nesse diretório que terminem com ".sql" no database MySQL.

Dockerfile:

 FROM mysql:5.7.15 MAINTAINER me ENV MYSQL_DATABASE= \ MYSQL_ROOT_PASSWORD= ADD schema.sql /docker-entrypoint-initdb.d EXPOSE 3306 

3) Inicie a instância do Docker MySQL.

 docker-compose build docker-compose up 

Obrigado ao Configurando o MySQL e importando o dump dentro do Dockerfile para me ajudar com o docker-entrypoint.sh e o fato dele rodar SQL e shell scripts!

Eu tentei a resposta de Greg com sucesso zero, eu devo ter feito algo errado já que meu database não tinha dados depois de todas as etapas: Eu estava usando a última imagem do MariaDB, apenas no caso.

Então decidi ler o ponto de input para a imagem oficial do MariaDB e usei-o para gerar um arquivo simples do docker-compose :

 database: image: mariadb ports: - 3306:3306 expose: - 3306 volumes: - ./docker/mariadb/data:/var/lib/mysql:rw - ./database/schema.sql:/docker-entrypoint-initdb.d/schema.sql:ro environment: MYSQL_ALLOW_EMPTY_PASSWORD: "yes" 

Agora sou capaz de persistir meus dados e gerar um database com meu próprio esquema!

Outra maneira baseada em uma mesclagem de respostas serveral aqui antes:

arquivo docker-compose:

 version: "3" services: db: container_name: db image: mysql ports: - "3306:3306" environment: - MYSQL_ROOT_PASSWORD=mysql - MYSQL_DATABASE=db volumes: - /home/user/db/mysql/data:/var/lib/mysql - /home/user/db/mysql/init:/docker-entrypoint-initdb.d/:ro 

onde /home/user .. é uma pasta compartilhada no host

E na pasta /home/user/db/mysql/init .. apenas solte um arquivo sql, com qualquer nome, por exemplo init.sql contendo:

 CREATE DATABASE mydb; GRANT ALL PRIVILEGES ON mydb.* TO 'myuser'@'%' IDENTIFIED BY 'mysql'; GRANT ALL PRIVILEGES ON mydb.* TO 'myuser'@'localhost' IDENTIFIED BY 'mysql'; USE mydb CREATE TABLE CONTACTS ( [ ... ] ); INSERT INTO CONTACTS VALUES ... [ ... ] 

De acordo com a documentação oficial do mysql , você pode colocar mais de um arquivo sql no docker-entrypoint-initdb.d , eles são executados em ordem alfabética

Depois de 4 de agosto de 2015, se você estiver usando a imagem oficial do mysql Docker, você pode simplesmente ADICIONAR / COPIAR um arquivo no diretório /docker-entrypoint-initdb.d/ e ele será executado com o contêiner sendo inicializado. Veja github: https://github.com/docker-library/mysql/commit/14f165596ea8808dfeb2131f092aabe61c967225 se você quiser implementá-lo em outras imagens de contêiner

A solução mais fácil é usar o tutum / mysql

Passo 1

 docker pull tutum/mysql:5.5 

Passo 2

 docker run -d -p 3306:3306 -v /tmp:/tmp -e STARTUP_SQL="/tmp/to_be_imported.mysql" tutum/mysql:5.5 

Etapa 3

Obtenha acima de CONTAINER_ID e, em seguida, execute os docker logs comando para ver as informações de senha geradas.

 docker logs # 

A outra maneira simples, use o docker-compose com as seguintes linhas:

 mysql: from: mysql:5.7 volumes: - ./database:/tmp/database command: mysqld --init-file="/tmp/database/install_db.sql" 

Coloque seu esquema de database no ./database/install_db.sql. Toda vez que você constrói seu contêiner, o install_db.sql é executado.

Para aqueles que não querem criar um script de ponto de input como eu, você pode realmente iniciar o mysqld em tempo de compilation e então executar os comandos mysql no seu Dockerfile da seguinte forma:

 RUN mysqld_safe & until mysqladmin ping; do sleep 1; done && \ mysql -uroot -e "CREATE DATABASE somedb;" && \ mysql -uroot -e "CREATE USER 'someuser'@'localhost' IDENTIFIED BY 'somepassword';" && \ mysql -uroot -e "GRANT ALL PRIVILEGES ON somedb.* TO 'someuser'@'localhost';" 

A chave aqui é enviar mysqld_safe para o fundo com o single & sign.

Depois de lutar um pouco com isso, dê uma olhada no Dockerfile usando volumes nomeados (db-data). É importante declarar um ponto final na parte final, onde mencionei que o volume é [external]

Tudo funcionou muito bem!

 version: "3" services: database: image: mysql:5.7 container_name: mysql ports: - "3306:3306" volumes: - db-data:/docker-entrypoint-initdb.d environment: - MYSQL_DATABASE=sample - MYSQL_ROOT_PASSWORD=root volumes: db-data: external: true 

Abaixo está o Dockerfile que usei com sucesso para instalar o xampp, criar um MariaDB com esquema e pré-preenchido com as informações usadas no servidor local (usrs, pics orders, etc ..)

 FROM ubuntu:14.04 COPY Ecommerce.sql /root RUN apt-get update \ && apt-get install wget -yq \ && apt-get install nano \ && wget https://www.apachefriends.org/xampp-files/7.1.11/xampp-linux-x64-7.1.11-0-installer.run \ && mv xampp-linux-x64-7.1.11-0-installer.run /opt/ \ && cd /opt/ \ && chmod +x xampp-linux-x64-7.1.11-0-installer.run \ && printf 'y\n\y\n\r\n\y\n\r\n' | ./xampp-linux-x64-7.1.11-0-installer.run \ && cd /opt/lampp/bin \ && /opt/lampp/lampp start \ && sleep 5s \ && ./mysql -uroot -e "CREATE DATABASE Ecommerce" \ && ./mysql -uroot -D Ecommerce < /root/Ecommerce.sql \ && cd / \ && /opt/lampp/lampp reload \ && mkdir opt/lampp/htdocs/Ecommerce COPY /Ecommerce /opt/lampp/htdocs/Ecommerce EXPOSE 80 
    Intereting Posts