मैं एक डॉक कंटेनर में स्कीमा के साथ एक MySQL डेटाबेस कैसे शुरू कर सकता हूं?


165

मैं एक MySQL डेटाबेस के साथ एक कंटेनर बनाने और इन डेटाबेस में एक स्कीमा जोड़ने की कोशिश कर रहा हूं।

मेरा वर्तमान डॉकरीफ़ाइल है:

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

कंटेनर बनाने के लिए मैं डॉकर पर दिए गए दस्तावेज का पालन कर रहा हूं और इस कमांड को निष्पादित कर रहा हूं:

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

लेकिन जब मैं इस कमांड को निष्पादित करता हूं तो कंटेनर नहीं बनाया जाता है और कंटेनर की स्थिति में यह देखना संभव है कि सीएमडी को सफलतापूर्वक निष्पादित नहीं किया गया था, वास्तव में केवल mysqlकमांड निष्पादित होता है।

वैसे भी, डेटाबेस को स्कीमा के साथ आरंभ करने का एक तरीका है या क्या मुझे इन कार्यों को मैन्युअल रूप से करने की आवश्यकता है?


मुझे लगता है कि आप एक डेटाबेस के साथ एक नई छवि बनाना चाहते हैं जो बीजित है और जाने के लिए तैयार है?
ग्रेग

हां, यह वही है जो मैं करना चाहता हूं।
मार्कस गोम्स


: यहां बताई गई है भी medium.com/@lvthillo/...
lvthillo

जवाबों:


105

मुझे इस सुपर लंबे जवाब के लिए खेद है, लेकिन, आपके पास जहां आप चाहते हैं वहां जाने के लिए थोड़ा रास्ता है। मैं कहूंगा कि आम तौर पर आप डेटाबेस के लिए डेटाबेस के रूप में एक ही कंटेनर में स्टोरेज नहीं रखेंगे, आप या तो एक होस्ट वॉल्यूम माउंट करेंगे ताकि डेटा डॉक होस्ट पर बना रहे, या, शायद एक कंटेनर का उपयोग किया जा सके डेटा (/ var / lib / mysql) दबाए रखें। इसके अलावा, मैं mysql के लिए नया हूं, इसलिए, यह सुपर कुशल नहीं हो सकता है। ने कहा कि...

मुझे लगता है कि यहां कुछ मुद्दे हो सकते हैं। Dockerfile का उपयोग छवि बनाने के लिए किया जाता है। आपको बिल्ड चरण निष्पादित करने की आवश्यकता है। कम से कम, उस निर्देशिका से जिसमें डॉकरफ़ाइल सम्‍मिलित है, आप कुछ ऐसा करेंगे:

docker build .

Dockerfile बनाने के लिए छवि का वर्णन करता है। मुझे mysql के बारे में ज्यादा जानकारी नहीं है (मैं एक पोस्टग्रैस फैनबॉय हूं), लेकिन, मैंने 'मैं एक mysql docker कंटेनर को इनिशियलाइज़ कैसे करूं' के लिए इंटरव्यू के आसपास एक खोज की। पहले मैंने काम करने के लिए एक नई निर्देशिका बनाई, मैंने इसे mdir कहा, फिर मैंने एक फ़ाइल निर्देशिका बनाई, जिसे मैंने एक epcis_schema.sql फ़ाइल में जमा किया, जो एक डेटाबेस और एक एकल तालिका बनाता है:

create database test;
use test;

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

तब मैंने फाइल डायरेक्टरी में init_db नामक स्क्रिप्ट बनाई:

#!/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

