简体   繁体   中英

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.

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?

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? so I want to map to a folder called '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.

When you map a path in a Docker container, this path is created inside the container. 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. 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.

You can map whole paths in Docker container like this:

volumes:
      - ./CypherQueries:/app/cypher

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

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