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

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/37465864/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me): StackOverFlow

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-08-31 21:50:38  来源:igfitidea点击:

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

mysqlruby-on-railsdocker-composedockerfile

提问by Fran Martinez

It's my first time working with Docker an I am not sure if I am doing things well.

这是我第一次使用 Docker,我不确定我是否做得很好。

I have a rails applications that depends on a Mysqldatabase, so I've configured the docker-compose.ymlfile like this:

我有一个依赖于Mysql数据库的 rails 应用程序,所以我配置了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 ...

Then, if I run the following:

然后,如果我运行以下命令:

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

I get this error:

我收到此错误:

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

This sounds normal, because I suspect that I have to buildbefore some container that links to db.

这听起来很正常,因为我怀疑我必须build在链接到db.

I know this because if I run this in this order:

我知道这一点,因为如果我按以下顺序运行:

$ 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

It works fine.

它工作正常。

But, how can I do to execute this sql before creating any container?

但是,如何在创建任何容器之前执行此 sql?

采纳答案by dnephin

You can load the sql file during the buildphase of the image. To do this you create a Dockerfilefor the dbservice that will look something like this:

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

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

where setup.shlooks something like this:

哪里setup.sh看起来像这样:

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

And in your docker-compose.ymlyou'd change imageto build: ./dbor the path where you put your files.

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

Now this works if you have all your sql in a raw .sqlfile, but this wont be the case if you're using rails or a similar framework where the sql is actually stored in code. This leaves you with two options.

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

  1. Instead of using FROM mysql:5.6you can use FROM your_app_image_that_has_the_code_in_itand apt-get install mysql .... This leaves you with a larger image that contains both mysql and your app, allowing you to run the ruby commands above. You'd replace the mysql < /mysql/setup/sqlwith the rails-app bundle exec rake db:createlines. You'd also have to provide an app config that hits a database on localhost:3306instead of db:3306

  2. My preferred option is to create a script which exports the sql into a .sqlfile, which you can then use to build your database container. This is a bit more work, but is a lot nicer. It means that instead of running rails-app bundle exec rake db:createyou'd just run the script to load a db.

  1. FROM mysql:5.6您可以使用FROM your_app_image_that_has_the_code_in_itand代替使用apt-get install mysql ...。这将为您留下一个更大的图像,其中包含 mysql 和您的应用程序,允许您运行上面的 ruby​​ 命令。你会更换mysql < /mysql/setup/sqlrails-app bundle exec rake db:create线条。您还必须提供一个应用程序配置来访问数据库localhost:3306而不是db:3306

  2. 我的首选选项是创建一个脚本,将 sql 导出到一个.sql文件中,然后您可以使用该文件来构建您的数据库容器。这是一个多一点的工作,但好多了。这意味着rails-app bundle exec rake db:create您只需运行脚本来加载数据库,而不是运行。

Such a script would look something like this:

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

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

where export.shlooks something like this:

哪里export.sh看起来像这样:

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

You could also replace the docker runscript with a second compose file if you wanted to.

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