How to write data to host file system from Docker container

I have a Docker container which is running some code and creating some HTML reports. I want these reports to be published into a specific directory on the host machine, i.e. at /usr/share/nginx/reports

The way I have gone about doing this is to mount this host directory as a data volume, i.e. docker run -v /usr/share/nginx/reports --name my-container com.containers/my-container

However, when I ssh into the host machine, and check the contents of the directory /usr/share/nginx/reports, I don't see any of the report data there.

Am I doing something wrong?

The host machine is an Ubuntu server, and the Docker container is also Ubuntu, no boot2docker weirdness going on here.

122706 次浏览

From "Managing data in containers", mounting a host folder to a container would be:

docker run -v /Users/<path>:/<container path>

(see "Use volume")

Using only -v /usr/share/nginx/reports would declare the internal container path /usr/share/nginx/reports as a volume, but would have nothing to do with the host folder.

This is one of the type of mounts available:

https://docs.docker.com/storage/images/types-of-mounts.png

I am using Docker toolbox on windows. I am Working on a Spring Boot Application using Docker. My application writes logs to

users/path/service.log

So when i started my application from host terminal the Log file was successfully updated. But the same when i did on docker no file was created and neither updated.

So i changed my log file location to match with the Container's Directories

var/log/service.log

I started my container again and my file was updated again.

You can choose any location as long as it matches with the container Directory. Just bash into the container and see what suits you.

Next step is to copy log files from container to host.

So in order to copy those logs to your host. You can use one of two ways i know of-

1- use Volumes in docker

2- use following Docker command to copy file from docker container to host-:

docker cp <containerId>:/file/path/within/container /host/path/target

In your application, if you set a working directory for your php code (report path), the path must be the one on the container. Then docker will copie automaticly copy to your host directory. It wasn't docker mis-configuration, but my application that was writing to the wrong place. Weird at first, but did work in my case.

The answer to this question is problematic because it varies depending on your operating system and your full requirements. The answer by VonC makes some assumptions that should be addressed and is therefore only correct in some contexts. Other answers on this topic generally ignore the fact that some people are running linux, others windows, and still others are on OSX or other weird OS's.

As VonC mentioned in his answer, in a lot of cases it is possible to bind-mount a host directory straight into the container, using a -v host-path:container-path argument to the docker command (you can also use --volume for added readability or --mount for rocket-science).

One of the biggest problems (in 2020) is the use of the Windows Subsystem for Linux (WSL), where bind-mounting a host volume is fraught with error and may or may not work as expected depending on whether the path mounted is in the linux filesystem or the windows filesystem. VonC's answer was written before WSL became a big problem, but it still makes assumptions about the local filesystem being real rather than mounted into a virtual-machine of some kind.

I have found that a lot of engineers prefer to bypass this unnecessary confusion through the use of docker volumes. A docker volume can be created with the command:

docker volume create <name>

Listed with

docker volume ls

and removed with

docker volume rm <name>

You can mount this by specifying the name of the volume on the left-hand-side of the --volume argument. If your volume was called, for example, 'logs', you could use something like --volume logs:/usr/share/nginx/reports to bind it to the log dir you're interested in. You can view the contents of the directory with something like this:

docker run -it --rm --volume logs:/logs alpine ls -AlF /logs/

This should list the files in that directory. If you have a file called 'nginx.log' for example, you could view it like this:

docker run -it --rm --volume logs:/logs alpine less /logs/nginx.log

And the contents would be paged to your terminal.

You can bind this volume to multiple containers simultaneously if needed. This is useful if, for example, you're writing to your logs with one container, and paging them to a console with another.

If you want to copy the example log file from above into a tmp directory on your local filesystem you can achieve that with:

docker run -it --rm --volume logs:/logs --volume /tmp:/local_tmp alpine cp /logs/nginx.log /local_tmp/

First, you need to create a directory where you want to share the data

mkdir -p /abc/def/

Now, you need to create a docker volume using the below command. As we see here, we are specifying device as '/abc/def/'

docker volume create --driver local \
--opt type=none \
--opt device=/abc/def/ \
--opt o=bind \
spark-volume

Now, start your container with below command..

docker run -d \
--mount type=volume,dst=/abc/def/,volume-driver=local,volume-opt=type=none,volume-opt=o=bind,volume-opt=device=/opt/spark/ \
--network host \
img:tag

Now, docker container will use /abc/def/ in local Filesystem as its storage and you will have all contents of /abc/def/ in docker container available in Local Filesystem