# How to access files outside a Docker container

> Learn how to access and persist files outside a Docker container using bind mounts and volumes with the docker run -v flag, so your data is not lost.

Author: [Flavio Copes](https://flaviocopes.com/about/) | Published: 2020-07-19 | Topics: [Docker](https://flaviocopes.com/tags/docker/) | Canonical: https://flaviocopes.com/docker-access-files-outside-container/

If containers are isolated, how can they communicate to the host machine, perhaps to store data? Because when we create a container from an image, any data generated is lost when the container is removed.

So we need a way to have permanent storage.

We can do so using **Bind Mounts** and **Volumes**.

There's not a lot of difference between the two, except Bind Mounts can point to any folder on the host computer, and are not managed by Docker directly.

Let's start with them. One classic example is logs. Suppose your app creates a log file, inside the container, in `/usr/src/app/logs`. You can map that to a folder on the host machine, using the `-v` (same as `--volume`) flag when you run the container with `docker run`, like this: `-v ~/logs:/usr/src/app/logs`

This will map that folder to the logs subfolder in the user's home directory.

> Node: the `-m` or `--mount` flag works in a very similar way

This is the flag used with the `examplenode` image we created previously:

```sh
docker run -d -p 80:3000 -v ~/logs:/usr/src/app/logs --name node-app examplenode
```

So now we can run our Node app, and any log will be stored in the host computer, rather than inside the Docker container. 

> Note that the `examplenode` app does not generate any log in `/usr/src/app/logs`, it's just an example and you would need to set that logging up first.

The details about the volume will be listed when you run `docker inspect` on the container name, under "Mounts":

```
"Mounts": [
    {
        "Type": "bind",
        "Source": "/Users/flavio/logs",
        "Destination": "/usr/src/app/logs",
        "Mode": "",
        "RW": true,
        "Propagation": "rprivate"
    }
],
```

Can you see `"Type": "bind"`? That means that we have created a *bind mount*.

Now, let's talk about **Volumes**.

The difference between Bind Mounts and Volumes is that by creating volumes, Docker will store the data in a folder it manages, which means it will take care of file permissions and ownership, and it will give you the tools to manage those volumes. While bind mounts are based on filesystem paths, and Docker can't provide the tooling around them.

For example, Docker lets you remove all unused volumes by running `docker volume prune` or `docker system prune --volumes`. 

To create a volume, we first need to run `docker volume create`:

```sh
docker volume create logs
```

Now you can use `docker volume ls` and `docker volume inspect` to get more data about the system volumes:

![Terminal showing docker volume create, docker volume ls, and docker volume inspect commands with JSON output](https://flaviocopes.com/images/docker-access-files-outside-container/Screen_Shot_2020-07-05_at_15.40.37.png)

Now run `docker run` with the option `-v logs:/usr/src/app/logs` (tell the volume name instead of a folder)

```sh
docker run -d -p 80:3000 -v logs:/usr/src/app/logs --name node-app examplenode
```

Now running `docker inspect` on the image will show the mounted volume:

```
"Mounts": [
    {
        "Type": "volume",
        "Name": "logs",
        "Source": "/var/lib/docker/volumes/logs/_data",
        "Destination": "/usr/src/app/logs",
        "Driver": "local",
        "Mode": "z",
        "RW": true,
        "Propagation": ""
    }
],
```

See? Now the logs will be stored in the `/var/lib/docker/volumes/logs/_data` folder.

Volumes will be essential when it will be time to deploy a container on a cloud service, for example.

You can remove a volume running `docker volume rm <name>`.
