Как создать инициализированный образ MySQL Docker?

0

Использование образа Docker mysql:5.7.21 Я хочу создать новое изображение, основанное на нем, которое уже будет инициализировано базой данных. (Я хочу использовать это для моей среды принятия).

Я знаю о /docker-entrypoint-initdb.d и я мог бы сделать следующее:

FROM mysql:5.7.21

COPY ./init /docker-entrypoint-initdb.d

Но проблема в том, что он будет копировать только файлы tar/sql, но он не будет выполняться до первого запуска. Другим недостатком является также размер изображения. Если вы копируете, например, 200 МБ данных внутри контейнера, то эти файлы будут оставаться на изображении (в виде слоя).

Поэтому мне было интересно, есть ли какая-то комбинация, о которой я не думал, с многоэтапным или новым --squash флагом (который позволит, добавлять файлы, выполнять файлы, удалять файлы).

В моем поиске этой проблемы я также нашел о --datadir. Не знаю, как это могло бы помочь.

редактировать:

Пока у меня есть пара:

FROM mysql:5.7.21 as builder

ENV MYSQL_ALLOW_EMPTY_PASSWORD yes
ENV MYSQL_DATABASE example

COPY ./init /docker-entrypoint-initdb.d

RUN head -n-2 < /usr/local/bin/docker-entrypoint.sh > /usr/local/bin/docker-entrypoint.sh \
    && docker-entrypoint.sh mysqld \
    && /etc/init.d/mysql start \
    && mysql -uroot -e 'FLUSH TABLES;' \
    && mysql -uroot -e 'show tables;' mysql \
    && mysql -uroot -e 'show tables;' example \
    && /etc/init.d/mysql stop \
    # This shows the files!
    && ls -la /var/lib/mysql

# This shows no files?!!
RUN ls -la /var/lib/mysql

FROM mysql:5.7.21

ENV MYSQL_ALLOW_EMPTY_PASSWORD yes
ENV MYSQL_DATABASE example

COPY --from=builder /var/lib/mysql /var/lib/mysql
RUN ls -la 

RUN ls -la /var/lib/mysql \
    && /etc/init.d/mysql start \
    && mysql -uroot -e 'show tables;' mysql \
    && mysql -uroot -e 'show tables;' example

См. Приведенные выше встроенные комментарии... что-то действительно странное происходит? Итак, в том же RUN, когда я выполняю ls -la on /var/lib/mysql я могу видеть файлы. Но в новом слое (новый RUN) он пуст: S

  • 0
    Вы хотите, чтобы контейнер сохранял данные в самом контейнере? Обычно для данных используют объем.
  • 0
    Да, я хочу хранить данные в контейнере самостоятельно. (В этом случае это всего лишь 10 МБ, но в будущем это может увеличиться). Он будет развернут в среде Docker Swarm, и я хочу сделать это как можно проще (без настройки постоянных томов).
Теги:
docker
image
containers
continuous-integration

2 ответа

0

Поэтому я нашел решение !!! Моя проблема заключалась в том, что /var/lib/mysql является томом: https://github.com/docker-library/mysql/blob/ad625c64a06e16683e997e5a0147508d115f4989/5.7/Dockerfile#L71

Рабочий многоступенчатый файл докеров:

FROM mysql:5.7.21 as builder

ENV MYSQL_ALLOW_EMPTY_PASSWORD yes
ENV MYSQL_DATABASE example

COPY ./init /docker-entrypoint-initdb.d

RUN head -n-2 < /usr/local/bin/docker-entrypoint.sh > /usr/local/bin/docker-entrypoint.sh
RUN mkdir -p /var/lib/mysql_tmp
RUN docker-entrypoint.sh mysqld --datadir /var/lib/mysql_tmp

FROM mysql:5.7.21

ENV MYSQL_ALLOW_EMPTY_PASSWORD yes
ENV MYSQL_DATABASE example

COPY --from=builder /var/lib/mysql_tmp /var/lib/mysql_tmp

CMD ["mysqld", "--datadir", "/var/lib/mysql_tmp"]

Итак, что мы здесь делаем, обязательно удалите последние 2 строки (можно было бы изменить, чтобы удалить только последнюю строку), поскольку в нем содержится exec "$@" который в основном означает exec msqld. Это MySQL deamon и поэтому он застрянет там.

Далее я изменил datadir из var/lib/mysql (который является томом) в var/lib/mysql_tmp (из-за отсутствия лучшего имени).

На последнем этапе я var/lib/mysql_tmp и удостоверяюсь, что mysqld использует этот var/lib/mysql_tmp.

Теперь я могу испечь (для меня только для чтения) db для моего принятия env.

0

Если вы проверите Dockerfile для изображения mysql:5.7.21 (https://hub.docker.com/r/library/mysql/), вы увидите, что для точки входа установлено значение ["docker-entrypoint.sh"], поэтому это первая команда, которая выполняется при запуске изображения.

Если вы хотите выполнить его во время создания изображения (таким образом, делая размер изображения огромным, но хорошо), вам просто нужно поместить его в свой файл Docker:

RUN docker-entrypoint.sh /bin/true

Эта точка входа выполнит сценарии, найденные в /docker-entrypoint-initdb.d но, как вы хорошо заметили, сценарии также занимают место. Чтобы отбросить файлы, вы можете использовать многоэтапную сборку, чтобы просто скопировать необработанную базу данных.

Еще раз проверьте файл Docker, чтобы увидеть, что единственный том на изображении - /var/lib/mysql. Предполагается, что это каталог, содержащий всю информацию о базе данных, и это должно быть то, что вы копируете. Результат выглядит примерно так:

FROM mysql:5.7.21 as base

COPY ./init /docker-entrypoint-initdb.d
RUN docker-entrypoint.sh /bin/true

FROM mysql:5.7.21

COPY --from=base /var/lib/mysql /var/lib/mysql

Все это сказало, я бы не рекомендовал создавать "инициализированные" изображения, поскольку это несколько противоречит духу использования контейнеров, но этот другой вопрос;)

  • 0
    Вы пробовали это? Потому что я даже раньше не задавал этот вопрос ... Он застрянет из-за последней команды exec. Я даже использовал tail, чтобы удалить последние 2 строки, но каталог как-то остался пустым.
  • 0
    Вы правы, вы должны добавить что-то в docker-entrypoint.sh, например: RUN docker-entrypoint.sh / bin / true
Показать ещё 1 комментарий

Ещё вопросы

Сообщество Overcoder
Наверх
Меню