这是我第一次使用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
如果您愿意,也可以用第二个compose文件替换docker run
脚本。