吉安网站推广,营养早餐网站的设计与制作,wordpress竖版图片尺寸,wordpress时钟本文工具准备#xff1a;
Docker for WindowsVisual Studio 2015 与 Visual Studio Tools for Docker或 Visual Studio 2017 需要在安装时选择“容器开发支持”#xff0c;如图#xff1a; Docker的思想是将不同的应用放在不同的容器中分开运行#xff0c;如运行.NetCore …本文工具准备
Docker for WindowsVisual Studio 2015 与 Visual Studio Tools for Docker或 Visual Studio 2017 需要在安装时选择“容器开发支持”如图 Docker的思想是将不同的应用放在不同的容器中分开运行如运行.NetCore Web的典型组合Nginx.NETCore(kestrel)我们应该使用一个容器运行Nginx另一个容器运行.NETCore App。
之前还陷入一个误区一直在研究如何将dotnet与Nginx配置实现到一个Dockerfile中后来了解到Docker Compose才知道这两者应该分开到不同的容器。
服务器端安装Docker与Docker Compose
见此文
DotnetCore的Dockerfile
一般来说通过Visual Studio 2015 Tools for Docker给项目添加Docker支持后项目中就会有Dockerfile与docker-compose.xml的初始模板。只需要修改其中的内容适应我们的项目即可。Visual Studio的2017可以在新建项目时或建立项目以后选择添加Docker支持。
Visual Studio 2017稍有不同的是其将docker-compose.yml文件作为解决方案级文件来管理。这对于组合多个项目是很有帮助的。如图 本文最初编写时项目使用的Visual Studio 2015所以docker-compose.yml还都是在Web项目中。但下文的设置对这两种组织方式都支持稍微调整一下路径即可。
首先是默认Dockerfile的文件我们将其配置为运行dotnet
FROM microsoft/aspnetcore:1.0
ENTRYPOINT [dotnet, orgname.projname.WebApi.dll]
ARG source.
WORKDIR /app
EXPOSE 5000
COPY $source /app
aspnetcore这个Iamge有1.0和1.1两个版本根据项目所使用的.NETCore版本自行更换
单独测试下这个Dockerfile的image生成
docker rmi orgname/projname.core:testdocker build --rm -t orgname/projname.core:test -f Dockerfile .
测试下镜像作为容器运行
docker run --name projname.core.inst -p 5000:5000 orgname/projname.core:test
测试完成后把所有测试产物如镜像和容器都删除。
docker stop projname.core.inst
docker rm -f projname.core.inst
docker rmi orgname/projname.core:test
在刚开始编写Dockerfile打包镜像时可能会反复进行生成运行容器的步骤。为了方便测试楼主把这些脚本整合成了一个buildtest.bat如下。
echo onSET /p app.NETCoreWeb(d)Nginx(n)SET /p job生成并运行(r)清理(c)SET /p mode交互运行(i)后台运行(b)if %app%d (SET contNameprojname.core.instSET imagNameorgname/projname.core:testSET fileDockerfile
)if %app%n (SET contNameprojname.core.pub.instSET imagNameorgname/projname.core.pub:testSET fileDockerfile-Nginx
)if %mode%i (SET operate-it
)if %mode%b (SET operate-d)if %job%r (GOTO Build)if %job%c (GOTO Clear):Builddocker stop %contName%
docker rm -f %contName%
docker rmi %imagName%
docker build --rm -t %imagName% -f %file% .docker run %operate% --name %contName% -p 5000:5000 -e ASPNETCORE_ENVIRONMENTStaging %imagName% GOTO End:Cleardocker stop %contName%
docker rm -f %contName%
docker rmi %imagName%
docker ps -a
docker imagesGOTO End:End
楼主一般用Docker for Windows做测试自然也就写了批处理的脚本后来这篇文章慢慢的攒了一段时间才最终完成为了调试方便转投PowerShell。包括这个脚本在内的本文提供的几个脚本都非常好用谁用谁知道。
Nginx的Dockerfile
首先是Nginx的配置文件这是比较重要的一个配置Nginx的Docker Image生成到时候会复制这个文件到Nginx Docker Image内。
本文介绍普通的80端口的转发配置如下
server { listen 8081; location / { proxy_pass http://core-app:5000; proxy_http_version 1.1; proxy_set_header Upgrade $http_upgrade; proxy_set_header Connection keep-alive; proxy_set_header Host $host; proxy_cache_bypass $http_upgrade;}}
注意 配置中的转发地址不再是localhost而是需要根据link所指定的服务/容器的别名来确定。这个link参数在下面有示例。这个涉及到Docker网络这是个非常复杂的话题。
注意nginx.conf需要ANSI编码且换行为Linux格式否则导入容器中可能会报错。可以使用Notepad编辑使用VS编辑可能会出问题
还可以配置Nginx使用HTTPS或者使用Nginx配置简单的负载均衡如果以后楼主有机会研究的话会再写文章分享。
测试下Nginx的Docker Image的生成
docker build --rm -t orgname/projname.core.pub:test -f Dockerfile-Nginx .
启动容器来测试
docker run --name projname.core.pub.inst -p 8081:8081 --link projname.core.inst:core-app orgname/projname.core.pub:test
注意link即指示链接到的之前创建的运行.net core的容器冒号后面部分是指定别名。这个别名就是前文Ngnix配置文件中所转发的地址。
如果启动Nginx容器后可以通过Nginx访问.NET Core Web App说明到此为止的配置都是正确的。可以继续配置docker compose了。
清理测试产物
docker stop projname.core.pub.inst
docker rm -f projname.core.pub.inst
docker rmi orgname/projname.core.pub:test
将docker相关文件添加到项目发布文件
(VS2015)编辑project.json文件中publishOptions-include的数组将Dockerfile、Dockerfile-Nginx、nginx.conf及docker-compose.yml添加到其中。
一般来说按照之前步骤添加“Docker Support”后插件会自动将相关文件添加到project.json的publishOptions中这一步进行确认就好。
(VS2017)在解决方案资源管理器中将Dockerfile、Dockerfile-Nginx、nginx.conf及docker-compose.yml包含在项目中。“复制到输出目录”选择“如果较新则复制”。
发布项目
使用下面命令发布项目
dotnet publish --framework netcoreapp1.0 --configuration release --output publish.linux
可以将这条命令保存为一个批处理文件如publish.linux.bat放到项目根目录下
编辑Docker Compose配置文件
docker compose配置文件基本上就之前用到的docker build和docker run命令的另一种表述形式
version: 3services:orgname.projname.webapi: image: orgname/projname.core:${TAG} build: context: . dockerfile: Dockerfile expose: - 5000 container_name: projname.core.inst environment: - ASPNETCORE_ENVIRONMENTDevelopment volumes: - ./log:/app/log:rw deploy: restart_policy: condition: always orgname.projname.webapi.pub: image: orgname/projname.core.pub:${TAG} build: context: . dockerfile: Dockerfile-Nginx ports: - 8081:8081 links: - orgname.projname.webapi:core-app container_name: projname.core.pub.instvolumes:orgname.projname.webapi:
注意服务orgname.projname.webapi中使用expose来暴露端口因为我们不需要将端口暴露给docker外部。另外我们也将日志输出到挂在到Docker的主机目录这样方便查看日志。
提示 强烈推荐使用version3版本的compose文件。version3中新增deploy选项可以实现docker run --restart选项的作用控制容器在失败等情况下自动重启从而保证服务的无人值守运行。compose选项详见此文档
构建Image
项目发布完成后进入发布文件夹publish执行下面的命令生成相关镜像
docker-compose build
提示可以在使用docker compose生成之前分别使用docker build单独生成dotnet core和nginx的镜像进行测试就像介绍Dockerfile那部分所述。
启动docker compose
确定compose生成好image后就可以启动服务容器了
docker-compose start
可以使用下面的命令将Build、Start一起完成。
docker-compose up
服务启动后可以通过Nginx服务访问.NET Core App。上面的命令会在前台运行并打印日志到控制台。如果需要在后台运行“服务”使用-d参数
docker-compose up -d
docker compose启动的也是普通的容器通过docker ps也可以看到compose启动的容器。
如果需要停止docker compose启动的服务使用
docker-compose down
注意服务的容器将被删除所有容器中的数据非主机挂载到容器目录下将丢失。
这一小节介绍的方式是在Docker for Windows中使用docker compose运行服务而实际情况下我们需要在服务器去运行docker compose具体方式后文有介绍。
其它相关命令
查看compose相关服务运行状态docker-compose ps重启compose中的服务docker-compose restart
环境
在程序开发中在不同环境下使用不同的配置是很常见的情况。如.NET Core就定义了三种默认的环境 - Development、Staging和Production。体现在配置文件上有appsettings.json、appsettings.Staging.json及appsettings.Production.json等文件楼主一般将其分别用作开发、测试和生产环境的配置相信大部分人也都是这么干的。.NET Core Web应用会根据一个名为ASPNETCORE_ENVIRONMENT的环境变量来判断应用所处的环境。所以我们需要做的就是在生成镜像时将这个变量传入。docker compose的environment就是做这个用的比如我们将docker-compose.yml文件中orgname.projname.webapi这个服务的定义改为
environment: - ASPNETCORE_ENVIRONMENTStaging
则我们的.NETCore应用将以Staging环境运行并使用appsettings.Staging.json这个配置文件。然后我们利用VS Tool for Docker创建的其它两个文件docker-compose.dev.debug.yml和docker-compose.dev.release.yml来实现不同环境的配置分离VS2017中这两个文件中的dev改为vs。
其实那两个文件是用于VS集成的Docker调试和发布用的不过我这里不打算依赖工具而是通过命令行的形式完成工作。所以删除两个文件中原有的内容并改为我们自己所需。
要使两个配置文件共同工作最主要的还是靠docker compose对多配置文件的支持。其-f选项可以设置多次docker compose会把其中的选项叠加。如
docker-compose.exe -f docker-compose.yml -f docker-compose.dev.debug.yml build
下面来分别看下用于不同环境的配置文件首先是docker-compose.dev.debug.yml
version: 3services:orgname.projname.webapi: environment: - ASPNETCORE_ENVIRONMENTStaging env_file: - staging.env
其中的env_file指定的staging.env用于演示由于我们的例子需要配置的环境变量很少所以无需使用这个文件。文件的格式很简单就是键值对的格式
ENVVAL
注意这个文件要使用ANSI编码不然会因为编码问题导致实际定义的变量和期望定义的变量不一致。
提示可以使用下面的命令确认compose执行时的配置
docker-compose.exe -f docker-compose.yml -f docker-compose.dev.debug.yml config
这对于检查环境变量等设置是否正确很有帮助。在确认无误后再进行build或up操作。上面说得env文件的编码问题就是通过config命令查出来的。(下文的composebuild.bat集成了这个检查的功能)
然后是docker-compose.dev.release.yml内容也差不多
version: 3services:orgname.projname.webapi: environment: - ASPNETCORE_ENVIRONMENTProduction
另外我们还要给测试和生产环境的image打上不同的tag。这个需要修改一下之前编辑的docker-compose.yml中服务定义中image那个配置
image: orgname/projname.core:${TAG}image: orgname/projname.core.pub:${TAG}
将它们的版本号都改为插值计算的方式。docker compose可以由当前执行的环境中获取这些值的定义。比如shell中EXPORT的变量或者cmd中SET的变量。在Windows下我们借助如下的批处理composebuild.bat来帮助定义这个变量并执行docker compose命令
echo offSET /p mode测试(t)发布(p)SET /p job检查(c)生成(b)运行(u)清理(r)if %job%c (SET operateconfig
)if %job%b (SET operatebuild)if %job%u (SET operateup
)if %mode%t (SET TAGtest)if %mode%p (SET TAG1.0.0)if %job%r (
docker rmi orgname/projname.core.pub:%TAG%
docker rmi orgname/projname.core:%TAG%GOTO End)if %mode%t (SET fileymldocker-compose.dev.debug.ymlGOTO Build)if %mode%p (SET fileymldocker-compose.dev.release.ymlGOTO Build)
:Builddocker-compose -f docker-compose.yml -f %fileyml% %operate%:End
这个脚本有一个小问题在后续章节会介绍将Image推送到注册中心而推送到注册中心需要一个tag操作。而这个脚本删除这些被tag的Image只会解除tag而不删除Image最终导致本地残留很多无tag的Image。可以全部工作结束后使用下面的PowerShell命令统一删除
Get-ContainerImage | ? {$_.RepoTags -eq $null} | foreach { Remove-ContainerImage $_.ID }
运行这个命令需要安装Docker-PowerShell可参见此文
运行这个批处理选一下需要运行的选项便可以通过docker compose在不同的环境下生成镜像或启动服务。
注意所有这些文件都记得加入project.json中(VS2015)包含到项目并复制到输出目录(VS2017)
添加到镜像仓库
这是可选步骤也可以在把Dockerfile和发布文件上传到服务器并在服务器上生成镜像。见总结。
可以使用Harbor构建一个私有Docker仓库。Harbor相对于Docker官方库就像GitLab相对于GitHub。Harbor的安装和基本使用参见此文。
Docker的Image进行分层存储所以第一次push到私有仓库的上传量比较大之后将只是推送改变的层。数据传输量比较小。push操作的操作的基本部分在那篇介绍Docker的文章中有介绍。这里我们只是给出脚本可以按照提示执行即可嗯这是一个PowerShell脚本ImagesPush.ps1不再是批处理了。
$reghostregister-host$regportregister-port$dockerregister$($reghost):$($regport)echo 测试(t)发布(p)$operationRead-Host
Switch($operation)
{ t {$tagtest} p {$tag1.0.0}
}#docker login $dockerregisterdocker tag orgname/projname.core:$tag $dockerregister/orgnameprojname/projname.core:$tag
docker tag orgname/projname.core.pub:$tag $dockerregister/orgnameprojname/projname.core.pub:$tagdocker push $dockerregister/orgnameprojname/projname.core:$tag
docker push $dockerregister/orgnameprojname/projname.core.pub:$tag
从镜像仓库获取并启动服务
通过Docker启动服务docker-compose.yml是必备的。我们执行docker-compose命令的目录下必须有这个文件不然分分钟报错。我们之前那个docker-compose.yml文件所创建容器的镜像是通过Build Dockerfile来得到的这里我们要新建这样的一个docker-compose.yml其使用一个现成的Image来启动容器。我们新建一个名为docker-compose.server.yml的文件不要怀疑名字错了。
version: 3services:orgname.projname.webapi: image: {REG}/orgnameprojname/projname.core:{TAG} expose: - 5000 container_name: projname.core.inst environment: - ASPNETCORE_ENVIRONMENT{ENV} volumes: - ./log:/app/log:rw deploy: restart_policy: condition: always orgname.projname.webapi.pub: image: {REG}/orgnameprojname/projname.core.pub:{TAG} ports: - 8081:8081 links: - orgname.projname.webapi:core-app container_name: projname.core.pub.instvolumes:orgname.projname.webapi:
与之前文件的最大不同这个配置没有了build这个小节。而镜像就需要从注册中心拉取直接上脚本(ImagesPull.ps1)然后稍作解释
$reghostregister-host$regportregister-port$dockerregister$($reghost):$($regport)echo Test(t) Publish(p)$operationRead-HostSwitch($operation)
{ t {$tagtest;$envstrStaging} p {$tag1.0.0;$envstrProduction}
}
docker login $dockerregisterdocker pull $dockerregister/orgnameprojname/projname.core:$tagdocker pull $dockerregister/orgnameprojname/projname.core.pub:$tagni docker-compose.yml -ItemType File -Force
(get-content docker-compose.server.yml) -replace {TAG},$($tag) -replace {REG},$($dockerregister) -replace {ENV},$($envstr) | set-content docker-compose.yml# remove old containerdocker-compose down docker-compose up
是的这是一个PowerShell脚本PowerShell现在也可以用Linux虽然还处在测试状态。在CentOS7.3中有一堆显示方面的bug中文支持也没有所以上面的脚本没有中文主要功能方面还是很正常的。Linux上安装PowerShell可见此文档。脚本中首先登录镜像仓库并下载镜像然后按照用户输入将docker-compose.server.yml进行插值得到需要的docker-compose.yml文件最后启动docker compose。
网络
网络方面Docker-Conpose为应用创建一个子网络Docker-Compose将每个Service作为一个容器实例并加入到这个网络中网络中的容器可以彼此访问。容器间以容器名称作为主机名来互相访问。Docker网络这块水很深楼主对这个了解几乎没有。
总结
借用此部分墙裂推荐Cmder这个神奇虽然时不时的会有光标错位中文重叠等问题但绝对是取代自带控制台的必备工具。
最后总结一下在上面的所有配置文件准备妥当后每次修改得到新版本后只需要执行下列步骤
方式1
执行publish.linux.bat生成项目发布文件运行buildtest.bat验证Dockerfile正常工作运行composebuild.bat根据提示选择在测试环境还是发布环境下验证配置、生成镜像使用ImagesPush.ps1将生成的镜像发布到Harbor在服务器上使用ImagesPull.ps1拉取镜像并使用compose启动服务。先要把docker-compose.server.yml放到与ImagesPull.ps1服务器端相同目录下
方式2
执行publish.linux.bat生成项目发布文件将所有文件上传到服务器在服务器端使用composebuild.bat来运行服务。目前楼主没有使用这种方法所以没有将这个脚本用shell或者powershell重写
如果您有更好的实现方法欢迎评论区指点一二。
原文地址http://www.cnblogs.com/lsxqw2004/p/6709766.html.NET社区新闻深度好文微信中搜索dotNET跨平台或扫描二维码关注