Я хочу создать образ докера поверх образа 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 (в лучших практиках указано «не добавляйте вещи только потому, что они будут хорошо иметь») (я ошибаюсь в этом?)
что может быть хорошим способом сделать это? Я имел в виду несколько вещей, но все они кажутся беспорядочными обходными путями.
Какие-либо предложения? Надеюсь, таким образом, который будет легко поддерживать позже и, возможно, также будет соответствовать лучшим практикам?
Вы должны поместить свой сценарий инициализации в каталог, смонтированный как /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.