> ## Documentation Index
> Fetch the complete documentation index at: https://notes.kodekloud.com/llms.txt
> Use this file to discover all available pages before exploring further.

# Volumes and Bind Mounts

> Explains Docker volumes and bind mounts for persisting container data, comparing -v and --mount usage, best practices, permissions, SELinux notes, and production recommendations

When you run a Docker container, it gets its own isolated filesystem. Any files created or changed inside that container exist only for the lifetime of the container unless you explicitly persist them. This is important to understand when running stateful services like databases.

Example: MySQL stores its data under `/var/lib/mysql` inside the container. If you create databases and then remove the container, all of that data disappears:

```bash theme={null}
# run an example MySQL container (the official image requires a root password env var)
docker run --name mysql-sample -e MYSQL_ROOT_PASSWORD=my-secret-pw -d mysql:latest
docker stop mysql-sample
docker rm mysql-sample
```

Because the container's filesystem is ephemeral, deleting the container removes `/var/lib/mysql` and any databases created inside it. To persist data beyond the container lifecycle, mount storage from the Docker host into the container.

Bind mount the host directory `/opt/datadir` into the container’s `/var/lib/mysql` using the short `-v` syntax:

```bash theme={null}
# bind-mount host directory /opt/datadir into container's /var/lib/mysql
docker run --name mysql-persist -v /opt/datadir:/var/lib/mysql -e MYSQL_ROOT_PASSWORD=my-secret-pw -d mysql:latest
```

With this bind mount, MySQL writes its files into `/opt/datadir` on the host. Removing the container (`docker rm`) does not remove data stored in `/opt/datadir`.

<Callout icon="lightbulb" color="#1CB2FE">
  Bind mounts map a host directory (or file) into a container. The host path must be absolute when using `--mount` and is created automatically with `-v` if it does not exist.
</Callout>

A quick comparison: `-v` (or `--volume`) vs `--mount`

* `-v` / `--volume` (short form) accepts a single colon-separated string (for example, `/host/path:/container/path`) and is concise.
* `--mount` is more explicit and recommended for clarity, especially for complex mounts; it accepts key-value pairs and requires you to set `type`, `source`, and `target`.

Use the table below to compare these two forms and see sample usage:

| Feature | `-v` / `--volume` | `--mount` |
| - | -: | :- |
| Syntax style | Single colon-separated string | Key-value pairs |
| Example | `-v /opt/datadir:/var/lib/mysql` | `--mount type=bind,source=/opt/datadir,target=/var/lib/mysql` |
| Host directory creation | `-v` will create the host directory if it doesn't exist | With `--mount type=bind` you should create the host directory beforehand |
| Clarity for advanced options | Less explicit | More explicit, easier to read for complex setups |
| When to prefer | Quick, simple mounts | Production, complex mounts, or when readability matters |

Equivalent `--mount` example to the earlier `-v` bind mount:

```bash theme={null}
docker run --name mysql-persist \
  --mount type=bind,source=/opt/datadir,target=/var/lib/mysql \
  -e MYSQL_ROOT_PASSWORD=my-secret-pw -d mysql:latest
```

Best practices and operational notes

* Always use absolute host paths with `--mount type=bind`.
* Create host directories ahead of time when using `--mount` to avoid surprises.
* Check file ownership and permissions: files created by the container may be owned by different UIDs/GIDs on the host. You may need to adjust permissions or use consistent UID/GID mappings.
* For SELinux-enabled hosts, you might need `:z` or `:Z` mount options with `-v` to allow container access (e.g., `-v /opt/datadir:/var/lib/mysql:Z`).
* For production deployments, prefer Docker named volumes, managed storage solutions, or networked storage backends and implement a regular backup strategy.

<Callout icon="warning" color="#FF6B6B">
  Persisting data with bind mounts exposes host files to the container. Misconfigured mounts can lead to data loss or security issues. Always back up important data and verify mount ownership/permissions before trusting a mount for production workloads.
</Callout>

Summary

* Containers are ephemeral by default; files inside a removed container are removed with it.
* Bind mounts let you map a host directory into a container so data persists independently of the container lifecycle.
* `-v` is concise and convenient; `--mount` is more explicit and recommended for clarity and production use.
* Consider file permissions, SELinux contexts, and backup strategies when persisting data.

Links and references

* [Docker Volumes and Bind Mounts](https://docs.docker.com/storage/volumes/)
* [Docker run reference](https://docs.docker.com/engine/reference/run/)
* [MySQL Docker image (Docker Hub)](https://hub.docker.com/_/mysql)

<CardGroup>
  <Card title="Watch Video" icon="video" cta="Learn more" href="https://learn.kodekloud.com/user/courses/docker-training-course-for-the-absolute-beginner/module/7a88081c-a9d0-45cc-b75e-55c93b6886d6/lesson/a7b65aeb-82fe-4c1d-b705-ef32c57e07d8" />
</CardGroup>


This documentation is built and hosted on [Mintlify](https://mintlify.com), a developer documentation platform.