简体   繁体   English

Docker-compose - 创建一个卷并在启动时将文本文件复制到其中,并在运行后通过容器中的 .net 核心控制台应用程序读取文本文件

[英]Docker-compose - create a volume and copy text files to it at spin-up and read text files via net core console app in container once running

Sorry, the title is a bot of a mouthful but I dont a better way to describe it.抱歉,标题有点啰嗦,但我找不到更好的描述方式。 I am sure I am misunderstanding the concept of images and building containers but let me say what I am trying to do and someone may be able to clarify if I have the wrong end of the stick.我确定我误解了图像和构建容器的概念,但让我说一下我正在尝试做的事情,有人可能会澄清我是否有错误的一端。

I have a console app running as a service that currently has a number of script files included in the project as embedded resources that can be read and actioned after the container has started.我有一个作为服务运行的控制台应用程序,该应用程序当前在项目中包含许多脚本文件作为嵌入式资源,可以在容器启动后读取和操作。 This works ok HOWEVER if there is ever a change to one of the scripts then the whole project has to be recompiled and redeployed.这可以正常工作,但是如果其中一个脚本发生更改,则必须重新编译和重新部署整个项目。

What I am trying to do instead is to have my console app read in the script files at runtime from a known source ie a folder that is outside of the current project but within the container so that I can then create a volume via the docker-compose file and copy scripts during spinup to the target folder in the container.我想做的是让我的控制台应用程序在运行时从已知来源读取脚本文件,即当前项目之外但在容器内的文件夹,这样我就可以通过 docker-compose 文件创建一个卷并在启动期间将脚本复制到容器中的目标文件夹。

I am struggling to get my head around as to how I can write my c# code to be able to read files from the specific location that will work the same whether the app is running inside of a container or locally during debug and I am wondering if maybe it is even possible?我正在努力思考如何编写我的 c# 代码,以便能够从特定位置读取文件,无论应用程序是在容器内运行还是在调试期间在本地运行,这些文件都可以正常工作,我想知道是否也许甚至有可能?

Am I over complicating this whole thing?我是不是把这整件事复杂化了?

An example of what I have been playing with is like this我一直在玩的一个例子是这样的

    services:
  consoleapp5:
    image: ${DOCKER_REGISTRY-}consoleapp5
    build:
      context: .
      dockerfile: ConsoleApp5/Dockerfile
    volumes:
      - ./CypherQueries/defaultCypher.txt:/app/cypher/defaultCypher.txt  

Now I am thinking that '/app' is the root of the container?现在我在想 '/app' 是容器的根目录吗? so I want to map to a folder called 'cypher'?所以我想 map 到一个名为“cypher”的文件夹? In my app I am not sure how I should navigate to this directory as things such as在我的应用程序中,我不确定应该如何导航到该目录,例如

StreamReader sr = new StreamReader("/app/cypher/Sample.txt");

or或者

var path = Path.Combine(
    Path.GetDirectoryName(System.Reflection.Assembly.GetExecutingAssembly().Location),
    "/app/cypher/Sample.txt");

I know they are crude examples but they are not going to work the way I want it to anyway are they?我知道它们是粗略的例子,但无论如何它们都不会按照我想要的方式工作,是吗?

I need the same code to work whether inside a container or not.无论是否在容器内,我都需要相同的代码才能工作。

Please let me know if I have not been clear with what I am trying to do.如果我不清楚我要做什么,请告诉我。

Any advice greatly appreciated.非常感谢任何建议。

As long as you hardcode your path - ie /app/cypher/Sample.txt - the question, whether your app works or not depends on whether this path exists and whether the expected scripts are actually in that path.只要您对路径进行硬编码 - 即 /app/cypher/Sample.txt - 问题,您的应用程序是否有效取决于此路径是否存在以及预期脚本是否实际位于该路径中。

When you map a path in a Docker container, this path is created inside the container.当你在 map 容器中创建路径时, Docker 容器中会创建此路径。 The mapped host path has always priority compared to paths that might already exist in the image.与映像中可能已存在的路径相比,映射的主机路径始终具有优先级。 So, when your Docker image already has a path "/app/cypher/defaultCypher.txt", it is obscured at docker-compose up and when it doesn't have that path, it just get's created inside the container.因此,当您的 Docker 图像已经具有路径“/app/cypher/defaultCypher.txt”时,它在 docker-compose 向上被遮挡,当它没有该路径时,它只是在容器内创建。 While that ensures your app to work in the container, it means you'd have to create that path on every host machine you want your app to work as well.虽然这可以确保您的应用程序在容器中运行,但这意味着您必须在希望您的应用程序也运行的每台主机上创建该路径。

When you want to ensure your app to be working on different hosts without manual path creation, my advise is either to use a relative path in your C# code and to deploy the whole package, or to assemble the path with a variable and make sure to pass that for every environment.当你想确保你的应用程序在不同主机上工作而无需手动创建路径时,我的建议是在你的 C# 代码中使用相对路径并部署整个 package,或者使用变量组装路径并确保将其传递给每个环境。

You can map whole paths in Docker container like this:您可以像这样在 Docker 容器中 map 整个路径:

volumes:
      - ./CypherQueries:/app/cypher

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM