为什么Docker不向我的容器添加文件?

我正在玩Google的Dart Docker镜像 。 我正在尝试构build一个Hello World应用程序,它监听端口80.我在Azure上的Ubuntu Server 14上运行它。

如果我运行google/dart-hello ,这一切工作正常,我可以在端口8080连接。

google/dart-hello图片基于google/dart-runtime图片,而图片则基于google/dart 。 基础图像添加飞镖; google/dart-runtime添加了一个Dockerfile,它希望执行bin/server.dart并暴露8080端口, google/dart-hello提供bin/server.dart (和pubspec.yaml )。 google/dart-runtime是没有用的,因为它不包含bin/server.dartpubspec.yaml

所以,如果你的服务器在bin/server.dart 并且你想在端口8080上监听, google/dart-runtime是一个很好的基础。当我想在端口80上监听时,我使用google/dart图片作为基地,希望压扁什么是在google/dart-runtimegoogle/dart-hello到我的容器,但改为端口80。

您可以在这里find三个Google图片的源代码仓库:

  • google/dart
  • google/dart-runtime ( Dockerfile )
  • google/dart-hello ( Dockerfile )

所以,我已经从google/dart-runtime的Dockerfile和从google/dart-hello ,所以我有以下几点:

 FROM google/dart WORKDIR /app ONBUILD ADD pubspec.yaml /app/ ONBUILD ADD pubspec.lock /app/ ONBUILD RUN pub get ONBUILD ADD . /app ONBUILD RUN pub get CMD [] ENTRYPOINT ["/usr/bin/dart", "/app/bin/server.dart"] EXPOSE 80 

在与此Dockerfile相同的目录中,我有以下文件:

  • 斌/ server.dart
  • pubspec.yaml
  • pubspec.lock

我正在build立的形象:

 sudo docker build --no-cache -t dart-test . 

这里是输出:

 danny@linux:~/dart_test$ sudo docker build --no-cache -t dart-test . Sending build context to Docker daemon 5.632 kB Sending build context to Docker daemon Step 0 : FROM google/dart ---> cd92c7fff717 Step 1 : WORKDIR /app ---> Running in d163d2597eba ---> 2802d6769b76 Removing intermediate container d163d2597eba Step 2 : ONBUILD ADD pubspec.yaml /app/ ---> Running in 7b8be2a481c2 ---> 096cbe12a2cd Removing intermediate container 7b8be2a481c2 Step 3 : ONBUILD ADD pubspec.lock /app/ ---> Running in 6ae0243b0dee ---> 80f20ebafa87 Removing intermediate container 6ae0243b0dee Step 4 : ONBUILD RUN pub get ---> Running in 621d4ce5c7f1 ---> 89a509d41b11 Removing intermediate container 621d4ce5c7f1 Step 5 : ONBUILD ADD . /app ---> Running in 4de26a33487f ---> b69c65f12441 Removing intermediate container 4de26a33487f Step 6 : ONBUILD RUN pub get ---> Running in f7cc689f6f81 ---> 2ccc79ea6d04 Removing intermediate container f7cc689f6f81 Step 7 : CMD [] ---> Running in 10bd31eb6679 ---> f828267f00b5 Removing intermediate container 10bd31eb6679 Step 8 : ENTRYPOINT ["/usr/bin/dart", "/app/bin/server.dart"] ---> Running in 013d3ca0f25d ---> a63b59f9fd05 Removing intermediate container 013d3ca0f25d Step 9 : EXPOSE 80 ---> Running in 4301c572e598 ---> 75a4317c135c Removing intermediate container 4301c572e598 Successfully built 75a4317c135c 

然而,如果我尝试运行这个(使用sudo docker run --rm -i -t dart-test ),我得到以下错误:

 danny@linux:~/dart_test$ sudo docker run -i -t --rm dart-test Unhandled exception: Uncaught Error: FileSystemException: Cannot open file, path = '/app/bin/server.dart' (OS Error: No such file or directory, errno = 2) 

如果我将Dockerfile中的dart执行replace为/bin/bash ,那么当我构build并运行时,我会将其放入/app/但该文件夹是空的

我已经用0.9(?)版本和1.2(一个来自apt-get docker.io ,另一个来自Docker网站上的更多参与指令)尝试过,因为我注意到了ADD修复在发行说明中。 两者都是一样的。

我可以在网上find大量的信息,人们经常把Dockerfile转换成STDIN,这意味着没有context ,但是在我的输出中可以看到正在发送5KB的数据。 虽然有可能这只是Dockerfile,没有其他的我猜? 他们在同一个目录中,这是一个列表:

 danny@linux:~/dart_test$ dir bin Dockerfile pubspec.lock pubspec.yaml 

ONBUILD指令仅在您创build稍后将被其他Dockerfile使用的基础映像时才有用(请参阅文档 )。

在这里,因为您编写了最终的Dockerfile,您只需要删除ONBUILD指令(但保留原始指令ADDRUN等)。

在您的Dockerfile您需要从指令中删除ONBUILD前缀。 ONBUILD前缀是推迟执行某些指令的一种方式,直到该图像被另一个Dockerfile引用为止。 这些指令被存储为您创build的映像的元数据的一部分,但是指令本身不会被执行,直到该映像在另一个DockerfileFROM字段中被引用。

你真正想要的是这样的:

 FROM google/dart WORKDIR /app ADD pubspec.yaml /app/ ADD pubspec.lock /app/ RUN pub get ADD . /app RUN pub get CMD [] ENTRYPOINT ["/usr/bin/dart", "/app/bin/server.dart"] EXPOSE 80 

docker image google / dart-runtime旨在成为您的Dart服务器应用程序的基础映像。 所以在你的项目中, Dockerfile应该只有以下内容

 FROM google/dart-runtime 

当你运行ONBUILD ,在基本映像中docker build ONBUILD命令将被执行。

如果你看Dockerfile的google / dart-hello,你会发现它只有一行。