(इस स्क्रिप्ट का अधिकांश भाग यहां से हटा लिया गया था: https://gist.github.com/pda/9697520 )

यहाँ फ़ाइलें / 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

अंत में, उन सभी को बांधने के लिए Dockerfile:

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"

इसलिए, मैंने अपनी mdir डायरेक्टरी (जिसमें फाइल डायरेक्टरी के साथ Dockerfile है) को cd'ed किया है। मैं फिर कमांड चलाता हूं:

docker build --no-cache .

आपको इस तरह आउटपुट देखना चाहिए:

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

अब आपके पास एक चित्र है '7f6d5215fe8d'। मैं इस छवि को चला सकता हूं:

docker run -d 7f6d5215fe8d

और छवि शुरू होती है, मुझे एक उदाहरण स्ट्रिंग दिखाई देती है:

4b377ac7397ff5880bc9218abe6d7eadd49505d50efb5063d6fab796ee157bd3

मैं तब इसे 'रोक' सकता था, और इसे पुनः आरंभ कर सकता था।

docker stop 4b377
docker start 4b377

यदि आप लॉग को देखते हैं, तो पहली पंक्ति में होगा:

docker logs 4b377

Populate initial db
var/lib/mysql/
...

फिर, लॉग के अंत में:

Running with existing database in /var/lib/mysql

ये / tmp / run_db स्क्रिप्ट के संदेश हैं, पहला इंगित करता है कि डेटाबेस को सहेजे गए (प्रारंभिक) संस्करण से अनपैक किया गया था, दूसरा इंगित करता है कि डेटाबेस पहले से ही था, इसलिए मौजूदा प्रतिलिपि का उपयोग किया गया था।

यहाँ निर्देशिका संरचना का एक एलएसएल है जिसका मैं ऊपर वर्णन करता हूं। ध्यान दें कि init_db और run_db निष्पादित बिट सेट के साथ स्क्रिप्ट हैं:

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

3
हे गैरी, मेरी मदद करने के लिए पहला धन्यवाद। मैंने आपके निर्देशों का पालन किया, लेकिन जब मैं docker build --no-cache निष्पादित करता हूं। , मैं init_dbस्क्रिप्ट के लिए एक अनुमति त्रुटि है ।
मार्कस गोम्स

मैं पहले से ही यह तय करने की कोशिश करता हूं कि RUNकमांड में अनुमति देकर और समस्या स्पष्ट रूप से हल हो गई है। लेकिन तब जब मैं निष्पादित करता docker runहूं तो मुझे run_dbस्क्रिप्ट के साथ भी यही समस्या है ।
मार्कस गोम्स

1
init_db और run_db को 0755 अनुमति की आवश्यकता है (वे स्क्रिप्ट हैं, उन्हें थोड़ा सा सेट करने की आवश्यकता है। एक chmod + x init_db run_db
ग्रेग

मैंने प्रत्येक फाइल पर अनुमतियों को दर्शाने वाली डायरेक्टरी लिस्टिंग के साथ उत्तर को अपडेट किया। नोट: chmod + x फ़ाइलें / * _ db आवश्यक अनुमतियों को पूरा करेगा।
ग्रेग

2
@Greg मैंने उपरोक्त चरणों की कोशिश की हालांकि मुझे एक त्रुटि मिल रही है ([त्रुटि] घातक त्रुटि: कृपया मैनुअल के "सुरक्षा" अनुभाग को पढ़ें कि कैसे रूट के रूप में mysqld को चलाया जाए!)। कोई सुझाव ?
बिनीश जॉन

121

मेरे पास यह वही मुद्दा था जहां मैं अपने MySQL डॉकर्स इंस्टेंस के स्कीमा को इनिशियलाइज़ करना चाहता था, लेकिन कुछ Googling करने और दूसरों के उदाहरणों का पालन करने के बाद मुझे यह काम करने में कठिनाई हुई। यहां मैंने इसे हल किया है।

1) एक फ़ाइल के लिए अपने MySQL स्कीमा डंप।

mysqldump -h <your_mysql_host> -u <user_name> -p --no-data <schema_name> > schema.sql

2) अपनी स्कीमा फ़ाइल को /docker-entrypoint-initdb.dडॉकर कंटेनर में निर्देशिका में जोड़ने के लिए ADD कमांड का उपयोग करें । docker-entrypoint.shफ़ाइल इस निर्देशिका के साथ समाप्त होने में किसी भी फाइल चलेंगे ".sql"MySQL डेटाबेस के खिलाफ।

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) Docker MySQL उदाहरण को शुरू करें।

