和这种蛋糕一样,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应用了:

Docker & ASP.NET Core (1):把代码连接到容器的更多相关文章

  1. Docker & ASP.NET Core (4):容器间的连接

    第一篇:把代码连接到容器 第二篇:定制Docker镜像 第三篇:发布镜像 Docker容器间的连接 Docker提供了两种方式可以用来做容器间的连接/通信: Legacy Linking:这种方式使用 ...

  2. Docker & ASP.NET Core (5):Docker Compose

    第一篇:把代码连接到容器 第二篇:定制Docker镜像 第三篇:发布镜像 第四篇:容器间的连接 Docker Compose简介 Compose是一个用来定义和运行多容器Docker应用的工具.使用C ...

  3. Docker & ASP.NET Core (3):发布镜像

    第一篇:把代码连接到容器 第二篇:定制Docker镜像 上一篇文章最后有个问题,定制的镜像无法正常运行: 这可能是由于无法找到要运行的dll引起的问题. 之前的Dockerfile的文档我是按照微软的 ...

  4. Docker & ASP.NET Core (2):定制Docker镜像

    上一篇文章:把代码连接到容器 Dockerfile 在Docker的世界里,我们可以通过一个叫Dockerfile的文件来创建Docker镜像,随后可以运行容器. Dockerfile就是一个文本文件 ...

  5. Docker & ASP.NET Core 教程

    第一篇:把代码连接到容器 第二篇:定制Docker镜像 第三篇:发布镜像 第四篇:容器间的连接 第五篇: Docker & ASP.NET Core (5):Docker Compose AS ...

  6. Azure DevOps+Docker+Asp.NET Core 实现CI/CD(二.创建CI持续集成管道)

    前言 本文主要是讲解如何使用Azure DevOps+Docker 来实现持续集成Asp.NET Core项目(当然 也可以是任意项目). 上一篇: Azure DevOps+Docker+Asp.N ...

  7. Ubuntu & GitLab CI & Docker & ASP.NET Core 2.0 自动化发布和部署(2)

    上一篇:Ubuntu & GitLab CI & Docker & ASP.NET Core 2.0 自动化发布和部署(1) 服务器版本 Ubuntu 16.04 LTS. 本 ...

  8. Jenkins + Docker + ASP.NET Core自动化部署

    本来没想着要写这篇博客,但是在实操过程中,一个是被网络问题搞炸了心态(真心感觉网络能把人搞疯,别人下个包.下个镜像几秒钟搞定,我看着我的几KB小水管真是有苦说不出),另一个就是这里面坑还是有一些的,写 ...

  9. 【译】在 ASP.NET 和 ASP.NET Core 之间共享代码

    原文 | Ken 翻译 | 郑子铭 随着 .NET 6 的发布,使用 ASP.NET Core 可以获得更多好处.但是将现有代码迁移到 ASP.NET Core 通常听起来像是一项巨大的投资.今天我们 ...

随机推荐

  1. 由一条sql语句想到的子查询优化

    摘要:相信大家都使用过子查询,因为使用子查询可以一次性的完成很多逻辑上需要多个步骤才能完成的SQL操作,比较灵活,我也喜欢用,可最近因为一条包含子查询的select count(*)语句导致点开管理系 ...

  2. Java中的Unsafe类111

    1.Unsafe类介绍 Unsafe类是在sun.misc包下,不属于Java标准.但是很多Java的基础类库,包括一些被广泛使用的高性能开发库都是基于Unsafe类开发的,比如Netty.Hadoo ...

  3. Docker 服务

    1.  Docker服务 作为一名后端攻城狮,对“服务”这个概念一定不陌生.比如,我们做一个会员系统,它可能会需要数据库.缓存.消息队列,这些都是中间件服务,除此以外可能还需要依赖其它的Dubbo服务 ...

  4. 【STM32H7教程】第4章 STM32H7工程模板建立(MDK5)

    完整教程下载地址:http://forum.armfly.com/forum.php?mod=viewthread&tid=86980 第4章   STM32H7工程模板建立(MDK5) 本章 ...

  5. 频率学派与贝叶斯学派(先验分布与后验分布,MLE和MAP)

    频率学派(古典学派)和贝叶斯学派是数理统计领域的两大流派. 这两大流派对世界的认知有本质的不同:频率学派认为世界是确定的,有一个本体,这个本体的真值是不变的,我们的目标就是要找到这个真值或真值所在的范 ...

  6. Docker 配置国内镜像加速器,加速下载速度

    文章首发自个人微信公众号:小哈学Java 个人网站地址:https://www.exception.site/docker/docker-configuration-of-mirror-acceler ...

  7. vue中的 ref 和 $refs

    如图,ref 被用来给元素或子组件注册引用信息.引用信息将会注册在父组件的 $refs 对象上.如果在普通的 DOM 元素上使用,引用指向的就是 DOM 元素:如果用在子组件上,引用就指向组件实例: ...

  8. 一个Mini的ASP.NET Core框架的实现

    一.ASP.NET Core Mini 在2019年1月的微软技术(苏州)俱乐部成立大会上,蒋金楠老师(大内老A)分享了一个名为“ASP.NET Core框架揭秘”的课程,他用不到200行的代码实现了 ...

  9. 带着新人看java虚拟机06(多线程篇)

    其实多线程还有很多的东西要说,我们慢慢来,可能会有一些东西没说到,那就没办法了,只能说尽量吧! 1.synchronized关键字 说到多线程肯定离不开这个关键字,为什么呢?因为多线程之间虽然有各自的 ...

  10. 『神坑』DotNetty 内存泄漏 解决办法

    背景 近来在用 DotNetty 实现一个文件上传下载的同步服务. 其中:客户端下载服务端的文件,客户端多次请求,从服务端将文件分片下载下来,追加到本地磁盘. —— 非常简单的代码,都写了几十次了,驾 ...