Jak zainicjować bazę danych MySQL za pomocą schematu w kontenerze dokera?
Próbuję utworzyć kontener z bazą danych MySQL i dodać do nich schemat.
Mój aktualny plik Dockerfile to:
FROM mysql
MAINTAINER (me) <email>
# 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
W celu utworzenia kontenera postępuję zgodnie z dokumentacją dostępną na Dockerze i wykonuję następujące polecenie:
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
Ale kiedy wykonuję to polecenie kontener nie jest tworzony i w stanie kontenera można zobaczyć, że CMD nie został wykonany pomyślnie, w rzeczywistości tylko mysql
Polecenie jest stracony.
W każdym razie, czy istnieje sposób, aby zainicjować bazę danych za pomocą schematu, Czy muszę wykonać te operacje ręcznie?
10 answers
Przepraszam za tę bardzo długą odpowiedź, ale masz mały sposób, aby dostać się tam, gdzie chcesz. Powiem, że normalnie nie umieszczałbyś magazynu dla bazy danych w tym samym kontenerze co sama baza danych, albo zamontowałbyś wolumin hosta, aby dane pozostały na hoście dokującym, albo może kontener mógłby być użyty do przechowywania danych (/var/lib / mysql). Poza tym jestem nowy w mysql, więc może to nie być zbyt wydajne. To powiedziane...
Myślę, że może być kilka problemy tutaj. Plik Dockerfile jest używany do tworzenia obrazu. Musisz wykonać krok budowania. Co najmniej z katalogu zawierającego plik Dockerfile można zrobić coś w stylu:
docker build .
Plik Dockerfile opisuje obraz do utworzenia. Nie wiem zbyt wiele o mysql( jestem fanboyem postgres), ale, zrobiłem poszukiwania wokół interwebs dla "jak zainicjować kontener mysql docker". Najpierw utworzyłem nowy katalog do pracy, nazwałem go mdir, a następnie utworzyłem katalog plików które złożyłem epcis_schema.plik sql, który tworzy bazę danych i pojedynczą tabelę:
create database test;
use test;
CREATE TABLE testtab
(
id INTEGER AUTO_INCREMENT,
name TEXT,
PRIMARY KEY (id)
) COMMENT='this is my test table';
Następnie utworzyłem skrypt o nazwie init_db w katalogu files:
#!/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 e.g. `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
(większość tego skryptu została zdjęta stąd: https://gist.github.com/pda/9697520 )
Oto skrypt files/run_db, który stworzyłem:
# 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
Wreszcie, plik Dockerfile, aby powiązać je wszystkie:
FROM mysql
MAINTAINER (me) <email>
# 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"
Więc, cd'ed do mojego katalogu mdir (który ma plik Dockerfile wraz z katalog plików). Następnie uruchamiam polecenie:
docker build --no-cache .
Powinieneś zobaczyć takie wyjście:
Sending build context to Docker daemon 7.168 kB
Sending build context to Docker daemon
Step 0 : FROM mysql
---> 461d07d927e6
Step 1 : MAINTAINER (me) <email>
---> 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
Masz teraz obraz "7f6d5215fe8d". Mógłbym uruchomić to zdjęcie:
docker run -d 7f6d5215fe8d
I zaczyna się obrazek, widzę ciąg instancji:
4b377ac7397ff5880bc9218abe6d7eadd49505d50efb5063d6fab796ee157bd3
Mogłem go "zatrzymać"i uruchomić ponownie.
docker stop 4b377
docker start 4b377
Jeśli spojrzysz na logi, pierwsza linia będzie zawierać:
docker logs 4b377
Populate initial db
var/lib/mysql/
...
Następnie, na końcu logów:
Running with existing database in /var/lib/mysql
To są wiadomości z / tmp / run_db skrypt, pierwszy wskazuje, że baza danych została rozpakowana z zapisanej (początkowej) wersji, drugi wskazuje, że baza danych już tam była, więc została użyta istniejąca Kopia.
Oto LS-lR struktury katalogów, którą opisałem powyżej. Zauważ, że init_db i run_db są skryptami z ustawionym bitem execute:
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
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2016-12-01 22:11:36
Miałem ten sam problem, w którym chciałem zainicjować schemat mojej instancji Dockera MySQL, ale napotkałem trudności z uzyskaniem tego po wykonaniu googlowania i podążaniu za przykładami innych. Oto jak to rozwiązałem.
1) zrzuć swój schemat MySQL do pliku.
mysqldump -h <your_mysql_host> -u <user_name> -p --no-data <schema_name> > schema.sql
2) Użyj polecenia Dodaj, aby dodać plik schematu do katalogu /docker-entrypoint-initdb.d
w kontenerze dokera. Plik docker-entrypoint.sh
uruchomi wszystkie pliki w tym katalogu kończące się na ".sql"
przeciwko MySQL baza danych.
Dockerfile:
FROM mysql:5.7.15
MAINTAINER me
ENV MYSQL_DATABASE=<schema_name> \
MYSQL_ROOT_PASSWORD=<password>
ADD schema.sql /docker-entrypoint-initdb.d
EXPOSE 3306
3) Uruchom instancję Docker MySQL.
docker-compose build
docker-compose up
Dzięki skonfigurowaniu MySQL i zaimportowaniu zrzutu w Dockerfile za podpowiedzenie mi na docker-entrypoint.sh i fakt, że uruchamia zarówno skrypty SQL i shell!
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2017-05-23 12:34:50
Próbowałem odpowiedzi Grega z zerowym powodzeniem, musiałem coś zrobić źle, ponieważ moja baza danych nie miała danych po wszystkich krokach: na wszelki wypadek korzystałem z najnowszego obrazu MariaDB.
Potem postanowiłem przeczytać entrypoint dla oficjalnego MariaDB image i użyłem go do wygenerowania prostegodocker-compose pliku:
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"
Teraz jestem w stanie utrzymać moje dane i wygenerować bazę danych z mojego własnego schematu!
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2016-04-04 16:10:40
Inny sposób oparty na połączeniu serwerowych odpowiedzi tutaj przed :
Docker-compose file:
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
Gdzie /home/user
.. jest folderem udostępnionym na hoście
I w folderze /home/user/db/mysql/init
.. wystarczy upuścić jeden plik sql o dowolnej nazwie, na przykład init.sql
zawierający:
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 ...
[ ... ]
Zgodnie z oficjalna dokumentacja mysql, można umieścić więcej niż jeden plik sql w docker-entrypoint-initdb.d
, są one wykonywane w porządku alfabetycznym
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2017-06-01 13:16:21
Po 4, 2015, Jeśli używasz oficjalnego obrazu Dockera mysql, możesz po prostu dodać / skopiować plik do /Docker-entrypoint-initdb.d / katalog i będzie działać z kontenerem jest zainicjowany. Zobacz github: https://github.com/docker-library/mysql/commit/14f165596ea8808dfeb2131f092aabe61c967225 jeśli chcesz zaimplementować go na innych obrazach kontenera
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2016-08-12 14:40:11
Najprostszym rozwiązaniem jest użycie tutum / mysql
Krok 1
docker pull tutum/mysql:5.5
Krok 2
docker run -d -p 3306:3306 -v /tmp:/tmp -e STARTUP_SQL="/tmp/to_be_imported.mysql" tutum/mysql:5.5
Step3
Przejdź powyżej CONTAINER_ID, a następnie wykonaj polecenie docker logs
, aby zobaczyć wygenerowane informacje o Hasle.
docker logs #<CONTAINER_ID>
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2015-12-20 04:22:35
W inny prosty sposób, użyj docker-compose z opadającymi liniami:
mysql:
from: mysql:5.7
volumes:
- ./database:/tmp/database
command: mysqld --init-file="/tmp/database/install_db.sql"
Umieść swój schemat bazy danych w/ database / install_db.sql. Za każdym razem, gdy budujesz kontener, install_db.SQL wykonany.
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2017-01-26 10:41:21
Dla tych, którzy nie chcą tworzyć skryptu entrypoint jak ja, w rzeczywistości można uruchomić mysqld w czasie kompilacji, a następnie wykonać polecenia mysql w pliku Dockerfile w następujący sposób:
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';"
Kluczem jest wysłanie mysqld_safe do tła za pomocą pojedynczego znaku &
.
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2018-02-06 16:53:21
Po tym, aby trochę się z tym zmagać, spójrz na plik Dockerfile używając nazwanych woluminów (db-data).
Ważne jest, aby dodać plus w końcowej części, gdzie wspomniałem, że objętość jest [external]
Wszystko działało świetnie w ten sposób!
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
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2017-05-02 09:38:13
Poniżej znajduje się plik Dockerfile, którego z powodzeniem użyłem do zainstalowania xampp, utworzenia MariaDB ze schematem i wstępnie wypełniony informacjami używanymi na lokalnym serwerze (usrs,zamówienia zdjęć,itp..)
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
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2017-11-21 00:50:30