Назад | Перейти на главную страницу

Создание контейнера docker mysql с подготовленной схемой базы данных

Я хочу создать образ докера поверх образа 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 (это кажется очень беспорядочным и звучит для меня как зараженный пул проблем)

Какие-либо предложения? Надеюсь, таким образом, который будет легко поддерживать позже и, возможно, также будет соответствовать лучшим практикам?

Вы должны поместить свой сценарий инициализации в каталог, смонтированный как /docker-entrypoint-initdb.d - см. раздел «Инициализация нового экземпляра» в Документы образов MySQL Docker.

Пришлось сделать это в тестовых целях.

Вот как я это сделал, используя фактические образы 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

Кредиты @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

Содержимое setup.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

Вот мой файл докеров работает абсолютно нормально. / sql-scripts / будет содержать ваш настраиваемый файл sql (содержащий вашу подготовленную базу данных), который выполняется после запуска контейнера. Однако вы можете посмотреть монтаж тома.

FROM mysql:5.6
COPY ./sql-scripts/ /docker-entrypoint-initdb.d/

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