# 25.15、Docker 数据卷

为了持久化我们的数据，所以Docker引入了数据卷，数据卷区别于容器，镜像，删除容器镜像并不会删除数据卷。

![](https://3801536837-files.gitbook.io/~/files/v0/b/gitbook-legacy-files/o/assets%2F-M7kU_Hr8e2bVvygGB-6%2F-M9bfDqKlyZKeB8NY_c4%2F-M9bfUNBJ5xPv-Ha733e%2F486468-20180208151943795-1803895047.png?alt=media\&token=9d32a9c8-531e-48f4-8d5d-91301ed6d9be)

![](https://3801536837-files.gitbook.io/~/files/v0/b/gitbook-legacy-files/o/assets%2F-M7kU_Hr8e2bVvygGB-6%2F-M9bfDqKlyZKeB8NY_c4%2F-M9bfWytxyBx2-ca_vLO%2F486468-20180208152108341-1652225529.png?alt=media\&token=a1ce0b4d-f6ce-4b0c-abf2-d0cd66e1fdfb)

## 数据卷作用

* 数据卷可以在容器间共享和重用数据
* 数据卷可以在宿主和容器间共享数据
* 数据卷数据改变是直接修改的
* 数据卷是持续性的，直到没有容器使用它们。即便是初始的数据卷容器或中间层的数据卷容器删除了，只要还有其他的容器使用数据卷，那么里面的数据都不会丢失。

## 数据卷介绍

所谓的数据卷无非就是一个存储数据的地方，可以是一个目录，也可以是一个文件。我们可以把容器里面某一个目录或者文件在我们本机（宿主）做一个映射关系，==当容器数据发生改变或者本机数据发送改变，可以相互作用，相互影响，当容器删除并不会删除数据卷==

## 创建数据卷

* `docker run`时，通过 `-v` 方式创建，`-v 主机目录/文件:容器中目录/文件` (==推荐==)

```bash
docker run --name container -v ~/data/html:/usr/share/html -d image
```

`:ro`：表示只读 `:rw`：表示可读可写

如：

```bash
docker run --name nginx -p 80:80 -v ~/data/conf/nginx.conf:/etc/nginx/nginx.conf:ro -d nginx
```

* 通过`docker volumn create` 创建，**没办法指定主机目录，固定为：/var/lib/docker/volumes/，只能创建目录数据卷**

<https://docs.docker.com/engine/reference/commandline/volume_create/>

```bash
docker volume create new-volumn
```

```bash
docker volume ls

docker volume inspect new-volume
```

```bash
docker run --name nginx -p 80:80 -v new-volume:/etc/nginx:ro -d nginx
```

**方便多个容器共用，无需指定具体目录，通常用于临时保存一些数据供其他容器查看或调用，类似临时表的概念**

* 通过 `Dockerfile` 中创建

```
VOLUME ["/uploads"]
```

\==特别注意：这里是不能指定主机目录的！！！！我们只是做了一个开放接口，因为每个人的电脑分区，系统类型都不一样，主机目录应该由运行者设置！！！==

比如客户上传的东西都放在了`uploads` 目录中，这样我们就可以做映射把数据备份到本机

```bash
docker run -v /etc/data:/uploads
```

## 注意事项

在`Windows`系统中，主机地址需要全路径，==盘符前面需要加两个斜杠==，如：`//D/workplace` 表示D盘workplace目录

在`Linux/Mac`系统中，主机地址需要添加==\~==开头，如：`~/etc` 表示根目录的etc目录，linux系统很少有盘符的概念（当然也可以有）

## Nginx 挂载数据卷的一个例子

```bash
docker run --name first-nginx -v ~/data/html:/usr/share/nginx/html -p 8081:80 -d nginx
```

**原有的数据依然存在**

## 开发注意事项

一旦我们定义了Docker数据卷，那么在我们程序中就要用数据卷目录为主，如

我们定义了 `/uploads` 用户上传的目录，那么我们的代码

C#

```csharp
FileHelper.Upload("/uploads","a.jpg");
```

我们代码所有需要上传在这个目录中的全部要用 `/uploads` 表示。而不是通过 获取当前项目的目录
