.Net Core部署到CentOS

  本文基于初次或再次尝试部署.Net Core应用到Linux服务器上,我尝试后自我总结的经验一个简单的Demo,尝试部署在Linux服务器上和跨服务器访问数据库。

 

一、环境介绍

  1、本地使用Visual Studio 2017开发,使用的.NetCore SDK版本为2.1.4;

  2、数据库使用的MSSQLServer,部署在阿里云服务器上,WindowServer;

  3、Demo部署在腾讯云服务器上,CentOS系统;

  4、CentOS中安装了.net CoreSDK 2.1.4(开发和部署的环境最好一致,我在这里掉过坑)

  5、代码管理通过Git来进行,在本地安装了Git,在CentOS中也安装了Git;

  6、利用jexus进行反向代理;

 

二、项目介绍

  建立一个Asp.Net Core项目,这个建立过程就不贴图了,步骤简单。此处还没有使用到Docker,建立项目时,没有勾选Docker支持

  

  整个项目从搭建到运行的简略过程

  

  1、建立实体,只加了一个User类,里面就是基本的用户名、密码、地址和创建日期。

public class User
    {
        public User()
        {
            this.CreateDate = DateTime.Now;
        }

        public int Id { get; set; }
        public string UserName { get; set; }
        public string Password { get; set; }
        public string Address { get; set; }
        public DateTime CreateDate { get; set; }
    }

   2、接下来是建立DbContext

    public class HDShopDbContext:DbContext
    {
        public HDShopDbContext(DbContextOptions<HDShopDbContext> options)
            :base(options)
        {

        }
        protected override void OnModelCreating(ModelBuilder modelBuilder)
        {
            //modelBuilder.Entity<User>().ToTable("xxxx");
        }

        public virtual  DbSet<User> User { get; set; }
    }

  3、配置服务,在项目中已经默认的将EFCore相关的Nuget包加入进来了,在StartUp.cs文件中进行服务配置,使用

  services.AddDbContext<HDShopDbContext>(d => d.UseSqlServer(Configuration.GetConnectionString("Default")));
 public class Startup
    {
        public Startup(IConfiguration configuration)
        {
            Configuration = configuration;
        }

        public IConfiguration Configuration { get; }

        // This method gets called by the runtime. Use this method to add services to the container.
        public void ConfigureServices(IServiceCollection services)
        {
            services.AddDbContext<HDShopDbContext>(d => d.UseSqlServer(Configuration.GetConnectionString("Default")));
            services.AddMvc();
        }

        // This method gets called by the runtime. Use this method to configure the HTTP request pipeline.
        public void Configure(IApplicationBuilder app, IHostingEnvironment env)
        {
            if (env.IsDevelopment())
            {
                app.UseBrowserLink();
                app.UseDeveloperExceptionPage();
            }
            else
            {
                app.UseExceptionHandler("/Home/Error");
            }

            app.UseStaticFiles();

            app.UseMvc(routes =>
            {
                routes.MapRoute(
                    name: "default",
                    template: "{controller=Home}/{action=Index}/{id?}");
            });
        }
    }

  此处,解释下Configure和ConfigureService的区别:

  Configure配置的是中间件,整个服务运行过程中,是以中间件形式进行跳转,从第一个中间件到第二个中间件,完成最后一个中间件要求后返回到上一个中间件,而中间件数量的多少是我们可以去控制的,如果有什么功能需要加入,我们也可以以中间件的形式控制运行,Configure方法即时控制中间件的。

  ConfigureService配置的是整个运行中所用到的各种框架,注入等等,在Configure方法前先被调用。

  具体可看@行动派Xdpie https://www.cnblogs.com/vipyoumay/p/5640645.html

  在appsetting.json中配置连接字符串,由于Linux中不能安装SQLServer除2017以外的其他版本我便将另一台WindowServer服务器数据库弄过来用了,SQLServer2017对于Linux服务器配置要求很高。

  记得连接字符串名字不要弄错了  ! ! !

  4、为了方便让EFCore的CodeFirst在我们部署完,启动后就自动创建数据库,我们准备点种子数据

