和这种蛋糕一样, Docker 的容器和镜像也是使用类似的分层文件系统构建而成的.
这样做的好处就是可以节省硬盘空间, 也利于复用等等. 因为 Docker 基于镜像创建容器的时候, 其镜像是共享的; 而且镜像里面的层如果已存在, 也无需再下载.
下面拉取一个 MongoDB 的镜像, 拉取的过程中可以看到:
图中红框范围内的就是 mongo 镜像的不同分层, 也就是镜像中的分层文件系统.
然而这些镜像层是只读的:
这样的限制多少看起来有点严格, 如果你想使用该镜像读写数据库怎么办? 或者记录 Log 到文件, 或者在容器运行的时候替换一些源代码该怎么办?
幸运的时候使用该镜像的容器会有可用于读写的 "薄薄" 一层:
从图中也可以看出容器和镜像的不同之处.
你可以在容器层进行写入, 但是如果容器被删除了, 那么可读写的这一层也会被删除.
这样就不太友好了, 而这时我们可以使用 Volume(卷).
下面就是这个问题, 如何把源码装进容器里?
1. 可以在制做镜像的时候把源码直接写入镜像.(这个先不考虑)
2. 把源码装进容器的可读写层.(这个是我要介绍的)
Volume 是什么?
Volume(卷)是容器中一个特别种类的目录, 通常叫做数据 volume, 顾名思义, 里面可以放置各种类型的数据, 例如代码, 日志文件, 数据文件等等.
Volume 可以在容器间被共享和复用. 可以让多个容器对同一个 volume 进行读写, 也可以让一个容器读写多个 volume.
对镜像的更新并不会影响 volume.
Volume 是被持久化的, 即使容器删除了, 它仍然还在.
可以这样去理解 Volume, 如果有一个容器, 那么我们可以在这个容器里面定义一个 Volume:
那么想要写到哪里去呢?
可以让 Docker 自己搞定, 或者你也可以自定义.
让 Docker 决定写入的位置
先介绍第一种情况, 当你写入到 volume 的时候, 比如在 Docker 容器里的代码对 / var/www 做了一个写入的操作, 那该目录其实就是你 docker host 里面的一个装载的文件夹 (mounted folder) 的别名. Docker host 也就是容器的宿主, 如果你使用的是 Linux 系统或 Windows 2016 及以上版本的系统, 那么该宿主就是操作系统. 容器也就是运行在该系统上.
那么在这个例子里, 我们写入的这个 volume, 它可以不是容器的可读写层, 它实际上可以写入 docker host 的装载的文件夹, 也就是操作系统的文件夹. 即使你把容器删除了, docker host 里的文件夹仍在健在.
通常我们使用如下命令来运行容器:
docker run -p 8000:80 microsoft/dotnet-samples:aspnetapp
而我们可以使用 - v 参数来指定 volume:
docker run -p 8000:80 -v /var/www microsoft/dotnet-samples:aspnetapp
这样的话,/var/www 只是容器 Volume 的别名, 实际被写入的区域在 Docker Host 里, docker 会自动的创建这个区域.
可以使用 docker inspect 容器名这个命令来查看相关的路径.
执行该命令后的结果中会显示如下部分 Mounts:
其中 Destination 是 volume 在容器里的地址(别名), 而 Source 则是 Volume 在宿主中的地址.
以上这部分介绍的就是让 Docker 来创建写入的目录.
自定义写入的位置
下面讲一下如何自定义这个目录的地址.
这样就对我们开发写代码比较友好了, 我的代码存放于 Windows/Mac 系统中, 然后我们让 Volume 读写我们代码所在的区域.
那么应该使用哪个 Docker 命令呢?
docker run -p 8000:80 -v ${PWD}:/var/www microsoft/dotnet-samples:aspnetapp
使用 - v 在容器里创建一个 volume, 它在容器的地址是 / var/www, 但是当你对它进行读写操作时, 它实际上找的是宿主的地址, 在这里也就是当前的工作目录(curent working directory).
如果你这时再执行 docker inspect 命令, 其结果大概如下:
把 ASP.NET Core 的源码连接到 Volume
首先使用 dotnet cli 或者 VS 建立一个 ASP.NET Core 项目:
然后使用 dotnet run 测试一下网站是否能正常运行:
接下来看看这个 ASP.NET Core 网站如何与 Volume 联系在一起.
首先下载 aspnetcore-build 镜像: docker pull microsoft/dotnet:2.1-sdk
下载完镜像之后, 就需要创建容器和 Volume 了, 不过在此之前先打开命令行, 进入 ASP.NET Core 项目源码的目录:
然后执行下面的命令(Windows 10 Powershell):
docker run -it -p 8080:5001 -v ${PWD}:/App --workdir "/app" microsoft/dotnet /bin/bash
这句话里 - it 参数表示进入交互模式
-p 8080:5001 表示把容器里的 5001 端口映射给宿主的 8080 端口.
-v 表示创建 volume
${PWD}是指宿主当前的目录.
${PWD}:/App 就是把容器里的 / App 文件夹连接到了宿主系统里的当前文件夹, 而容器里的 / App 目录就是应用程序将要运行的位置.
--workdir "/app" 表示容器里当前的工作目录是 / App.
然后使用 microsoft/dotnet 这个镜像.
最后使用 / bin/bash 返回一个终端, 以便让我与容器里进行交互.
执行命令后, Docker 可能会有提示需要共享一个目录, 点击确认即可.
然后我就会进入 Container 了:
进入容器之后, 我就可以执行 dotnet restore, dotnet build 等等命令了:
当然了, 可以执行 dotnet run:
然而这时候, 我访问本机 (宿主) 的 localhost:8080, 确无法显式页面.
首先为了简便, 先把 HTTPS 重定向相关的内容去掉.
然后要让应用监听任意地址的 5001 端口:
然后再次运行 dotnet run.
随后在宿主系统的浏览器打开 http://localhost:8080 即可打这个 ASP.NET Core 的 web 应用了:
来源: https://www.cnblogs.com/cgzl/p/9985656.html