Docker,如何运行 .sql 文件中的图像?

Docker, how to run .sql file in an image?

这是我第一次与 Docker 合作,我不确定我是否做得很好。

我有一个 rails 应用程序依赖于 Mysql 数据库,所以我配置了 docker-compose.yml 文件,如下所示:

db:
  image: library/mysql:5.6
  environment:
    MYSQL_ALLOW_EMPTY_PASSWORD: "yes"
  expose:
    - "3306"
  ports:
    - "3306:3306"

rails-app:
  build: .
  dockerfile: Dockerfile
  environment:
    RAILS_ENV: development
  links:
    - db
  volumes:
    - ".:/home/app"
  volumes_from:
    - bundle

  ... omitted lines ...

然后,如果我 运行 以下内容:

$ docker-compose run db mysql --host=$DOCKER_LOCALHOST --port=3306 --protocol=tcp -u root < shared/create_common_tables.sql

我收到这个错误:

ERROR 2003 (HY000): Can't connect to MySQL server on '192.168.99.100' (111)

这听起来很正常,因为我怀疑我必须在某些链接到 db 的容器之前 build

我知道这个,因为如果我 运行 这个顺序:

$ docker-compose build rails-app
$ docker-compose run -e RAILS_ENV=development rails-app bundle
$ docker-compose run -e RAILS_ENV=development rails-app bundle exec rake db:create
$ docker-compose run db mysql --host=$DOCKER_LOCALHOST --port=3306 --protocol=tcp -u root < shared/create_common_tables.sql

它工作正常。

但是,我怎样才能在创建任何容器之前执行此 sql?

您可以在图像的 build 阶段加载 sql 文件。为此,您为 db 服务创建一个 Dockerfile,它看起来像这样:

FROM mysql:5.6
COPY setup.sh /mysql/setup.sh
COPY setup.sql /mysql/setup.sql
RUN /mysql/setup.sh

其中 setup.sh 看起来像这样:

#!/bin/bash
set -e
service mysql start
mysql < /mysql/setup.sql
service mysql stop

然后在您的 docker-compose.yml 中,您将 image 更改为 build: ./db 或您放置文件的路径。

现在,如果您将所有 sql 都放在原始 .sql 文件中,则此方法有效,但如果您使用的是 rails 或类似的框架,则情况并非如此sql实际上是存储在代码中的。这给您留下了两个选择。

  1. 您可以使用 FROM your_app_image_that_has_the_code_in_itapt-get install mysql ... 而不是 FROM mysql:5.6。这为您留下了包含 mysql 和您的应用程序的更大图像,允许您 运行 上面的 ruby 命令。您会将 mysql < /mysql/setup/sql 替换为 rails-app bundle exec rake db:create 行。您还必须提供在 localhost:3306 而不是 db:3306

  2. 上访问数据库的应用程序配置
  3. 我的首选方案是创建一个脚本,将 sql 导出到 .sql 文件中,然后您可以使用它来构建数据库容器。这是更多的工作,但更好。这意味着您只需 运行 脚本来加载数据库,而不是 运行 宁 rails-app bundle exec rake db:create

这样的脚本看起来像这样:

#!/bin/bash
set -e
docker-compose build rails-app
docker run -d --name mysql_empty mysql:5.6
docker run --link mysql_empty:db -v $PWD:/output project_rails-app export.sh

其中 export.sh 看起来像这样:

#!/bin/bash
set -e
RAILS_ENV=development
rails-app bundle exec rake db:create
mysqldump > /output/setup.sql

如果需要,您也可以用第二个撰写文件替换 docker run 脚本。