Подтвердить что ты не робот

Докер, как запустить .sql файл в изображении?

Это моя первая работа с Докером, и я не уверен, что я хорошо делаю.

У меня есть приложения 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 перед созданием любого контейнера?

4b9b3361

Ответ 1

Вы можете загрузить файл sql во время фазы build изображения. Для этого вы создаете Dockerfile для службы db, которая будет выглядеть примерно так:

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, но это не так, если вы используете рельсы или аналогичную структуру, где sql фактически хранится в коде. Это оставляет вам два варианта.

  • Вместо использования FROM mysql:5.6 вы можете использовать FROM your_app_image_that_has_the_code_in_it и apt-get install mysql .... Это дает вам более крупное изображение, содержащее как mysql, так и ваше приложение, позволяющее запускать рубиновые команды выше. Вы заменили бы mysql < /mysql/setup/sql на строки rails-app bundle exec rake db:create. Вам также необходимо предоставить конфигурацию приложения, которая попадает в базу данных на localhost:3306 вместо db:3306

  • Мой предпочтительный вариант - создать script, который экспортирует sql в файл .sql, который затем можно использовать для создания контейнера базы данных. Это немного больше работы, но намного приятнее. Это означает, что вместо запуска rails-app bundle exec rake db:create вы просто запустите script, чтобы загрузить db.

Такой script будет выглядеть примерно так:

#!/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 script на второй файл компоновки, если хотите.