7

I would like to copy my winetricks cache over to the docker container:

HOST:

~/.cache/winetricks

to CONTAINER

/home/myUser/.cache/winetricks.

My current approach is to create a copy of the cache in the docker root and use COPY to move the cache over to the container. This will make the cache available at build time.

I am using the approach to save build time. The Docker COPY command is commented out in production.

So here is my question: Why do I have to make a duplicate of my ~/.cache directory? Why can I not copy a directory from outside of the docker root to the container?

user8162
  • 391
  • 3
  • 12
  • If this is truly a cache (volatile, with contents that only impact performance but not behavior), I strongly suggest that you **don't** copy it. Mount this into your container as a volume instead. That way content cached by one instance will be usable by another or by the host, and you don't create a whole bunch of new containers by re-COPYing content every time the cache changes (which, if it's a volatile cache, will be happening all the time). – Charles Duffy Feb 23 '18 at 17:09
  • I thought I can not mount within a docker file. – user8162 Feb 23 '18 at 17:18
  • Is there a specific question or is this just about the approach (in which case this probably isn't the right forum)? I don't particularly see a problem with copying a local cache source vs downloading at build time if the same files are going to end up in the _image_ anyway. You certainly don't want to maintain a volatile cache inside a _container_ -- you would want a volume (named or anonymous), there are plenty sources of documentation and tutorials on how to do that. – ldg Feb 23 '18 at 18:50
  • so the question is, why i have to copy everything to docker root in the first place, but I guess, that is just the way docker thinks it's best. – user8162 Feb 23 '18 at 18:53
  • 1
    Gotcha. See [add-copy docs](https://docs.docker.com/v17.09/engine/userguide/eng-image/dockerfile_best-practices/#add-or-copy) - Docker copies all the files used to build the image into a build context (you can use a .dockerignore file to manage which files) and only those files are available for local `COPY`. You can use `ADD` or `RUN curl/wget/etc` to fetch remote files available over a network. Again, the best approach is really going to be up to your workflow. – ldg Feb 23 '18 at 18:59
  • I start to understand. so I can **remove** files with `.dockerignore` but I can not **add** files/symlinks to directories outside of the docker root. I do get the reason behind it but as I will not check in all my directories from my docker-root to my git, it's unlikely that someone will get the same docker-root as I have, now. So in my opinion it's an unncessary limit. same goes for non-existing *copy if exists* instructions. – user8162 Feb 23 '18 at 19:08
  • Did you find out the actual solution of copying host root system files into the container during the build? I am at the same step and unable to add files beyond the docker root. Everyone is answering something useless instead of exactly understanding the question. – Bharadwaj Mar 13 '18 at 15:47
  • It is not directly possible. – user8162 Mar 13 '18 at 15:50

2 Answers2

6

So here is my question: Why do I have to make a duplicate of my ~/.cache directory? Why can I not copy a directory from outside of the docker root to the container?

The first step of a docker build command is to send the build context to the docker engine performing the build. This engine may be on a remote server. This build context is typically a . at the end of the command line indicating to send the current directory as your context.

This context is used for every COPY and ADD command, and any file not included in the context is unavailable for the COPY and ADD. Changing the behavior to allow all files on the host to be accessible would break the client/server design of docker builds and introduce a security vulnerability where someone could send a malicious Dockerfile to the build server and use that to extract secret data from the server into the image.

You can change the build context to be your home directory, instead of your project sub-directory. To do this, you'd also need to update all the COPY and ADD commands with the path relative to $HOME. You would also see a significantly longer build time as your entire home directory gets sent to the server.

For your specific issue, there's a new feature that just entered into experimental called BuildKit. One of the first features being implemented is mounting a directory during a RUN command for the purposes of a packaging cache you only want to pull once.

BMitch
  • 231,797
  • 42
  • 475
  • 450
  • thank you for your answer. It was primarily an understanding issue of the docker concept. We are limited to docker security policies here. I wanted to speed up build-time during dev by preserving the `~/.cache` directory. `RUN --mount` seems to go in the right direction but this discussion is far beyond the scope of stackoverflow. – user8162 Jul 30 '18 at 21:34
1

https://docs.docker.com/storage/volumes/#choose-the--v-or-mount-flag

@Charles Duffy is right.

dockerfile below

VOLUME ["(change-to-full-path)/.cache/winetrick"]

lanch value below

-v (change-to-full-path)/.cache/winetricks:/home/myUser/.cache/winetricks

This will allow you to set a volume, and then path it into the container

ajankuv
  • 499
  • 3
  • 22
  • 1
    So the VOLUME is a mount point inside the docker container but the binding to the host results at run time. How can I now bind the host directory during `docker build`? – user8162 Feb 23 '18 at 17:52
  • You cannot mount a VOLUME during the build. The closest answer I found is [here](https://stackoverflow.com/questions/26050899/how-to-mount-host-volumes-into-docker-containers-in-dockerfile-during-build) – Bharadwaj Mar 13 '18 at 15:48