我现在有几个Dockerfiles。
一个是Cassandra 3.5,它是 FROM cassandra:3.5
我也有一个用于Kafka的Dockerfile,但是t要复杂得多。它是 FROM java:openjdk-8-fre
它运行一个很长的命令来安装Kafka和Zookeeper。
最后,我有一个用Scala编写的应用程序,它使用SBT。
对于那个Dockerfile,它是 FROM broadinstitute/scala-baseimage
,这让我得到Java 8,Scala 2.11.7和STB 0.13.9,这是我需要的。
也许,我不明白Docker是如何工作的,但我的Scala程序将Cassandra和Kafka作为依赖项并用于开发目的,我希望其他人能够简单地克隆我的repo Dockerfile
然后能够使用Cassandra,Kafka,Scala,Java和SBT构建它,所有这些都可以编译源代码。我虽然遇到了很多问题。
如何组合这些Dockerfiles?我如何简单地制作一个带有烘焙物品的环境?
由于可能发生冲突,您无法组合dockerfiles。您要做的是创建一个新的dockerfile或构建一个自定义图像。
TL; DR;
如果您当前的开发容器包含您需要和工作的所有工具,那么将其保存为图像并将其保存到存储库并创建一个dockerfile以从该存储库中提取该图像。
细节:
构建自定义图像比使用公共图像创建dockerfile要容易得多,因为您可以将任何hacks和mod存储到图像中。为此,启动一个带有基本Linux映像(或broadinstitute / scala-baseimage)的空容器,安装所需的任何工具并配置它们直到一切正常,然后将其(容器)保存为映像。在此图像上创建一个新容器并测试是否可以通过docker-compose构建代码(或者您想要构建/构建它)。如果它有效,那么您可以将工作基础图像上传到回购,以便其他人可以将其拉出来。
要使用公共映像构建dockerfile,您需要在dockerfile本身上放置所有hack,mods和setup。也就是说,您需要将您使用的每个命令行放入文本文件中,并将任何hacks,mods和setup设置为命令行。最后,您的dockerfile将自动创建一个图像,您不需要将此图像存储到仓库中,您只需要为其他人提供dockerfile,他们就可以在自己的docker上旋转图像。
请注意,一旦有了工作的dockerfile,就可以轻松调整它,因为每次使用dockerfile时它都会创建一个新的图像。使用自定义映像时,您可能会遇到因冲突而需要重建映像的问题。例如,您的所有工具都可以使用openjdk,直到您安装一个不起作用的工具。该修复程序可能涉及卸载openjdk并使用oracle one,但是您为所有已安装的工具所做的所有配置都已破坏。
你可以随着 多阶段构建Docker 1.17中引入的功能
看看这个:
FROM golang:1.7.3
WORKDIR /go/src/github.com/alexellis/href-counter/
RUN go get -d -v golang.org/x/net/html
COPY app.go .
RUN CGO_ENABLED=0 GOOS=linux go build -a -installsuffix cgo -o app .
FROM alpine:latest
RUN apk --no-cache add ca-certificates
WORKDIR /root/
COPY --from=0 /go/src/github.com/alexellis/href-counter/app .
CMD ["./app"]
然后正常构建图像:
docker build -t alexellis2/href-counter:latest
来自: https://docs.docker.com/develop/develop-images/multistage-build/
最终结果是与以前相同的微小生产图像,复杂性显着降低。您不需要创建任何中间图像,也不需要将任何工件提取到本地系统。
它是如何工作的?第二个FROM指令以alpine:最新图像为基础开始一个新的构建阶段。 COPY --from = 0行仅将前一阶段的构建工件复制到此新阶段。 Go SDK和任何中间工件都被遗忘,而不是保存在最终图像中。
是的,就是你 能够 将大量软件整合到一个Docker镜像中(GitLab 这样做,一个图像包括Postgres和其他一切),但是 generalhenry 是对的 - 这不是使用Docker的典型方式。
正如你所说,卡桑德拉和卡夫卡是 依赖 对于您的Scala应用程序,它们不属于应用程序,因此它们并非都属于同一图像。
必须使用Docker Compose编排许多容器,这会增加额外的管理层,但它会为您提供更大的灵活性:
- 您的容器可以具有不同的生命周期,因此当您要部署新版本的应用程序时,您只需要运行新的应用程序容器,就可以保持依赖项运行;
- 您可以在任何环境中使用相同的应用程序映像,使用不同的依赖关系配置 - 例如在开发中,你可以运行一个基本的Kafka容器,并且它在多个节点上集群,你的app容器是相同的;
- 您的依赖项也可以被其他应用程序使用 - 因此多个使用者可以在不同的容器中运行,并且所有容器都使用相同的Kafka和Cassandra容器;
- 加上已经提到的所有可扩展性,日志记录等。
Docker不会对图像进行合并,但是如果可用的话,没有什么能阻止你将dockerfiles组合在一起,并将它们转换成你需要构建的胖图像。然而,有时候这是有道理的,因为在容器中运行多个进程,大多数Docker教条都会指出这一点,特别是对于微服务架构而言,这是不太理想的(但是规则是否正确?)
您无法将泊坞窗图像合并到1个容器中。参见Moby问题中的详细讨论, 如何通过Dockerfile将多个图像合并为一个。
对于您的情况,最好不要包含整个Cassandra和Kafka图像。该应用程序只需要Cassandra Scala驱动程序和Kafka Scala驱动程序。容器应仅包含驱动程序。