Как инициализировать базу данных MySql в Docker Compose - PullRequest
0 голосов
/ 01 февраля 2019

Сценарий: Я разработал микросервис в Spring, который использует базу данных mysql 8.Эта база данных должна быть инициализирована (создать базу данных, несколько таблиц и данных).На моей хост-машине я инициализировал базу данных с помощью data.sql и schema.sql script.Проблема в том, что я должен установить:

spring.datasource.initialization-mode=always

для первого выполнения.Это инициализирует мою базу данных так, как я хочу.Для будущих запусков я должен прокомментировать эту команду.Очень уродливое решение, но я не смог найти лучшего, и я сейчас не получил ответа на этот вопрос .Я думал, что для тестирования это нормально, но я определенно должен улучшить это.В настоящее время я хочу запустить свой сервис с помощью docker с помощью docker compose.

Ожидается: Это файл docker-compose.Довольно простой.Я совершенно новичок в мире докеров и поэтому хочу идти шаг за шагом.

version: '3' 
services:usermanagement-service:
build:
  ./UserManagementService
restart:
  on-failure
ports:
  - "7778:7778"
links:
  - mysqldb
depends_on:
  - mysqldb   mysqldb:
build:
  ./CustomMySql
volumes:
  - ./mysql-data:/var/lib/mysql
restart:
  on-failure
environment:
  MYSQL_ROOT_PASSWORD: root
  MYSQL_DATABASE: userdb
  MYSQL_USER: testuser
  MYSQL_PASSWORD: testuser
expose:
  - "3600"

Я ожидал, что моя база данных будет инициализирована с пользователем, и этопри первом запуске мой микросервис инициализирует базу данных данными.Поэтому перед следующим началом создания я должен прокомментировать команду и перестроить образ.(Я знаю, некрасиво)

Проблема: Так что кроме этого уродливого решения я сталкиваюсь с проблемами во время выполнения.На docker-compose up мой микросервис работает быстрее, чем инициализация базы данных.Поэтому он пытается вызвать БД, что приводит к ошибке en.Из-за restart on failure микросервис снова появляется.Теперь он работает, потому что инициализация базы данных завершена.

Решение: Я искал www, и кажется, что это известная проблема, которая может быть решена в файле wait-for-it.sh.Это должно быть включено в COPY в Dockerfile.Так что я не эксперт, но я ищу хорошее решение:

  • init database изнутри spring и заставьте мой сервис ждать, пока mysql будет готов
  • , или init the databaseиз моего контейнера через том при первом запуске и, конечно, решить эту проблему инициализации.

Я не знаю, что здесь лучше всего делать, и я был бы очень благодарен за некоторую помощь, какпостроить это.

1 Ответ

0 голосов
/ 01 февраля 2019

Для загрузки файлов sql только при первом запуске:

Вы можете использовать приведенный ниже файл компоновки

services:

  usermanagement-service:
    build: ./UserManagementService
    restart: on-failure
    ports:
      - "7778:7778"
    depends_on:
      mysqldb:
        condition: service_healthy

  mysqldb:
    image: mysql
    volumes:
      - ./mysql-data:/var/lib/mysql
      - ./mysql-init-files:/docker-entrypoint-initdb.d
    restart: always
    environment:
      MYSQL_ROOT_PASSWORD: root
      MYSQL_DATABASE: userdb
      MYSQL_USER: testuser
      MYSQL_PASSWORD: testuser
    ports:
      - "3600:3306"
    healthcheck:
      test: ["CMD", "mysqladmin" ,"ping", "-h", "localhost"]
      timeout: 20s
      retries: 10

Вы должны разместить свой data.sqlи schema.sql файлы в каталоге ./docker-entrypoint-initdb.d с использованием Volumes для получения дополнительной информации .

Файлы SQL в этой папке будут загружены, только если каталог данных DB пуст (самый первый запуск службы db) .(т.е.) в вашем случае папка ./mysql-data должна быть пустой

Для вашей второй проблемы:

Вместо использования wait-for-it.sh, вы можете использовать healthcheck иservice_healthy.Здесь usermanagement-service будет запущен, как только mysqldb успешно выполнит ["CMD", "mysqladmin" ,"ping", "-h", "localhost"] в указанный интервал.Для получения более подробной информации о проверке работоспособности и зависимости от нее см. здесь .

Получил test команду из здесь .

...