Моя цель - создать образ Docker, который включает в себя MySQL, предварительно заполненный таблицами и данными, полученными с помощью миграции Alembic. К сожалению, Alembic не может создавать необходимые данные без активного экземпляра MySQL и не может самостоятельно создать SQL-дамп, который будет загружен MySQL при первом запуске.
Я попытался использовать многоэтапные сборки, чтобы использовать для них как контейнеры mysql
и python
, но демон MySQL снова сбрасывается, как только начинается этап Python.
# start MySQL daemon
FROM mysql:5.6
RUN docker-entrypoint.sh
# install and run Alembic
FROM python:2.7-alpine
# [install Alembic]
COPY ./alembic-migrations /alembic-migrations
# [run migrations]
Я не зависел от этого конкретного решения, но это казалось самым простым вариантом. Есть ли способ сделать то, что я пытаюсь? Должен ли я отказаться от установки Python и Alembic в контейнере MySQL?
Вероятно, у некоторых глаз евангелиста Докера истекают кровью, но именно так я смог выполнить поведение, которое я искал. Это было на самом деле проще и работает быстрее, чем я ожидал.
FROM python:2.7-alpine as python
FROM mysql:5.6
# set up a functional chroot of the Python image at /python
COPY --from=python / /python
RUN set -ex; \
cp /etc/resolv.conf /python/etc/resolv.conf; \
mknod -m 0644 /python/dev/random c 1 8; \
mknod -m 0644 /python/dev/urandom c 1 9;
# install software depedencies in chroot jail
RUN set -ex; \
chroot /python apk --no-cache --virtual add [some dependencies]
# install Python libraries
COPY ./requirements.txt /python/tmp/requirements.txt
RUN chroot /python pip install -r /tmp/requirements.txt;
# apply Alembic migrations and remove the Python chroot jail
COPY ./usr/local/bin/build.sh /usr/local/bin/
COPY ./alembic /python/alembic
RUN build.sh && rm -rf /python;
ENTRYPOINT ["docker-entrypoint.sh", "--datadir=/var/lib/mysql-persist"]
EXPOSE 3306
CMD ["mysqld"]
Сценарий build.sh
просто docker-entrypoint.sh
скрипт docker-entrypoint.sh
из контейнера MySQL, а затем вызывает код, зависящий от Alembic, в chroot Python.
#!/bin/sh
docker-entrypoint.sh --datadir=/var/lib/mysql-persist 2>/dev/null &
chroot /python build.sh
Обратите внимание, что я настраиваю пользовательский каталог данных (/var/lib/mysql-persist
), потому что верхний контейнер mysql определяет VOLUME/var/lib/mysql
, который я не могу переопределить.
Результатом является построенное изображение, которое содержит MySQL, в комплекте с базой данных, но не содержит никаких следов контейнера Python или скриптов Alembic. Теперь он может быть распространен через реестр и получен с помощью docker-compose
, избегая необходимости для всех пользователей выполнять миграции Alembic самостоятельно.
docker-compose
для этой цели, но он медленный, потому что ему нужно постоянно перезапускать Alembic на каждом компьютере разработчика, в каждой среде, каждый раз, когда кто-то переключает ветки. Мы хотим создать образ, который можно распространять через реестр со всеми уже созданными базами данных разработки / тестирования. Если есть способ сделать это с помощьюdocker-compose
, я хотел бы услышать об этом.