本文翻译自hans kilian的文章

creating a containerized .net core application in less than 10 lines of code

docker的一个优势是你可以在别人的容器之上创建你自己的容器。在这片文章我将向你展示怎么快速得创建一个包含.net core应用的docker容器。

我们需要的仅仅只是一台安装了docker的机器,并且能连接上internet。

创建一个目录并且在该目录中创建一个文件“dockerfile”。打开那个文件,粘贴一下的代码行,并且保存。

from microsoft/dotnet:2.1-sdk as build-env
workdir /app
run dotnet new razor
run dotnet publish -c release -o out
from microsoft/dotnet:2.1-aspnetcore-runtime-alpine
workdir /app
copy --from=build-env /app/out ./
entrypoint ["dotnet", "app.dll"]

在终端中执行命令 “docker build -t myapp .”

这行命令从当前目录的dockerfile文件创建了一个docker镜像并且给这个镜像取了一个名字叫做“myapp”的标签。

然后我们就可以通过输入命令“docker run -d -p 80:80 myapp”运行这个容器化的应用了。

然后当你打开你的浏览器并且导航到/你将看到下面显示的屏幕:

这是怎么运行的呢?

上边的那个dockerfile指定了多级构建,包含有两个部分,每个部分四行。第一部分为要运行的应用生成并编译了源码,第二部分把编译好的应用打包进一个我们能运行的容器中。多级构建在docker17.05中才开始有介绍,因此如果你要使用该特性的话你需要17.05或者更新的docker版本。

  • 第一行指出了我们将基于微软提供的.net core 2.1 sdk来构建我们想要的docker镜像。我们给.net core 2.1 sdk取个别名“build-env”,这在后边会用到。
  • 第二行中我们创建了一个工作目录“/app”。
  • 第三行中我们在上边创建的目录中执行命令“dotnet new razor”,这行命令使用razor pages创建了一个基本的asp.net应用程序所需要的所有的源代码。
  • 第四行中我们发布上边的应用到“out”目录。全路径是“/app/out”。“publish”命令足够智能,它可以在发布之前自动还原所需要的nuget包并且进行编译。

dockerfile中的最后四行将发布了的应用程序打包进一个只包含.net core运行时环境的docker镜像中。当我们运行这个应用的时候完全没有必要包含整个的sdk。我们想要运行的镜像越小越好。

第一行我们首先指定我们想要开始构建一个跟上一个不一样的docker镜像。这次我们将会使用基于包含了asp.net core运行时环境的alpine linux分支开始构建。alpine是一个非常小的linux发行版本,并且被广泛地使用与docker基础镜像中。

然后我们再次创建了一个工作目录“/app”,这跟第一次创建的“/app”不是同一个目录,因为我们现在正在构建一个新的docker镜像。

然后我们从第一个创建的镜像中复制应用的文件。“–from=build-env”选项指定了我们想要的是从第一个创建的镜像中复制。我们从第一个创建的镜像中复制了所有的“/app/out”目录下的文件到当前的目录/app

然后我们指定了容器的运行入口是dotnet 命令并且还要跟上参数“app.dll”。

当我们运行这个镜像的时候,我们指定了几个运行参数。第一个参数“-d”指定了该镜像应该在后台运行。第二个参数“-p 80:80”指定了容器中的80端口应该被映射到运行容器的机器的80端口上。如果你机器上的80端口被占用了,你可以使用其他端口进行映射。比如你想映射到运行docker的机器的8080端口,你可以使用“-p 8080:80”,然后你可以通过“”访问该应用。不管你映射到机器上的哪个端口,应用程序表现出来的是不变的,就像它一直使用的是80端口一样。

你可以使用docker命令“docker ps”查看当前运行的docker镜像。

你也可以使用“docker kill <name>”停止容器。

从这里我们将要进一步学习些什么?

当然了这不是一个有用的示例。为了让示例更加接近实际,你可以很容易地改变这个例子去容器化一个自定义的c#工程项目。假设你有一个子目录“code”,其中含有你的项目源码,你可以替换“run dotnet new razor” 为“copy ./code/ ./”,仅仅就改变这一行,你就可以构建你自定义的项目。或者你还可以从使用“git clone”命令从git上拉取项目。

在docker容器中构建你的解决方案的另外一个好处是你不需要担心你电脑上安装的sdk的版本冲突。如果你想尝试net core 2.2 preview,你可以很简单地使用下边的代码来使用2.2 的sdk和2.2的 asp.net 运行时环境:

from microsoft/dotnet:2.2.100-preview3-sdk as build-env
workdir /app
run dotnet new razor
run dotnet publish -c release -o out
from microsoft/dotnet:2.2.0-preview3-aspnetcore-runtime-alpine
workdir /app
copy --from=build-env /app/out ./
entrypoint [“dotnet”, “app.dll”]

如果你不喜欢这样的结果(2.2 preview现在似乎没有2.1好用),你不需要卸载任何的2.2的preview sdk,因为你的机器上从来没有安装过它。2.2 sdk仅仅只是安装在docker镜像之中的,仅仅只是下载下来并没有运行,除非你要求运行该镜像的时候。

如果你想查看其他的合适的.net docker镜像,你可以从这里开始

我希望这篇文章可以鼓励你尝试使用docker或者.net core,如果你从来没有尝试过的话。添加一个类似postgresql 数据库将会非常简单,因为这里已经有构建好的合适的docker镜像可以使用,你根本不需要任何的定制化。当你有多个需要相互之间进行通信的容器的时候,docker-compose是一个很棒的工具,它可以使用一个简单的命令加速并接管控制多个容器。