Docker:构建依赖于另一个图像的图像 运行
Docker: Building an image that depends on another image to be running
我的 objective 是构建一个 Docker 图像,其中包含 MySQL 预填充了 Alembic 迁移生成的表和数据。不幸的是,如果没有活动的 MySQL 实例,Alembic 无法生成必要的数据,也无法独立创建 SQL 转储为 loaded by MySQL on first run.
我已经尝试使用 multi-stage builds 来同时使用 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]
我不喜欢这个特定的解决方案,但它似乎是最简单的选择。有没有办法做我正在尝试的事情?我应该辞职在 MySQL 容器中安装 Python 和 Alembic 吗?
它可能会让一些 Docker 传播者的眼睛流血,但这就是我能够实现我正在寻找的行为的方式。它实际上比我预期的更简单并且运行速度更快。
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
脚本只是从 MySQL 容器中派生出 docker-entrypoint.sh
脚本,然后在 Python chroot 中调用 Alembic-specific 代码。
#!/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 迁移的需要。
我的 objective 是构建一个 Docker 图像,其中包含 MySQL 预填充了 Alembic 迁移生成的表和数据。不幸的是,如果没有活动的 MySQL 实例,Alembic 无法生成必要的数据,也无法独立创建 SQL 转储为 loaded by MySQL on first run.
我已经尝试使用 multi-stage builds 来同时使用 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]
我不喜欢这个特定的解决方案,但它似乎是最简单的选择。有没有办法做我正在尝试的事情?我应该辞职在 MySQL 容器中安装 Python 和 Alembic 吗?
它可能会让一些 Docker 传播者的眼睛流血,但这就是我能够实现我正在寻找的行为的方式。它实际上比我预期的更简单并且运行速度更快。
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
脚本只是从 MySQL 容器中派生出 docker-entrypoint.sh
脚本,然后在 Python chroot 中调用 Alembic-specific 代码。
#!/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 迁移的需要。