[mysql] Docker 컨테이너에서 스키마를 사용하여 MySQL 데이터베이스를 초기화하는 방법은 무엇입니까?

MySQL 데이터베이스가있는 컨테이너를 만들고이 데이터베이스에 스키마를 추가하려고합니다.

내 현재 Dockerfile은 다음과 같습니다.

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에 제공된 설명서를 따르고이 명령을 실행합니다.

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

그러나이 명령을 실행하면 컨테이너가 생성되지 않고 컨테이너 상태에서 CMD가 성공적으로 실행되지 않았으며 실제로 mysql명령 만 실행되는 것을 볼 수 있습니다.

어쨌든 스키마를 사용하여 데이터베이스를 초기화하는 방법이 있습니까? 아니면 이러한 작업을 수동으로 수행해야합니까?



답변

이 매우 긴 답변에 대해 유감스럽게 생각하지만 원하는 곳으로 갈 수있는 약간의 방법이 있습니다. 필자는 일반적으로 데이터베이스 자체와 동일한 컨테이너에 데이터베이스 스토리지를 저장하지 않고 데이터를 도커 호스트에 유지하도록 호스트 볼륨을 마운트하거나 컨테이너를 사용하여 데이터를 보유하십시오 (/ var / lib / mysql). 또한, 나는 mysql을 처음 사용하기 때문에 매우 효율적이지 않을 수 있습니다. 그건 …

여기에 몇 가지 문제가 있다고 생각합니다. Dockerfile은 이미지를 만드는 데 사용됩니다. 빌드 단계를 실행해야합니다. 최소한 Dockerfile이 들어있는 디렉토리에서 다음과 같이하십시오.

docker build .

Dockerfile은 만들 이미지를 설명합니다. 나는 mysql에 대해 잘 모른다 (나는 postgres fanboy이다). 그러나 나는 어떻게 mysql docker container를 초기화합니까? 먼저 작업 할 새 디렉토리를 만들고 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 )

다음은 내가 만든 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

마지막으로 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했습니다. 그런 다음 명령을 실행합니다.

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 스크립트의 메시지이며, 첫 번째는 데이터베이스가 저장된 (초기) 버전에서 압축이 풀 렸음을 나타내고, 두 번째는 데이터베이스가 이미 존재 했으므로 기존 사본이 사용되었음을 나타냅니다.

다음은 위에서 설명한 디렉토리 구조의 ls -lR입니다. 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


답변

MySQL Docker 인스턴스의 스키마를 초기화하려는 것과 동일한 문제가 있었지만 일부 인터넷 검색을 수행하고 다른 사람들의 예를 따르면이 작업을 수행하는 데 어려움을 겪었습니다. 내가 해결 한 방법은 다음과 같습니다.

1) MySQL 스키마를 파일로 덤프하십시오.

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

2) ADD 명령을 사용하여 스키마 파일을 /docker-entrypoint-initdb.dDocker 컨테이너 의 디렉토리에 추가하십시오 . docker-entrypoint.sh파일로 끝나는이 디렉토리에있는 파일을 실행합니다 ".sql"MySQL 데이터베이스에 대한.

도커 파일 :

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

docker-entrypoint.sh에 대한 정보와 SQL 및 셸 스크립트를 모두 실행한다는 사실을 알려준 Dockerfile 내에서 MySQL설정하고 덤프를 가져 와서 감사합니다 !


답변

이전에 서버 응답을 병합 한 또 다른 방법은 다음과 같습니다.

도커 작성 파일 :

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알파벳 순서로 실행합니다.


답변

다른 간단한 방법은 다음 줄과 함께 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이 실행됩니다.


답변

나는 성공을 거두지 않은 Greg의 대답을 시도했지만 모든 단계 후에 데이터베이스에 데이터가 없기 때문에 뭔가 잘못했을 것입니다. 만약을 대비하여 MariaDB의 최신 이미지를 사용하고있었습니다.

그런 다음 공식 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"

이제 데이터를 유지하고 내 스키마로 데이터베이스를 생성 할 수 있습니다!


답변

2015 년 8 월 4 일 이후 공식 mysql Docker 이미지를 사용하는 경우 파일을 /docker-entrypoint-initdb.d/ 디렉토리에 ADD / COPY하면 컨테이너가 초기화 된 상태로 실행됩니다. 다른 컨테이너 이미지에서 구현하려면 github : https://github.com/docker-library/mysql/commit/14f165596ea8808dfeb2131f092aabe61c967225를 참조하십시오.


답변

가장 쉬운 해결책은 tutum / mysql 을 사용하는 것입니다

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>