如何在启动时将文件从主机复制到容器中?

时间:2019-11-12 09:18:33

标签: docker dockerfile docker-entrypoint

我正在尝试使用dockerfile构建docker映像,我的目的是在运行“ docker run”命令时将文件复制到特定文件夹中!

这是我的dockerfile代码:

    FROM openjdk:7

    MAINTAINER MyPerson

    WORKDIR /usr/src/myapp

    ENTRYPOINT ["cp"]

    CMD ["/usr/src/myapp"]

    CMD ls /usr/src/myapp

在没有任何错误(使用docker build命令)构建映像之后,我尝试运行新映像:

    docker run myjavaimage MainClass.java

我收到此错误:** cp:'MainClass.java'之后缺少目标文件操作数**

我该如何解决?

3 个答案:

答案 0 :(得分:1)

我认为您想要这个Dockerfile:

FROM openjdk:7
WORKDIR /usr/src/myapp
COPY MainClass.java .
RUN javac MainClass.java
ENV CLASSPATH=/usr/src/myapp
CMD java MainClass

docker build映像时,它会将您的Java源文件从本地目录COPY插入映像中,对其进行编译,并设置一些元数据告诉JVM在哪里找到生成的{{1 }}文件。然后,当您启动容器时,它将运行打包在其中的单个应用程序。

使用Maven或Gradle之类的高级构建工具将多个文件编译成单个.class文件已经足够普遍了。在运行构建之前,请确保.jar所需的所有源文件。在Java中,似乎很常见的是在Docker外部构建COPY文件,而在.jar中构建该文件而无需JDK,这也是一条合理的路径。

在您显示的Dockerfile中,使用Docker combines ENTRYPOINT and CMD into a single command,并将该命令作为容器的单个主进程运行。如果您在COPY命令中提供某种命令,它将覆盖docker run但不会覆盖CMD。您只会得到一个ENTRYPOINT和一个ENTRYPOINT,而Dockerfile中的最后一个将获胜。因此,您正在尝试运行类似

的容器进程
CMD

正如@QuintenScheppermans在他们的答案中建议的那样,您可以使用# What's in the Dockerfile cp /bin/sh -c "ls /usr/src/myapp" # Via your docker run command cp MainClass.java 选项在运行时注入文件,但这将在已经发生docker run -v之类的命令之后发生。您实际上并不需要一个工作流程,每次RUN javac容器时,整个应用程序都会被重建。在docker run或更早的时间内构建图像。

答案 1 :(得分:1)

两件事。

  1. 您已使用CMD两次。

CMD只能使用一次,将其视为docker映像的用途。每次运行容器时,如果要使用多个命令,它将始终执行CMD,应使用RUN,最后使用CMD

FROM openjdk:
MAINTAINER MyPerson
WORKDIR /usr/src/
ENTRYPOINT ["cp"]
RUN /usr/src/myapp
RUN ls /usr/src/myapp
  1. 将内容复制到图像中 有一个简单的命令COPY,语法为COPY <from-here> <to-here>

好像您想运行myjavaimage,所以您将要做的是

COPY /path/to/myjavaimage /myjavaimage
CMD myjavaimage MainClass.java

在您看到箭头的地方,我刚刚编写了伪代码。将其替换为正确的代码。

此外,您的Dockerfile创建错误。

ENTRYPOINT->不知道为什么要使用“ cp”,但这是一个实际的切入点。可以指向您项目的根目录或将要运行的应用程序。 不明白为什么要这么做ls /usr/src/myapp,但是如果您确实想这样做,请使用RUN而不是CMD

最后, 调试Docker容器的最佳方法是在交互模式下。这意味着要进入您的容器,环顾四周,运行代码,然后查看问题出在哪里。

运行此命令:docker run -it <image-name> /bin/bash,然后深入内部,这通常是了解导致问题的最佳方法。

答案 2 :(得分:0)

This stackoverflow page完美回答了您的问题。

COPY foo.txt /data/foo.txt
# where foo.txt is the relative path on host
# and /data/foo.txt is the absolute path in the image

如果在运行命令时需要挂载文件:

docker run --name=foo -d -v ~/foo.txt:/data/foo.txt -p 80:80 image_name