ASP.NET Core 2.0 : 九.从Windows发布到CentOS的跨平台部署
本文聊一下如何在Windows上用VS开发并发布, 然后将其部署到CentOS上。对于我们一些常在Windows上逛的来说,CentOS用起来还真有些麻烦。MSDN官方有篇文章大概讲了一下(链接),按照MSDN上面的例子用vs创建个hellomvc项目,还是踩了好多坑,将整个过程和遇到的坑说一下,希望对有需要的朋友有所帮助。(ASP.NET Core系列目录)
本文主要内容:
1.工具准备
2.CentOS 上安装.NET Core环境
3.Windows上用VS发布项目
4.项目运行测试
5.安装并配置Apache
6.创建service管理应用
7.其他注意事项
8.独立部署(SCD)
9.2018.5.8文章更新:Visual Studio 2017 15.7版本的项目发布提供了部署模式(框架依赖和独立部署)和目标运行时(win、osx、linux)的选择功能
示意图:
最近在阿里云上弄了个ECS玩,既然.NET Core跨平台了,也就选了个CentOS的系统,然后踩坑开始。
一、工具准备
Putty:阿里云提供了一个网页方式远程操作CentOS的命令行工具,没找到怎么粘贴,挺不好用的。这个是一个命令行的小软件,也省去了每次都要登录阿里云控制台的步骤。链接
FileZila:sftp工具,用于将windows上生成的发布包弄到CentOS上去。链接
二、CentOS 上安装.NET Core环境
安装.NET Core的环境有两种方式,SDK和Runtime,区别类似java的JDK和JRE。
官方提供的下载页面用Build Apps 和Run Apps描述这两个, 我们不需要在CentOS上编码, 所以安装Runtime就够了。
在页面的all downloads中找到CentOS对应的Runtime版本页面(链接)进行安装,这里要注意一下:
坑一:版本问题,看了一下自己的VS中项目的Microsoft.AspNetCore.All版本是2.0.6, 也就去找了Runtime的2.0.6版本, 否则容易出现某些组件在VS上的引用版本和CentOS上的环境中的版本不一致的错误。
通过Putty链接到CentOS服务器,按照该页面上的步骤执行如下命令:
sudo rpm --import https://packages.microsoft.com/keys/microsoft.asc
sudo sh -c 'echo -e "[packages-microsoft-com-prod]\nname=packages-microsoft-com-prod \nbaseurl= https://packages.microsoft.com/yumrepos/microsoft-rhel7.3-prod\nenabled=1\ngpgcheck=1\ngpgkey=https://packages.microsoft.com/keys/microsoft.asc" > /etc/yum.repos.d/dotnetdev.repo' sudo yum update
sudo yum install libunwind libicu
最后还有下面关键一步我执行后部署仍会有提示某包找不到的问题,
sudo yum install dotnet-runtime-2.0.
在github上看到这样一段话:
Linux
On supported Linux systems, register the Microsoft Product feed as described above and install dotnet-hosting-2.0. using your package manager. This will also install the .NET Core Runtime and other required packages.
后来测试了一下不安装dotnet-runtime-2.0.6而是安装dotnet-hosting-2.0.6成功。
sudo yum install dotnet-hosting-2.0.
三、Windows上用VS发布项目
右键项目选择发布,默认情况下是FDD(依赖框架部署),发布生成的内容不包含依赖的框架内容,将依赖上文安装的runtime。
在CentOS上创建个文件夹, 通过FileZila将发布的文件上传到该文件夹。
参考创建目录命令: mkdir -p /var/aspnetcore/hellomvc
四、项目运行测试
执行命令运行上传后的项目:
dotnet /var/aspnetcore/hellomvc/hellomvc.dll
我们都知道,默认情况下,项目采用的事5000端口,我运行项目时遇到了端口冲突,可能是被占用了吧,VS中修改一下Program.cs, 将端口改为常用的8080
public static IWebHost BuildWebHost(string[] args) =>
WebHost.CreateDefaultBuilder(args)
.UseUrls("http://*:8080")
.UseStartup<Startup>()
.Build();
重新发布并上传,执行上面的命令成功,提示Kestrel开始监听8080端口。
浏览器访问一下http://ip:8080
结果如上图很怪异,坑二出现,按F12查看一下提示找不到xxx.css xxx.js等,通过FileZila确认对应的css和js文件都已成功上传在指定位置。
第一感觉是没有执行UseStaticFiles(), 确认了一下已执行。接着又怀疑是目录大小写问题,一 一排除, 均正常。
后来先cd到发布目录,再次执行,终于成功。
cd /var/aspnetcore/hellomvc
结果如我们熟悉的下图:
五、安装并配置Apache
安装Apache,并配置反向代理, 将80端口请求转给上面的8080端口由Kestrel处理。
安装并启动Apache
sudo yum -y install httpd mod_ssl
sudo systemctl start httpd
访问一下http://ip ,页面是Apache的默认页面,安装成功。
配置代理,创建并打开文件hellomvc.conf:
nano /etc/httpd/conf.d/hellomvc.conf
nano是一个文本编辑工具,如果提示 nano: command not found 可能nano没有安装
执行 yum install nano 命令安装即可。
hellomvc.conf文件内写入如下内容:
<VirtualHost *:>
ProxyPreserveHost On
ProxyPass / http://127.0.0.1:8080/
ProxyPassReverse / http://127.0.0.1:8080/
ServerName www.example.com
ServerAlias *.example.com
ErrorLog ${APACHE_LOG_DIR}hellomvc-error.log
CustomLog ${APACHE_LOG_DIR}hellomvc-access.log common
</VirtualHost>
重启Apache服务并将该服务设置为自动启动:
sudo systemctl restart httpd
sudo systemctl enable httpd
再次通过 dotnet /var/aspnetcore/hellomvc/hellomvc.dll 将项目运行起来后,访问 http://ip 或者 http://ip:8080 均访问正常。
到现在可能有人比较疑惑, 既然之前的项目已经可以正常访问了,为什么还要用Apache?在项目中直接指定监听80端口不就已经OK? 因为这样做该服务直接占用了80端口, 但有些情况下,我们需要将来自不同域名的访问指定到不同的端口处理,例如可以将a.com的请求指定到8080,将b.com的请求指定到8081. 当然, 如果没有这样的需求,直接用Kestrel做服务而不用反向代理。
另外每次通过命令 dotnet xxx.dll 的方式来启动也不是个很好的体验,我们可以创建个service来管理它, 这也有点向windows的service。
六.创建service管理应用
再次用nano创建文件:
sudo nano /etc/systemd/system/kestrel-hellomvc.service
文件内容如下:
[Unit]
Description=Example .NET Web API App running on CentOS [Service]
WorkingDirectory=/var/aspnetcore/hellomvc
ExecStart=/usr/local/bin/dotnet /var/aspnetcore/hellomvc/hellomvc.dll
Restart=always
# Restart service after seconds if dotnet service crashes
RestartSec=
SyslogIdentifier=dotnet-example
User=apache
Environment=ASPNETCORE_ENVIRONMENT=Production [Install]
WantedBy=multi-user.target
保存并启动服务:
systemctl enable kestrel-hellomvc.service
systemctl start kestrel-hellomvc.service
查看是否成功:
systemctl status kestrel-hellomvc.service
在此处我遇到了问题,提示出错,..........(code=exited, status=203/EXEC).............. kestrel-hellomvc.service failed。坑三出现,又是各种搜索,后来发现msdn中提供的上面的kestrel-hellomvc.service文件内容中的 ExecStart=/usr/local/bin/dotnet 在我的CentOS系统中不存在,通过 which dotnet 查看我的系统中是在 /usr/bin/dotnet ,修改kestrel-hellomvc.service重新执行 systemctl start kestrel-hellomvc.service 提示成功。注意修改该文件后会提示先执行 systemctl daemon-reload 重新加载。
至此,主要工作均已完成。
七.其他注意事项
A.kestrel-hellomvc.service中的User=apache
在安装Apache之前,通过 dotnet /var/aspnetcore/hellomvc/hellomvc.dll 已经可以将项目运行起来了, 那时候就想先创建Service,因为觉得这与Apache无关, 结果service总是启动失败,后来才注意到了这个User=apache,这里要求这个User存在并且拥有相应的权限。由于对CentOS不熟悉,这点也绕了好久。
B.启用ForwardedHeaders中间件
由于采用了反向代理,需要启用ForwardedHeaders中间件转发,在Startup的Configure中添加如下代码,注意UseForwardedHeaders要用在UseAuthentication之前。(MSDN上的详细说明)
app.UseForwardedHeaders(new ForwardedHeadersOptions
{
ForwardedHeaders = ForwardedHeaders.XForwardedFor | ForwardedHeaders.XForwardedProto
}); app.UseAuthentication();
八.独立部署(SCD)
下面说一下独立部署(包含依赖项)的发布方式。
在VS中右击项目文件,注意是 .csproj 而不是 .sln ,选择编辑xxx.csproj,打开该文件:
<Project Sdk="Microsoft.NET.Sdk.Web"> <PropertyGroup>
<TargetFramework>netcoreapp2.</TargetFramework>
</PropertyGroup> <ItemGroup>
<PackageReference Include="Microsoft.AspNetCore.All" Version="2.0.6" />
</ItemGroup> <ItemGroup>
<DotNetCliToolReference Include="Microsoft.VisualStudio.Web.CodeGeneration.Tools" Version="2.0.3" />
</ItemGroup> </Project>
在PropertyGroup中添加RuntimeIdentifiers标签
<PropertyGroup>
<TargetFramework>netcoreapp2.</TargetFramework>
<RuntimeIdentifiers>win10-x64;centos.-x64</RuntimeIdentifiers>
</PropertyGroup>
win10-x64;centos.-x64 叫做.NET Core RID, 是一些固定的内容, 具体可选项见.NET Core RID的目录。
当我们再次发布的时候,在发布设置的目标运行时中就出现了这两个选项,我们可以根据需要部署的系统选择对应的RID后进行发布。
九.2018.5.8文章更新
Visual Studio 2017 15.7版本的项目发布提供了部署模式(框架依赖和独立部署)和目标运行时(win、osx、linux)的选择功能
ASP.NET Core 2.0 : 九.从Windows发布到CentOS的跨平台部署的更多相关文章
- Ubuntu & Docker & Consul & Fabio & ASP.NET Core 2.0 微服务跨平台实践
相关博文: Ubuntu 简单安装 Docker Mac OS.Ubuntu 安装及使用 Consul Consul 服务注册与服务发现 Fabio 安装和简单使用 阅读目录: Docker 运行 C ...
- Docker & Consul & Fabio & ASP.NET Core 2.0 微服务跨平台实践
相关博文: Ubuntu 简单安装 Docker Mac OS.Ubuntu 安装及使用 Consul Consul 服务注册与服务发现 Fabio 安装和简单使用 阅读目录: Docker 运行 C ...
- ASP.NET Core 2.0 多应用实现Cookie共享
前言 .NET Core 2.0 发布之后,在Authentication中间件部分,相关API有不少改动(官方文档),本文主要讲的就是实现应用Cookie共享,对Cookie中间件使用不了解的可以去 ...
- .NET跨平台之旅:将示例站点升级至ASP.NET Core 1.0
北京时间6月28日凌晨,微软发布了 .NET Core 1.0,详见新闻 .NET Core 1.0 正式发布了 ,ASP.NET Core 1.0 也随之一起发布了. 紧跟这次发布,我们将跑在 Li ...
- Asp.net Core 1.0.1升级到Asp.net Core 1.1.0 Preview版本发布到Windows Server2008 R2 IIS中的各种坑
Asp.net Core 1.0.1升级到Asp.net Core 1.1.0后,程序无法运行了 解决方案:在project.json中加入runtime节点 "runtimes" ...
- .NET Core & ASP.NET Core 1.0在Redhat峰会上正式发布
众所周知,Red Hat和微软正在努力使.NET Core成为Red Hat企业版Linux (RHEL)系统上的一流开发平台选项.这个团队已经一起工作好几个月了,RHEL对.NET有许多需求.今天在 ...
- ASP.NET Core 1.0 开发记录
官方资料: https://github.com/dotnet/core https://docs.microsoft.com/en-us/aspnet/core https://docs.micro ...
- 初识ASP.NET Core 1.0
本文将对微软下一代ASP.NET框架做个概括性介绍,方便大家进一步熟悉该框架. 在介绍ASP.NET Core 1.0之前有必要澄清一些产品名称及版本号.ASP.NET Core1.0是微软下一代AS ...
- 跨平台运行ASP.NET Core 1.0
前言 首先提一下微软更名后的叫法: ASP.NET 5 更名为 ASP.NET Core 1.0 .NET Core 更名为 .NET Core 1.0 Entity Framework 7 更名为 ...
随机推荐
- 编译GDAL使用最新的HDF库配置文件
HDF库最新版本中的动态库以及目录结构都发生了变化,导致按照之前的博客进行编译GDAL时,会出问题.使用HDF4版本为HDF4-4.2.10,HDF5的版本为HDF5-1.8.12.两个库的目录结构如 ...
- Android初级教程理论知识(第四章内容提供器)
之前第三章理论知识写到过数据库.数据库是在程序内部自己访问自己.而内容提供器是访问别的程序数据的,即跨程序共享数据.对访问的数据也无非就是CRUD. 内容提供者 应用的数据库是不允许其他应用访问的 内 ...
- [GitHub]第六讲:开源项目贡献流程
Github 是目前世界上最大的开源项目的托管交流平台.贡献开源项目的流程也是 Github 全力支持的,也一样是遵循 Github Flow,虽然跟前面团队合作流程会有一点差别.在团队内部,大家都是 ...
- 如何在Cocos2D 1.0 中掩饰一个精灵(六)
大熊猫猪·侯佩原创或翻译作品.欢迎转载,转载请注明出处. 如果觉得写的不好请告诉我,如果觉得不错请多多支持点赞.谢谢! hopy ;) 掩饰一个精灵:实现代码 打开HelloWorldLayer.m并 ...
- 使用HTML5拍照
原文连接地址: Camera and Video Control with HTML5 演示地址: HTML5拍照演示 翻译日期: 2013年8月6日 首先,我们看看HTML代码结构,当然,这部分的D ...
- linux 编译c程序与动态链接库
linux 下编译c程序与动态链接库 1 动态库h文件和c文件 1.1 h 文件: kaflog4c.h /** * kaflog4c.h */ #include <stdio.h> #i ...
- 我眼中的Linux设备树(一 概述)
一 概述设备树(Device tree)是一套用来描述硬件属相的规则.ARM Linux采用设备树机制源于2011年3月份Linux创始人Linus Torvalds发的一封邮件,在这封邮件中他提倡A ...
- ArrayList与Vector的区别
ArrayList与Vector的区别 相同 这两个类都实现了List接口. 他们都是有序集合. 不同 ArrayList实现不是同步的,Vector实现是同步的. ArrayList与Vector都 ...
- int*p[ ]与int(*p)[ ]的不同
举例说明: 1)int* p[2] 是一个指向int型的指针数组,即:p是包含两个元素的指针数组,指针指向的是int型. 可以这样来用: #include <iostream> using ...
- Python学习笔记 - 字符串和编码
#!/usr/bin/env python3 # -*- coding: utf-8 -*- #第一行注释是为了告诉Linux/OS X系统, #这是一个Python可执行程序,Windows系统会忽 ...