Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How to write data to host file system from Docker container

Tags:

docker

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.

like image 963
jcm Avatar asked Jul 16 '15 08:07

jcm


People also ask

Can Docker container access files on host?

Docker volumes are convenient for sharing files from the host and keeping larger files out of image layers. They can also be significantly faster for filesystem access than the container filesystem, as some storage backends impose significant overheads for certain workloads.

How do you make a Docker container writable?

In your Dockerfile, just make use of RUN chown <your user> <location> . Show activity on this post. Write data into the writable layer of the container and commit the changes to an image with different tag (OR) use the same container name to start the container.


2 Answers

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

like image 151
VonC Avatar answered Sep 18 '22 06:09

VonC


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/ 
like image 44
Software Engineer Avatar answered Sep 20 '22 06:09

Software Engineer