为什么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.dart
或pubspec.yaml
。
所以,如果你的服务器在bin/server.dart
并且你想在端口8080上监听, google/dart-runtime
是一个很好的基础。当我想在端口80上监听时,我使用google/dart
图片作为基地,希望压扁什么是在google/dart-runtime
和google/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
指令(但保留原始指令ADD
, RUN
等)。
在您的Dockerfile
您需要从指令中删除ONBUILD
前缀。 ONBUILD
前缀是推迟执行某些指令的一种方式,直到该图像被另一个Dockerfile引用为止。 这些指令被存储为您创build的映像的元数据的一部分,但是指令本身不会被执行,直到该映像在另一个Dockerfile
的FROM
字段中被引用。
你真正想要的是这样的:
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,你会发现它只有一行。