docker-compose build
docker-compose up

MySQL की स्थापना करने के लिए धन्यवाद और मुझे docker-entrypoint.sh पर क्लू करने के लिए Dockerfile के भीतर डंप आयात और तथ्य यह है कि यह दोनों SQL और शेल स्क्रिप्ट चलाता है!


2
यह निश्चित रूप से बेहतर जवाब है। DDLs और आरंभीकरण लिपियों को /docker-entrypoint-initdb.d निर्देशिका में कॉपी करना, dockerhub mysql डॉक्स को इस तरह की चीजों के साथ क्या करना है।
चेसवेल्स

2
जब कुछ बदलता है तो क्या होता है schema.sql? मैं चाहता हूं कि मेरे डीबी को तदनुसार अपडेट किया जाए। इसके अलावा क्या होता है जब मैं दूसरी बार इस कंटेनर का निर्माण करता हूं? क्या डीबी नष्ट हो जाएगा और फिर से बनाया जाएगा?
गोगा कोरेली

1
@ गोगा कोरेली डोकर केवल इनिट कमांड चलाता है, अगर कोई डेटा एंट्री / var / lib / mysql में नहीं है
medTech

38

इससे पहले यहां एक अन्य तरीका जो सर्वर संबंधी प्रतिक्रियाओं के विलय पर आधारित है:

docker- रचना फ़ाइल:

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

कहाँ /home/user.. मेजबान पर एक साझा फ़ोल्डर है

और /home/user/db/mysql/initफ़ोल्डर में .. बस किसी भी नाम के साथ एक sql फ़ाइल को छोड़ दें, उदाहरण के लिए init.sql:

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 ...
[ ... ]

आधिकारिक mysql प्रलेखन के अनुसार , आप एक से अधिक sql फ़ाइल डाल सकते docker-entrypoint-initdb.dहैं, वे वर्णानुक्रम में निष्पादित होते हैं


28

दूसरा सरल तरीका, निम्न पंक्तियों के साथ docker-compose का उपयोग करें:

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

अपने डेटाबेस स्कीमा को ./database/install_db.sql में डालें। हर बार जब आप अपने कंटेनर का निर्माण करते हैं, तो install_db.sql निष्पादित हो जाएगा।


26

मैंने ग्रेग के जवाब को शून्य सफलता के साथ आज़माया है, मैंने कुछ गलत किया होगा क्योंकि मेरे डेटाबेस में सभी चरणों के बाद कोई डेटा नहीं था: मैं मारबाडी की नवीनतम छवि का उपयोग कर रहा था, बस मामले में।

तब मैंने आधिकारिक MariaDB छवि के लिए प्रविष्टि बिंदु को पढ़ने का फैसला किया , और एक साधारण डॉकटर-कम्पोज़ फ़ाइल बनाने के लिए इसका उपयोग किया:

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"

अब मैं अपने डेटा को बनाए रखने और अपने स्वयं के स्कीमा के साथ एक डेटाबेस बनाने में सक्षम हूं!


1
नमस्ते, मैं भी ऐसा ही करने की कोशिश कर रहा हूं, लेकिन पटकथा कभी निष्पादित नहीं होती है। क्या कोई अन्य पैरामीटर है जिसे प्रदान करने की आवश्यकता है? मैंने अभी इस वॉल्यूम को mariadb के लिए जोड़ा है --/database/schema.sql:/docker-entrypoint-initdb.d/schema.sql:ro। धन्यवाद
bilak

नोट: स्क्रिप्ट को कंटेनर इनिशियलाइज़ेशन के दौरान केवल एक बार निष्पादित किया जाएगा। यदि आप बाद में एक नई स्क्रिप्ट जोड़ते हैं तो यह निष्पादित नहीं होगा।
ALex_hha

23

4 अगस्त, 2015 के बाद, यदि आप आधिकारिक mysql Docker छवि का उपयोग कर रहे हैं, तो आप बस /docker-entrypoint-initdb.d/ निर्देशिका में एक फ़ाइल जोड़ सकते हैं और इसे कंटेनर के साथ चलाया जा सकता है। यदि आप इसे अन्य कंटेनर छवियों पर लागू करना चाहते हैं तो github देखें: https://github.com/docker-library/mysql/commit/14f165596ea8808dfeb2131f092aabe61c967225


