Ich versuche, einen Container mit einer MySQL-Datenbank zu erstellen und ein Schema zu dieser Datenbank hinzuzufügen.
Mein aktuelles Dockerfile ist:
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
Um den Container zu erstellen, folge ich der Dokumentation von Docker und führe diesen Befehl aus:
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
Aber wenn ich diesen Befehl ausführe, wird der Container nicht erstellt und im Container-Status kann man sehen, dass der CMD nicht erfolgreich ausgeführt wurde, sondern nur der mysql
-Befehl ausgeführt wird.
Gibt es eine Möglichkeit, die Datenbank mit dem Schema zu initialisieren, oder muss ich diese Vorgänge manuell durchführen?
Es tut mir leid für diese super lange Antwort, aber, Sie haben einen kleinen Weg zu gehen, um zu bekommen, wo Sie wollen. Ich werde sagen, dass normalerweise würden Sie nicht den Speicher für die Datenbank in den gleichen Container wie die Datenbank selbst setzen, würden Sie entweder ein Host-Volume mounten, so dass die Daten auf dem Docker-Host persistiert, oder, vielleicht ein Container verwendet werden könnte, um die Daten (/var/lib/mysql) zu halten. Außerdem bin ich neu in mysql, so, dies könnte nicht super effizient sein. Das sagte ...
Ich denke, dass es hier ein paar Probleme geben könnte. Die Dockerdatei wird verwendet, um ein Image zu erstellen. Sie müssen den Build-Schritt ausführen. Zumindest würden Sie aus dem Verzeichnis, das die Dockerdatei enthält, etwas tun wie:
docker build .
Das Dockerfile beschreibt das zu erstellende Image. Ich weiß nicht viel über mysql (ich bin ein Postgres-Fan), aber ich habe im Internet nach 'how do i initialize a mysql docker container' gesucht. Zuerst habe ich ein neues Verzeichnis zum Arbeiten erstellt, ich nannte es mdir, dann habe ich ein Verzeichnis files erstellt, in dem ich eine epcis_schema.sql-Datei hinterlegt habe, die eine Datenbank und eine einzelne Tabelle erstellt:
create database test;
use test;
CREATE TABLE testtab
(
id INTEGER AUTO_INCREMENT,
name TEXT,
PRIMARY KEY (id)
) COMMENT='this is my test table';
Dann habe ich ein Skript namens init_db im files-Verzeichnis erstellt:
#!/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
(der größte Teil dieses Skripts stammt von hier: https://gist.github.com/pda/9697520)
Hier ist das von mir erstellte Skript files/run_db:
# 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
Zum Schluss noch die Dockerdatei, um sie alle zu verbinden:
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"
Ich wechselte also mit cd'ed in mein mdir-Verzeichnis (in dem die Dockerdatei zusammen mit dem Dateiverzeichnis liegt). Dann habe ich den Befehl ausgeführt:
docker build --no-cache .
Sie sollten eine Ausgabe wie diese sehen:
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
Sie haben jetzt ein Bild '7f6d5215fe8d'. Ich könnte dieses Bild ausführen:
docker run -d 7f6d5215fe8d
und das Bild startet, sehe ich einen Instanzstring:
4b377ac7397ff5880bc9218abe6d7eadd49505d50efb5063d6fab796ee157bd3
Ich könnte es dann 'anhalten' und neu starten.
docker stop 4b377
docker start 4b377
Wenn Sie sich die Logs ansehen, steht in der ersten Zeile:
docker logs 4b377
Populate initial db
var/lib/mysql/
...
Dann, am Ende der Protokolle:
Running with existing database in /var/lib/mysql
Dies sind die Meldungen des Skripts /tmp/run_db. Die erste zeigt an, dass die Datenbank aus der gespeicherten (ursprünglichen) Version entpackt wurde, die zweite zeigt an, dass die Datenbank bereits vorhanden war, so dass die vorhandene Kopie verwendet wurde.
Hier ist ein ls -lR der Verzeichnisstruktur, die ich oben beschrieben habe. Beachten Sie, dass init_db und run_db Skripte sind, bei denen das execute-Bit gesetzt ist:
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
I've versucht Greg's Antwort mit Null Erfolg, muss ich etwas falsch gemacht haben, da meine Datenbank hatte keine Daten nach all den Schritten: Ich habe vorsichtshalber das neueste Image von MariaDB'verwendet.
Dann entschied ich mich, den Einstiegspunkt für das offizielle MariaDB-Image zu lesen und damit eine einfache docker-compose-Datei zu erzeugen:
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"
Jetzt bin ich in der Lage, meine Daten zu persistieren UND eine Datenbank mit meinem eigenen Schema zu erstellen!
Die einfachste Lösung ist die Verwendung von tutum/mysql
docker pull tutum/mysql:5.5
docker run -d -p 3306:3306 -v /tmp:/tmp -e STARTUP_SQL="/tmp/to_be_imported.mysql" tutum/mysql:5.5
Holen Sie sich obige CONTAINER_ID und führen Sie dann den Befehl docker logs
aus, um die generierten Passwortinformationen zu sehen.
docker logs #<CONTAINER_ID>