public class DbInitializer
    {
        public static void Initialize(HDShopDbContext context)
        {
            context.Database.EnsureCreated();
            if (context.User.Any())
            {
                return;
            }
            var users = new User[]
            {
                new User(){Address="测试",UserName ="1测试1",Password="123456"},
                new User(){Address="测试",UserName ="2测试2",Password="123456"},
                new User(){Address="测试",UserName ="3测试3",Password="123456"},
                new User(){Address="测试",UserName ="4测试4",Password="123456"},
                new User(){Address="测试",UserName ="5测试5",Password="123456"},
                new User(){Address="测试",UserName ="6测试6",Password="123456"},
            };
            foreach (var user in users)
            {
                context.Add(user);
            }
            context.SaveChanges();
        }
    }

  5、编译运行,测试下本地运行是否成功。我这就不将我的测试结果展示出来了。

  6、进入Linux服务器,下载好Git,通过配置好SSH公钥,在GitHub或是码云上做个记录。

   Linux服务器上配置Git的教程:https://www.cnblogs.com/yolo-bean/p/7808767.html

  7、Linux服务器安装jexus,通过如下命令安装

curl https://jexus.org/release/x64/install.sh|sh

   安装成功后会提示:OK, Jexus has been installed in /usr/jexus.

   至此,作为反向代理的jexus安装完毕,以前需要安装jexus+mono,现在最新版本的jexus已经将mono合并进去了,形成了现在的jexus独立版.

  8、安装.Net Core环境

   我的建议是先查看开发环境的.Net Core SDK版本,不然如果服务器上的环境和开发环境存在版本差异的话会出现一些坑,比如我遇到的一个坑

Error:
  An assembly specified in the application dependencies manifest ({projectName}.deps.json) was not found:
    package: 'Microsoft.AspNetCore.Antiforgery', version: '2.0.2'
    path: 'lib/netstandard2.0/Microsoft.AspNetCore.Antiforgery.dll'
  This assembly was expected to be in the local runtime store as the application was published using the following target manifest files:
    aspnetcore-store-2.0.5.xml

  在我安装服务器的SDK的时候选择的是2.1.3版本,而我的开发环境是2.1.4版本,结果就出错了,弄了一阵子没搞好这个原因,同样就是这个原因,使得我从Git上pull下来的项目,虽然发布成功了,但是部署的话是不能够正常访问的,同时通过dotnet /xxx/xxx/xx.dll进行测试会一直出现这个错误。最后通过干掉已有的版本,获得最新的版本,同样,我也在这里有个问题,貌似没得更新SDK版本的指令吧?我没有找到,抱歉,如有,请联系我,谢谢。

  通过命令干掉旧版的CLI,同时下载新版的SDK搞定,成功运行起来了。

rm -rf /usr/share/dotnet​ 删除旧版cli

 

  下面是我的安装.Net Core的指令

  1、配置dotnet产品Feed
sudo rpm --import https://packages.microsoft.com/keys/microsoft.asc
sudo sh -c 'echo -e "[packages-microsoft-com-prod]
name=packages-microsoft-com-prod 
baseurl= https://packages.microsoft.com/yumrepos/microsoft-rhel7.3-prod
enabled=1
gpgcheck=1
gpgkey=https://packages.microsoft.com/keys/microsoft.asc" > /etc/yum.repos.d/dotnetdev.repo'

  2、安装SDK,注意版本!!!

sudo yum update
sudo yum -y install libunwind libicu
sudo yum install dotnet-sdk-2.1.4

   至此环境便已经搭建好了。

 

三、部署过程

  通过Git将码云或是Github上的项目Pull下来,最好现在服务器上指定好Git路径,比如我的建立一个专门放置项目的文件夹,其中对每一个需要Clone到本地的项目建立一个文件夹,可以让我思路比较清晰。或许,你有更好的方式,也可以使用。

  

  通过建立完毕运行指令

