【发布时间】:2019-06-18 17:32:20
【问题描述】:
我有一个包含多个子项目的项目,我想为每个子项目提供一个单独的 docker 映像。为了提高效率,我想使用multistage builds,并正在寻找一种最佳实践模式,如何以最有效和最直观的方式完成这项工作。到目前为止,我发现了两种可能性,都有缺点:
多个 Dockerfile 和构建调用
我可以为构建器镜像制作一个 Dockerfile
FROM maven as builder
COPY . /build
WORKDIR /build
RUN mvn -e clean install
并为每个子项目单独的 Dockerfiles
FROM my_builder as builder
FROM openjdk:jre-slim as proj1
COPY --from=builder /build/proj1.jar /somewhere/
CMD ["java", "-jar","/somewhere/proj1.jar"]
这可行,但缺点是我必须分多个步骤构建我的镜像,并且子项目的 Dockerfile 不能自己构建:
docker build -t my_builder .
docker build proj1/
docker build proj2/
使用 docker-compose 文件
我可以通过使用 docker-compose 文件来解决这个问题:
version: "3.4"
services:
builder:
build:
context: ./
proj1:
build:
target: proj1
context: ./proj1
depends_on:
- builder
proj2:
build:
target: proj2
context: ./proj2
depends_on:
- builder
这具有能够使用单个命令运行构建的优势
docker-compose build
但有一个缺点,即为项目中不需要的 docker-compose 创建了一个不需要的和人为的依赖项。
在所有子项目中构建整个项目
我还可以将 buildstage 添加到所有 Dockerfile 中
FROM maven as builder
COPY . /build
WORKDIR /build
RUN mvn -e clean install
FROM openjdk:jre-slim as proj1
COPY --from=builder /build/proj1.jar /somewhere/
CMD ["java", "-jar","/somewhere/proj1.jar"]
这样的好处是我可以自己构建每个项目的容器
docker build proj1/
另一方面,它的效率较低并且违反了 DRY 原则(每个 Dockerfile 的第一部分一遍又一遍地重复)。
最佳实践?
有没有更好的方法来做到这一点?最好是一个可以使用单个 Dockerfile 的?
【问题讨论】:
-
您是否考虑过使用 maven、gradle 或其他构建工具来封装流程?
-
@YuriG. 我做到了。一个简单的 bash 脚本就足够了。但这是一个肮脏的 hack,类似于 docker 引入多阶段构建之前的构建器模式。我真的很想避免这种情况并找到一个干净的 docker-only 解决方案。
-
那么,有什么问题吗?创建一个带有简单错误处理的简单 bash 脚本,在此处发布,社区将给予反馈
标签: docker build docker-compose dockerfile devops