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实际上是存储在代码中的。这给您留下了两个选择。
您可以使用 FROM your_app_image_that_has_the_code_in_it
和 apt-get install mysql ...
而不是 FROM mysql:5.6
。这为您留下了包含 mysql 和您的应用程序的更大图像,允许您 运行 上面的 ruby 命令。您会将 mysql < /mysql/setup/sql
替换为 rails-app bundle exec rake db:create
行。您还必须提供在 localhost:3306
而不是 db:3306
上访问数据库的应用程序配置
我的首选方案是创建一个脚本,将 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
脚本。
这是我第一次与 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实际上是存储在代码中的。这给您留下了两个选择。
您可以使用
FROM your_app_image_that_has_the_code_in_it
和apt-get install mysql ...
而不是FROM mysql:5.6
。这为您留下了包含 mysql 和您的应用程序的更大图像,允许您 运行 上面的 ruby 命令。您会将mysql < /mysql/setup/sql
替换为rails-app bundle exec rake db:create
行。您还必须提供在localhost:3306
而不是db:3306
上访问数据库的应用程序配置
我的首选方案是创建一个脚本,将 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
脚本。