在Dockerfile中设置MySQL并导入转储

我试图为我的LAMP项目设置一个Dockerfile,但是在启动MySQL时遇到一些问题。 我有我的Dockerfile上的以下行:

VOLUME ["/etc/mysql", "/var/lib/mysql"] ADD dump.sql /tmp/dump.sql RUN /usr/bin/mysqld_safe & sleep 5s RUN mysql -u root -e "CREATE DATABASE mydb" RUN mysql -u root mydb < /tmp/dump.sql 

但是我一直得到这个错误:

 ERROR 2002 (HY000): Can't connect to local MySQL server through socket '/var/run/mysqld/mysqld.sock' (111) 

有关如何在Dockerfile构build过程中设置数据库创build和转储导入的任何想法?

Dockerfile每个RUN指令都在不同的层中执行(如RUN文档中所述)。

在你的Dockerfile ,你有三条RUN指令。 问题是MySQL服务器只在第一个启动。 在其他的,没有MySQL正在运行,这就是为什么你的连接错误与mysql客户端。

要解决这个问题,你有两个解决scheme。

解决scheme1:使用单线RUN

 RUN /bin/bash -c "/usr/bin/mysqld_safe --skip-grant-tables &" && \ sleep 5 && \ mysql -u root -e "CREATE DATABASE mydb" && \ mysql -u root mydb < /tmp/dump.sql 

解决scheme2:使用脚本

创build一个可执行的脚本init_db.sh

 #!/bin/bash /usr/bin/mysqld_safe --skip-grant-tables & sleep 5 mysql -u root -e "CREATE DATABASE mydb" mysql -u root mydb < /tmp/dump.sql 

将这些行添加到您的Dockerfile

 ADD init_db.sh /tmp/init_db.sh RUN /tmp/init_db.sh 

官方mysql docker镜像的最新版本允许你在启动时导入数据。 这是我的docker-compose.yml

 data: build: docker/data/. mysql: image: mysql ports: - "3307:3306" environment: MYSQL_ROOT_PASSWORD: 1234 volumes: - ./docker/data:/docker-entrypoint-initdb.d volumes_from: - data 

在这里,我有docker docker/data下的data-dump.sql,它和docker-compose运行的文件夹相关。 我将这个sql文件/docker-entrypoint-initdb.d到容器上的这个目录/docker-entrypoint-initdb.d

如果你有兴趣看看它是如何工作的,可以看一下他们在GitHub中的docker-entrypoint.sh 。 他们已经添加了这个块来允许导入数据

  echo for f in /docker-entrypoint-initdb.d/*; do case "$f" in *.sh) echo "$0: running $f"; . "$f" ;; *.sql) echo "$0: running $f"; "${mysql[@]}" < "$f" && echo ;; *) echo "$0: ignoring $f" ;; esac echo done 

另外需要注意的是,如果你希望数据在mysql容器被停止和删除之后仍然被保存,你需要有一个单独的数据容器,就像你在docker-compose.yml中看到的那样。 数据容器Dockerfile的内容非常简单。

 FROM n3ziniuka5/ubuntu-oracle-jdk:14.04-JDK8 VOLUME /var/lib/mysql CMD ["true"] 

数据容器甚至不必处于持久性的启动状态。

我所做的是将我的SQL转储下载到“db-dump”文件夹中,然后装载它:

 mysql: image: mysql:5.6 environment: MYSQL_ROOT_PASSWORD: pass ports: - 3306:3306 volumes: - ./db-dump:/docker-entrypoint-initdb.d 

当我第一次运行docker-compose up时,转储在db中被恢复。

我用docker-entrypoint-initdb.d方法(感谢@Kuhess)但是在我的情况下,我想根据我在.env文件中定义的一些参数来创build我的数据库,所以我做了这些

1)首先,我在docker root project目录下定义.env文件

 MYSQL_DATABASE=my_db_name MYSQL_USER=user_test MYSQL_PASSWORD=test MYSQL_ROOT_PASSWORD=test MYSQL_PORT=3306 

2)然后我定义我的docker-compose.yml文件。 所以我使用args指令来定义我的环境variables,并从.env文件中设置它们

 version: '2' services: ### MySQL Container mysql: build: context: ./mysql args: - MYSQL_DATABASE=${MYSQL_DATABASE} - MYSQL_USER=${MYSQL_USER} - MYSQL_PASSWORD=${MYSQL_PASSWORD} - MYSQL_ROOT_PASSWORD=${MYSQL_ROOT_PASSWORD} ports: - "${MYSQL_PORT}:3306" 

3)然后我定义一个包含Dockerfile的mysql文件夹。 所以Dockerfile是这样的

 FROM mysql:5.7 RUN chown -R mysql:root /var/lib/mysql/ ARG MYSQL_DATABASE ARG MYSQL_USER ARG MYSQL_PASSWORD ARG MYSQL_ROOT_PASSWORD ENV MYSQL_DATABASE=$MYSQL_DATABASE ENV MYSQL_USER=$MYSQL_USER ENV MYSQL_PASSWORD=$MYSQL_PASSWORD ENV MYSQL_ROOT_PASSWORD=$MYSQL_ROOT_PASSWORD ADD data.sql /etc/mysql/data.sql RUN sed -i 's/MYSQL_DATABASE/'$MYSQL_DATABASE'/g' /etc/mysql/data.sql RUN cp /etc/mysql/data.sql /docker-entrypoint-initdb.d EXPOSE 3306 

4)现在我使用mysqldump转储我的数据库,并把data.sql里面的MySQL文件夹

 mysqldump -h <server name> -u<user> -p <db name> > data.sql 

该文件只是一个正常的SQL转储文件,但我在开始时添加2行,所以文件看起来像这样

 -- -- Create a database using `MYSQL_DATABASE` placeholder -- CREATE DATABASE IF NOT EXISTS `MYSQL_DATABASE`; USE `MYSQL_DATABASE`; -- Rest of queries DROP TABLE IF EXISTS `x`; CREATE TABLE `x` (..) LOCK TABLES `x` WRITE; INSERT INTO `x` VALUES ...; ... ... ... 

所以发生什么事情是我用“运行sed -i's / MYSQL_DATABASE /'$ MYSQL_DATABASE'/ g'/etc/mysql/data.sql”命令来replaceMYSQL_DATABASE占位符与我已经设置了它的数据库的名称在.env文件中。

 |- docker-compose.yml |- .env |- mysql |- Dockerfile |- data.sql 

现在您已经准备好构build并运行您的容器

您也可以看看docker-compose的服务:

https://docs.docker.com/compose/wordpress/#build-the-project

与此同时,MySQL可以附加到您的应用程序