有缘遇到你 發表於 2018-11-20 20:47:00

Docker & ASP.NET Core (1):把代码连接到容器

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

</div>
<div id="MySignature" role="contentinfo">
    <p><img src="https://img2022.cnblogs.com/blog/986268/202201/986268-20220121212852077-392691317.png" width="500" height="182.45" alt="杨旭技术专栏"></p><br><br>
来源:https://www.cnblogs.com/yangxu-pro/p/9985656.html
頁: [1]
查看完整版本: Docker & ASP.NET Core (1):把代码连接到容器