如何从 Docker 容器内的输入文件中读取内容

huangapple go评论82阅读模式
英文:

How to read from input file inside docker container

问题

我有一个简单的Java程序,运行在Docker容器内。

我在Windows上使用Eclipse,但我创建了Linux容器(使用Windows Docker桌面)。

我使用PowerShell启动容器。

镜像已成功创建。

我看到了这个帖子,但它对我没有帮助c++ program with docker。我在那个答案中使用的解决方案出现了错误。

PS E:\Java\Test> docker run -v E:\Java\Test:\tt img \tt\in.txt

docker: Error response from daemon: OCI runtime create failed: container_linux.go:349: starting container process caused "exec: '\\tt\\in.txt': executable file not found in $PATH": unknown.

Dockerfile

FROM java:8
COPY hello.jar app.jar
CMD ["java", "-jar", "app.jar", "pkg.hello"]
public static void main(String[] args) throws Exception {
    String fileName = "E:\\Java\\Test\\in.txt";
    List<String> lines = Collections.emptyList();
    lines = Files.readAllLines(Paths.get(fileName), StandardCharsets.UTF_8);
    Iterator<String> itr = lines.iterator();
    while (itr.hasNext())
        System.out.println(itr.next());
}

有什么想法,谢谢。

英文:

I have a simple program in java which is run inside docker container.

I used Eclipse On windows - But I created the linux containers (with windwos docker desktop)

I used Powershell to start container
The image is successfully created

I saw this thread but it didnt help me c++ program with docker. I have an error using the solution in that answer.

PS E:\Java\Test&gt; docker run -v E:\Java\Test:\tt img \tt\in.txt

docker: Error response from daemon: OCI runtime create failed: container_linux.go:349: starting container process caused "exec: &quot;\\tt\\in.txt&quot;: executable file not found in $PATH": unknown.

Dockerfile

FROM java:8
COPY  hello.jar app.jar
CMD [&quot;java&quot;, &quot;-jar&quot;, &quot;app.jar&quot;, &quot;pkg.hello&quot;]



public static  void main(String[] args) throws Exception {
	String fileName =&quot;E:\\Java\\Test\\in.txt&quot;;
	List&lt;String&gt; lines = Collections.emptyList();
	lines =   Files.readAllLines(Paths.get(fileName), StandardCharsets.UTF_8);
	Iterator&lt;String&gt; itr = lines.iterator(); 
    while (itr.hasNext()) 
      System.out.println(itr.next()); 
	}

Any ideas, thanks

答案1

得分: 2

新的Docker文件

FROM java:8

COPY hello.jar app.jar

ENTRYPOINT ["java", "-jar", "app.jar", "pkg.hello"]

在经过多次的试错之后,我找到了一个解决方案,可能不止一个。我想为那些像我一样不是很专业的人解释一下,

正如我们所知,Docker在容器内部创建了类似于迷你操作系统的东西,我的意思是所需的库和文件**+**我们开发的应用程序。我尝试运行并查看在Docker中运行时我的目录里有什么。在Windows上通过在Eclipse上运行显示常规路径,E:\Java\....。**但是当我在Docker上运行时,它只显示"/"。**然后我尝试查看内容。在Windows上,当前目录内的文件和文件夹都在,**但是在Docker上,它显示了一些与Linux根路径文件夹相同的文件夹,如bin、sbin、mnt、proc等。**所以我意识到有一个迷你的Linux。*我知道这个事实,但从未见过这个结果。*所以很明显,in.txt在Docker文件系统中不存在。***现在我们看到了Docker的一些功能,比如-v。***它允许我们从主机(即Windows)复制/粘贴一个目录到Docker容器文件系统中。运行了这个命令后,我看到一个叫做data的新文件夹被添加到了Docker的文件夹中

docker run -v ${pwd}:/data img

整个pwd(在Windows上的当前目录)的内容被复制到了data目录中,包括in.txt。现在我的Java程序应该在Docker内部运行,所以我需要更改硬编码的路径。

String fileName = "data//in.txt";

显然在Windows上这不起作用,因为我的文件夹中没有\data\in.txt。我可以通过获取一些参数并跳过硬编码来做到这一点,不管怎样,有很多方法。我将我的代码添加到查看目录状态,你可能想要尝试。

