有没有办法将Docker图像合并到一个容器中?

有没有办法将Docker图像合并到一个容器中?,docker,dockerfile,docker-image,Docker,Dockerfile,Docker Image,我现在有一些文件 一个是卡桑德拉3.5版,它是卡桑德拉3.5版的 我还有一个卡夫卡的卷宗文件,但它要复杂一点。它是来自java:openjdk-8-fre的,它运行一个长命令来安装Kafka和Zookeeper 最后,我有一个用Scala编写的应用程序,它使用SBT 对于Dockerfile,它是来自broadinstitute/scala baseimage的,它为我提供了Java 8、scala 2.11.7和STB 0.13.9,这正是我所需要的 也许,我不明白Docker是如何工作的,但

我现在有一些文件

一个是卡桑德拉3.5版,它是卡桑德拉3.5版的

我还有一个卡夫卡的卷宗文件,但它要复杂一点。它是来自java:openjdk-8-fre的
,它运行一个长命令来安装Kafka和Zookeeper

最后,我有一个用Scala编写的应用程序,它使用SBT

对于Dockerfile,它是来自broadinstitute/scala baseimage的
,它为我提供了Java 8、scala 2.11.7和STB 0.13.9,这正是我所需要的

也许,我不明白Docker是如何工作的,但我的Scala程序将Cassandra和Kafka作为依赖项,出于开发目的,我希望其他人能够简单地使用
Dockerfile
克隆我的repo,然后能够使用Cassandra、Kafka、Scala、Java和SBT构建它,这样他们就可以编译源代码了。不过我有很多问题

如何合并这些DockerFile?如何简单地创建一个包含这些东西的环境?

是的,您可以将大量软件滚动到一个Docker映像中(这样做,一个映像包含Postgres和其他所有内容),但这是正确的-这不是使用Docker的典型方式

正如您所说,Cassandra和Kafka是Scala应用程序的依赖项,它们不是应用程序的一部分,因此它们不属于同一个映像

使用Docker Compose编排多个容器会增加一个额外的管理层,但它为您提供了更大的灵活性:

  • 你的容器可以有不同的生命周期,因此当你有新版本的应用程序要部署时,你只需要运行一个新的应用程序容器,你就可以让依赖项保持运行
  • 您可以在任何环境中使用相同的应用程序映像,为您的依赖项使用不同的配置-例如,在dev中,您可以运行基本的Kafka容器,在prod中,您的应用程序容器在许多节点上都是相同的
  • 你的依赖项也可以被其他应用程序使用——因此多个消费者可以在不同的容器中运行,并且都使用相同的Kafka和Cassandra容器
  • 加上前面提到的所有可伸缩性、日志记录等

    • 您不能合并DockerFile,因为可能会发生冲突。您要做的是创建一个新的dockerfile或构建一个自定义映像

      TL;博士 如果您当前的开发容器包含所有您需要且可用的工具,则将其另存为映像并保存到repo,然后创建dockerfile以从该映像中提取该repo

      详情: 构建自定义映像要比使用公共映像创建dockerfile容易得多,因为您可以将任何黑客和mod存储到映像中。为此,请使用基本Linux映像(或broadinstitute/scala baseimage)启动一个空白容器,安装所需的任何工具并进行配置,直到一切正常工作,然后将其保存为映像(容器)。根据此图像创建一个新容器,并测试您是否可以通过docker compose(或以您想要的方式)在其上构建代码。如果它能工作,那么你就有了一个可以上传到回购协议的工作基础映像,这样其他人就可以拉它了

      要构建具有公共映像的dockerfile,您需要在dockerfile本身上放置所有的hack、mod和setup。也就是说,您需要将使用的每个命令行放入文本文件中,并将任何黑客、mod和设置减少到命令行中。最后,您的dockerfile将自动创建一个映像,您不需要将此映像存储到repo中,您只需将dockerfile提供给其他人,他们就可以在自己的docker上旋转映像


      请注意,一旦您有了一个工作dockerfile,您就可以轻松地对其进行调整,因为每次使用dockerfile时,它都会创建一个新图像。使用自定义映像时,可能会遇到由于冲突而需要重建映像的问题。例如,在安装一个不起作用的工具之前,所有工具都可以使用openjdk。修复可能涉及卸载openjdk并使用oracle one,但您为所有已安装的工具所做的所有配置都已中断。

      Docker不会合并映像,但没有任何东西阻止您合并DockerFile(如果可用),并将其滚入需要构建的胖映像中。然而,有时这是有意义的,因为对于在一个容器中运行多个进程,大多数Docker教条会指出这不太可取,尤其是在微服务架构中(不管有没有违反规则的权利?)

      您不能将Docker映像合并到一个容器中。请参阅Moby问题中的详细讨论


      对于您的情况,最好不要包含整个卡桑德拉和卡夫卡图像。应用程序只需要Cassandra Scala驱动程序和Kafka Scala驱动程序。容器应仅包含驱动程序。

      您可以,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
      
      发件人:

      最终的结果是与以前一样的微小产品图像,大大降低了复杂性。您不需要创建任何中间映像,也不需要将任何工件提取到本地系统

      它是如何工作的?第二个FROM指令以“阿尔卑斯山:最新图像”为基础开始了一个新的构建阶段。COPY--from=0行只将构建的工件从上一阶段复制到这个新阶段。Go SDK和任何中间工件都会被留下,不会保存在最终映像中


      以下答案适用于docker 1.7及以上版本:

      我更喜欢使用
      --from=NAME
      from image作为NAME
      为什么? 您可以使用
      --from=0
      及更高版本,但当dockerfile中有许多docker阶段时,这可能不难管理

      sampl
      FROM golang:1.7.3 as backend
      WORKDIR /backend
      RUN go get -d -v golang.org/x/net/html  
      COPY app.go .
      RUN  #install some stuff, compile assets....
      
      FROM golang:1.7.3 as assets
      WORKDIR /assets
      RUN ./getassets.sh
      
      FROM nodejs:latest as frontend 
      RUN npm install
      WORKDIR /assets
      COPY --from=assets /asets .
      CMD ["./app"] 
      
      FROM alpine:latest as mergedassets
      WORKDIR /root/
      COPY --from=merge ./
      COPY --from=backend ./backend .
      CMD ["./app"]
      
      FROM ubuntu:latest
      RUN apt update
      RUN apt install -y sudo
      RUN sudo apt install -y docker.io
      RUN sudo apt install -y python3-pip
      RUN sudo apt install -y python3
      RUN docker --version
      RUN pip3 --version
      RUN python3 --version
      
      docker build -t docker-hub-repo/image-name:latest path/to/Dockerfile
      docker push docker-hub-repo/image-name:latest
      
      #syntax=bergkvist/includeimage
      FROM alpine:3.12.0
      INCLUDE rust:1.44-alpine3.12
      INCLUDE python:3.8.3-alpine3.12