Створення контейнера докер-mysql з підготовленою схемою бази даних


17

Я хочу створити зображення докера поверх файлу mysql, який вже містить необхідну схему для мого додатка.

Я спробував додати рядки до Dockerfile, які імпортують мою схему як файл sql. Я зробив так (мій Dockerfile):

FROM mysql

ENV MYSQL_ROOT_PASSWORD="bagabu"
ENV MYSQL_DATABASE="imhere"

ADD imhere.sql /tmp/imhere.sql

RUN "mysql -u root --password="bagabu" imhere < /tmp/imhere.sql"

Наскільки я розумію, це не спрацювало, тому що зображення докера mysql не містить клієнта mysql (найкращі практики показують, що "не додавати речі тільки тому, що їх буде приємно мати") (я помиляюся з цього приводу?)

який може бути хороший спосіб зробити це? Я мав на увазі кілька речей, але всі вони здаються безладним способом обходу.

  1. встановіть клієнт mysql, виконайте все, що я маю з ним, а потім видаліть / очистіть.
  2. скопіюйте бінарний клієнт mysql на зображення, зробіть те, що мені потрібно зробити, а потім видаліть його.
  3. Створіть схему на іншому сервері sql та самі скопіюйте файл db (це здається дуже безладним і звучить мені як заражений пул проблем)

Будь-які пропозиції? Сподіваємось, таким чином, який буде легко підтримувати пізніше і, можливо, відповідатиме найкращим практикам?


Відповіді:


14

Ви повинні помістити свій скрипт init у каталог, встановлений як /docker-entrypoint-initdb.d- див. Розділ "Ініціалізація нового екземпляра" в документах зображень MySQL Docker .


2
Це працює для виведення свіжого контейнера та завантаження його моєю схемою. Який приємний спосіб її вирішити, але що робити, якщо я шукаю спосіб створити власне зображення докера, у якому вже встановлена ​​схема?
Том Клино

Насправді, не маю на увазі :-) Я думав, що /docker-entrypoint-initdb.dце в хості, але він є насправді в контейнері. Я змінив ADDкоманду для копіювання в цей каталог і видалив RUNкоманду. Докер успішно створив зображення, і я його протестував, і він працює.
Том Клино

14

Мені довелося це робити для цілей тестування.

Ось як я це зробив, використовуючи фактичні зображення MySQL / MariaDB на dockerhub та багатоступеневій збірці:

FROM mariadb:latest as builder

# That file does the DB initialization but also runs mysql daemon, by removing the last line it will only init
RUN ["sed", "-i", "s/exec \"$@\"/echo \"not running $@\"/", "/usr/local/bin/docker-entrypoint.sh"]

# needed for intialization
ENV MYSQL_ROOT_PASSWORD=root

COPY setup.sql /docker-entrypoint-initdb.d/

# Need to change the datadir to something else that /var/lib/mysql because the parent docker file defines it as a volume.
# https://docs.docker.com/engine/reference/builder/#volume :
#       Changing the volume from within the Dockerfile: If any build steps change the data within the volume after
#       it has been declared, those changes will be discarded.
RUN ["/usr/local/bin/docker-entrypoint.sh", "mysqld", "--datadir", "/initialized-db", "--aria-log-dir-path", "/initialized-db"]

FROM mariadb:latest

COPY --from=builder /initialized-db /var/lib/mysql

Повний робочий приклад тут: https://github.com/lindycoder/prepopulated-mysql-container-example


2
найкраща відповідь, яку я знайшов у всьому Інтернеті, моя була для постгресів, тому це було трохи складніше, але, нарешті, це спрацювало. І це прекрасно працює!
snowe2010

Старіші версії mysql (5.7.9) не мають /usr/local/bin/docker-entrypoint.sh, які посилаються на /entrypoint.sh, а просто містять entrypoint.sh в /. Зміна /usr/local/bin/docker-entrypoint.sh на /entrypoint.sh працює, і, імовірно, має працювати і для "сучасних" версій.
Марвін

2

Кредити @Martin Roy

Внесені незначні зміни для роботи з mysql ...

Зміст Dockerfile

FROM mysql:latest as builder

# That file does the DB initialization but also runs mysql daemon, by removing the last line it will only init
RUN ["sed", "-i", "s/exec \"$@\"/echo \"not running $@\"/", "/usr/local/bin/docker-entrypoint.sh"]

# needed for intialization
ENV MYSQL_ROOT_PASSWORD=root

COPY setup.sql /docker-entrypoint-initdb.d/

# Need to change the datadir to something else that /var/lib/mysql because the parent docker file defines it as a volume.
# https://docs.docker.com/engine/reference/builder/#volume :
#       Changing the volume from within the Dockerfile: If any build steps change the data within the volume after
#       it has been declared, those changes will be discarded.
RUN ["/usr/local/bin/docker-entrypoint.sh", "mysqld", "--datadir", "/initialized-db"]

FROM mysql:latest

COPY --from=builder /initialized-db /var/lib/mysql

Налаштування вмісту .sql

CREATE DATABASE myexample;

USE myexample;

CREATE TABLE mytable (myfield VARCHAR(20));

INSERT INTO mytable VALUES ('Hello'), ('Dolly');

Повний робочий приклад тут: https://github.com/iamdvr/prepopulated-mysql-container-example


-1

Програмне забезпечення для управління, як Ansible, може допомогти вам легко автоматизувати імпорт mysql без необхідності встановлення та перевстановлення клієнта. Ansible має чудові вбудовані функції для управління зображеннями докерів та контейнерами та базами даних mysql.


Це цікаво - я використовував Ansible, але не використовував його для зображень Docker. Можете поширити свою відповідь якимись прикладами, Патріку?
Грег Дубіцький

У Ansible є чудова сторінка документів, ви можете знайти модуль Ansible на цій URL- адресі : docs.ansible.com/ansible/docker_module.html На кожній сторінці розділу модуля цього посібника наведено кілька прикладів.
Патрік
Використовуючи наш веб-сайт, ви визнаєте, що прочитали та зрозуміли наші Політику щодо файлів cookie та Політику конфіденційності.
Licensed under cc by-sa 3.0 with attribution required.