String d = System.getProperty("user.dir");
File f = new File(d);
File filesList[] = f.listFiles();
for(File file : filesList) {
    System.out.println("文件名:" + file.getName());
    System.out.println("文件路径:" + file.getAbsolutePath());
    if (file.getName().equals("data") == true) {
        File filesList2[] = file.listFiles();
        for(File file2 : filesList2) {
            System.out.println("文件名:" + file2.getName());
            System.out.println("文件路径:" + file2.getAbsolutePath());
        }
    }
    System.out.println(" ");
}
英文:

New Docker file

FROM java:8

COPY  hello.jar app.jar

ENTRYPOINT [&quot;java&quot;, &quot;-jar&quot;, &quot;app.jar&quot;, &quot;pkg.hello&quot;]

Ok after lots of trial and error I found one solution, there might be more than one. I want to explain a bit for those who are not very expert like me,

As we know docker makes a something like a mini OS inside the container, I mean the required libraries and files + the application we developed. I tried to run and see what is inside my directory when running in docker. by running on eclipse on windows it shows the regular path, E:\Java\.... . But when I ran it on docker it shows only "/". and then I tried to see the contents. on windows the files and folders inside the current Dir but on docker it shows some folders same as LINUX root path folders, bin sbin mnt proc etc. So I realized that there is a mini linux. I knew this fact but never seen this result. So obviously the in.txt is not there in docker file system. now we see the docker features like -v. it allows us to copy/paste one directory from host, which is windows, to docker container file system. After running this command I saw that a new folder called data is added to docker folders

docker run -v ${pwd}:/data img

the whole contents of pwd (current directory on Win) is copied to data directory, along with in.txt. now my java program is supposed to be run inside the docker, So i need to change the hard-coded path.

String fileName =&quot;data//in.txt&quot;; 

definitely it does not work on windows because there is not \data\in.txt in my folders.
I could do it by getting some arguments and skip the hard-code, no matter. there are plenty of ways. I added my codes to see the Dir status, you may want to try.

String d = System.getProperty(&quot;user.dir&quot;);
	File f = new File(d);
	File filesList[] = f.listFiles();
	for(File file : filesList) {
         System.out.println(&quot;File name: &quot;+file.getName());
         System.out.println(&quot;File path: &quot;+file.getAbsolutePath());
         if (file.getName().equals(&quot;data&quot;)==true)
         {
        	 File filesList2[] = file.listFiles();
        	 for(File file2 : filesList2) {
        	 System.out.println(&quot;File name: &quot;+file2.getName());
	         System.out.println(&quot;File path: &quot;+file2.getAbsolutePath());
        	 }
        	 
         }
         System.out.println(&quot; &quot;);
      }

答案2

得分: 0

我认为在这种情况下,您需要使用 ENTRYPOINT 而不是 CMD。简而言之:

使用 CMD 时,当您运行容器时,容器名称旁边的指令将成为新的 CMD(从这里出现错误 &quot;\\tt\\in.txt&quot;: executable file not found in $PATH&quot;: unknown)。另一方面,使用 ENTRYPOINT 时,您在容器名称之前添加的指令将被添加为附加参数。

有关 CMDENTRYPOINT 的更详细解释,请查阅此文章

英文:

I think in this case you will need to use ENTRYPOINT instead of CMD. In short:

With CMD when you run the container, the instruction next to container name will become the new CMD used (from here the error &quot;\\tt\\in.txt&quot;: executable file not found in $PATH&quot;: unknown). On the other hand, with ENTRYPOINT the instruction you add before the container name will be added as an additional argument.

Check this article for a longer explanation about CMD and ENTRYPOINT.

huangapple
  • 本文由 发表于 2020年8月17日 05:53:08
  • 转载请务必保留本文链接:https://go.coder-hub.com/63442283.html
匿名

发表评论

匿名网友

:?: :razz: :sad: :evil: :!: :smile: :oops: :grin: :eek: :shock: :???: :cool: :lol: :mad: :twisted: :roll: :wink: :idea: :arrow: :neutral: :cry: :mrgreen:

确定