1
यह आधिकारिक डॉकर MSQL छवि के वर्तमान संस्करणों के लिए सही उत्तर है।
NaN

11

सबसे आसान उपाय है टुटम / मायस्कल का उपयोग करना

चरण 1

docker pull tutum/mysql:5.5

चरण 2

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

चरण 3

CONTAINER_ID से ऊपर उठें और फिर docker logsउत्पन्न पासवर्ड जानकारी देखने के लिए कमांड निष्पादित करें।

docker logs #<CONTAINER_ID>

क्या आपने इसे सफलतापूर्वक चलाने के लिए प्राप्त किया है? मैं कोई सफलता के साथ हफ्तों के लिए tutum / mysql के साथ fiddling गया है।
आईमेसोल

2
हाँ। मैं उपयोग करता हूं tutum/mysql:5.5और यह सफल रहा। docker run -d -p 3306:3306 -v /tmp:/tmp -e MYSQL_PASS="admin" -e STARTUP_SQL="/tmp/mysqldump.mysql" tutum/mysql:5.5docker logs CONTAINER_IDयदि आप समस्याओं को पूरा करते हैं तो आप हमेशा त्रुटि संदेशों को देखने के लिए कमांड निष्पादित कर सकते हैं।
मेनफ्रेमर

मैं समझ नहीं पा रहा हूँ कि रास्ता कहाँ /tmp/to_be_imported.mysqlसे आ रहा है। मेजबान ओएस पर एक रास्ता है? जहां एक है COPYया ADDकंटेनर की फाइल सिस्टम पर बातें डाल करने के लिए?
रैंडी एल

@ the0ther आप की जरूरत नहीं है COPY/ ADDक्योंकि / tmp मेजबान निर्देशिका कंटेनर के / tmp के लिए मुहिम शुरू की है। कमान पर बारीकी से देखो वहाँ हिस्सा है -v /tmp:/tmp। व्यक्तिगत रूप से मैं फ़ाइल को कंटेनर में उपलब्ध कराने के लिए केवल एक वॉल्यूम माउंट नहीं करूंगा, लेकिन मुझे लगता है कि यह एक व्यक्तिगत पसंद है।
विल

1
निष्पक्ष होना करने के लिए, आप गैर-सरकारी छवियों का उपयोग नहीं करना चाहिए, जब तक आप चाहते हैं यह फिर से करने के लिए।
ड्रैगस

3

मेरे जैसे एक एंट्रीपॉइंट स्क्रिप्ट बनाने की इच्छा न रखने वाले लोगों के लिए, आप वास्तव में बिल्ड-टाइम पर mysqld शुरू कर सकते हैं और फिर अपने Dockerfile में mysql कमांड निष्पादित कर सकते हैं:

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';"

यहाँ कुंजी mysqld_safe को एकल &चिह्न के साथ पृष्ठभूमि में भेजने के लिए है ।


1

नीचे Dockerfile मैं सफलतापूर्वक xampp स्थापित करने के लिए उपयोग किया जाता है, योजना के साथ एक MariaDB बनाएं और स्थानीय सर्वर (usrs, pics आदेश, आदि) पर उपयोग की जाने वाली जानकारी के साथ पहले से आबादी है।)

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

0

उसके साथ थोड़ा संघर्ष करने के बाद, नामांकित संस्करणों (db-data) का उपयोग करके डॉकरीफाइल देखें। यह महत्वपूर्ण है कि अंतिम भाग में एक प्लस घोषित किया जाए, जहां मैंने उल्लेख किया है कि वॉल्यूम है[external]

सभी ने इस तरह शानदार काम किया!

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
हमारी साइट का प्रयोग करके, आप स्वीकार करते हैं कि आपने हमारी Cookie Policy और निजता नीति को पढ़ और समझा लिया है।
Licensed under cc by-sa 3.0 with attribution required.