git clone 你项目的SSH地址

  我们可以利用其他dotnet的指令进行一些操作了,具体需要什么指令可以通过dotnet --help进行获得

  查看下文件夹中的内容

  

  可以通过指令 dotnet run 将项目进行启动

  

  此处会发现,我们不能干什么事情了,只能按Ctrl + C让服务停下来,我们可以将当前这个程序作为后台程序运行,具体的操作就是Ctrl +Z将服务暂停,然后通过指令 bg 将其设为后台进程,如果想要进入已有的后台进程通过指令 fg

  如果我们是只在命令行里操作的话,又看不到页面,又不能通过外网访问,又想要确保网站是否真的运行成功了,我们可以通过指令来查看网站的首页信息,将返回网站的html信息。具体更多的linux下http指令请参照http://blog.csdn.net/wh211212/article/details/54285921

 curl localhost:65758

   我们可以发布了,通过指令 dotnet build将项目再次编译一下,然后通过 dotnet publish -o /xxxx/xxxx 将项目发布到指定文件夹

   接下来,可以开始配置jexus了.

/// 1、切换到Jexus配置文件目录
cd /usr/jexus/siteconf
/// 2、复制默认的配置文件为HDShop
cp default HDShop
vi HDShop

######################
# Web Site: HDShop
########################################
port=9527
root=/ /var/www/HDShop
hosts= *    #OR your.com,*.your.com

AppHost={CmdLine=dotnet /var/www/HDShop/HDShop.dll;AppRoot=/var/www/HDShop/;Port=0}

   至此,需要的所有准备工作已经做好,

  通过jexus的命令来启动服务,jexus的命令大全可以参照:http://blog.csdn.net/yang1982_0907/article/details/45155765

/// 如果已启动 Jexus:
sh /usr/jexus/jws restart

/// 如果未启动 Jexus:
sh /usr/jexus/jws start

   此时通过外网输入ip地址或域名(如果有的话)+端口(我写的不是默认80端口而是9527端口)

  网站正常启动,成功读到阿里云上那台数据库服务器的数据,同时也进行增删改成功了。

  至此,尝试结束,其中还有许多的其他部分没有说明进来,比如说Docker,我是使用了Docker的,但在写的部分中并没涉及Docker,因为我自己发现一些逻辑绕不过去,具体问题见下一章。还有也尝试了想要用图形界面操控Linux服务器并且远程操控,专门下了GNOME和TigerVNC,发现很卡,卡到心累,便不再使用,直接在命令行中进行所有工作。同时,对于Window下的项目怎么移动到Linux上,其实还有很多种方式,比如FTP等等,这个可以从度娘获知。我比较喜欢Git这种方式。

 

四、后续问题

  此次没有配合Docker容器一起使用,下一次将会带来Docker容器

  1、引入Docker容器,实现服务部署于容器中,通过外网访问可以访问到Docker容器中的网站。

  2、项目还没有加入Dockerfile文件,此次都是通过手工去部署的,下一次将使用Dockerfile进行服务部署。

  3、域名绑定还没有尝试。

  但是还有一些问题没有解决

  1、jexus配合Docker使用使用,但是遇到点问题还需解决。

  比如:目前来讲,我将网站直接发布好了,那么我就不需要指令 dotnet run 让其自运行自侦听了,那么全是依靠的jexus的代理。这么一来,Docker容器中运行服务那是什么意思呢?我暂时还不能理解。同时如果说Docker容器中运行网站,那么是由网站本身自侦听还是由容器中的jexus进行代理呢?

  2、端口映射问题,主机端口和Docker容器中端口映射问题。

  3、Docker容器间访问设置

 

2018-2-3,望技术有成后能回来看见自己的脚步

 

posted @ 2018-02-03 15:18  微笑刺客D  阅读(7266)  评论(18编辑  收藏  举报
返回顶部