本系列文章所要做出的演示架构基于 .NET Core Web Api、MSSQL、Skywalking 和 nginx ,这些都会通过docker-compose一键创建/启动容器,然后用 Azure DevOps 发布上线。

所以本系列文章重点并不是如何写好.NET Core,而是围绕着 .NET Core 的容器化架构加上一部分 DevOps 的实践。

系列大纲

本系列文章会分为四个部分,大家可以通过大纲大概了解一下我们会涉及到哪些内容,是不是你想了解想学习的东西。

  1. 用 docker-compose 启动WebApiSQL Server

  2. 在容器中集成SkywalkingAPM

  3. 通过nginx-proxy对 ESSkywalkingWebApi实现自动反向代理和HTTPS

  4. 通过Azure DevOps进行CI/CD和蓝绿发布

前提条件

本系列文章不会对.NET CoreDocker等做零基础讲解,如果遇到不会建项目,不懂某条命令一类的问题需要你多谷歌一下,遇到问题可以先看文章结尾的帮助信息,会写一些对排错有帮助的内容。

然后 Azure DevOps 部分会要求你有一个 Linux 服务器,没有的可以用信用卡去 Google Cloud Platform、Azure、AWS 等自己免费撸一个,我推荐 Google Cloud Platform。

环境条件

  • NET Core 2.2 SDK

  • Docker 最新版(目前是 18.09.2)

  • SQL Server

接下来我们开始系列第一篇。

创建 .NET Core WebApi 项目

首先我们创建一个.NET Core WebApi项目,将其命名为Core.API,然后为了演示方便,我们修改一下ValuesControllerGet方法。

[HttpGet("{id}")]public ActionResult<string> Get(int id){    return "您输入的是:" + id;}

然后修改一下launchSettings.json,将httpsUrl移除掉:

...        "Core.API": {            "commandName": "Project",            "launchBrowser": true,            "launchUrl": "api/values",            "environmentVariables": {                "ASPNETCORE_ENVIRONMENT": "Development"            },            //"applicationUrl": "https://localhost:5001;http://localhost:5000"            "applicationUrl": "http://localhost:5000"        }...

然后点击这里运行看一下效果:

接下来,为了让WebApi在容器中被顺利访问,我们需要让Kestrel监听外网流量,修改Program.csCreateWebHostBuilder方法:

public static IWebHostBuilder CreateWebHostBuilder(string[] args) =>            WebHost.CreateDefaultBuilder(args)                .UseStartup<Startup>()                .UseUrls("http://0.0.0.0:5000");

创建 Dockerfile

找到我们的解决方案文件夹,创建一个名为Dockerfile的文件。

然后将以下内容复制进去:

FROM mcr.microsoft.com/dotnet/core/sdk:2.2-stretch AS publishWORKDIR /srcCOPY . .RUN dotnet publish "/src/Core.API/Core.API.csproj" -c Release -o /appFROM mcr.microsoft.com/dotnet/core/aspnet:2.2-stretch-slimEXPOSE 5000WORKDIR /appCOPY --from=publish /app .ENTRYPOINT ["dotnet", "Core.API.dll"]

开启你的命令行工具,指向到 API 项目中,将下列命令中的[yourusername]替换为你的 Docker 用户名,当然如果你没有登录的话,你需要先执行docker login登录一下,然后依次执行下列命令:

docker build -t [yourusername]/coreapi .docker run -p 5000:5000 -it --rm --name coreapi [yourusername]/coreapi

不出意外等一段时间你应该会发现自己的 API 在容器里活泼地蹦达了起来,我们这次访问http://localhost:5000/api/values/5这个 Url,你应该能看到跟之前一样的结果。

好,我们按下Ctrl+C让它冷静下来,继续教程。

配置 Entityframework Core

一个标准的应用当然不能少了数据库,一个简明扼要的教程就需要EFCoreCode First

我们新建一个名为Core.Entity.NET Standard类库,打开你的程序包管理控制台,将默认项目指向Core.Entity,安装以下依赖:

Install-Package Microsoft.EntityFrameworkCore -Version 2.2.4Install-Package Microsoft.EntityFrameworkCore.SqlServer -Version 2.2.4Install-Package Microsoft.EntityFrameworkCore.Design -Version 2.2.4Install-Package Microsoft.Extensions.Configuration.Json -Version 2.2.0Install-Package Microsoft.Extensions.Configuration.FileExtensions -Version 2.2.0

新建两个类文件,一个叫CoreContext,作为我们的数据库上下文:

using Microsoft.EntityFrameworkCore;using Microsoft.Extensions.Configuration;using System;using System.IO;namespace Core.Entity{    public class CoreContext : DbContext    {        public CoreContext() { }        public CoreContext(DbContextOptions<CoreContext> options)            : base(options)        {        }        public virtual DbSet<Post> Post { get; set; }        protected override void OnConfiguring(DbContextOptionsBuilder optionsBuilder)        {            if (!optionsBuilder.IsConfigured)            {                var config = new ConfigurationBuilder()                    .SetBasePath(Path.Combine(Directory.GetCurrentDirectory()))                    .AddJsonFile("appsettings.Development.json", optional: false).Build();                optionsBuilder.UseSqlServer(config["ConnectionString"]);            }        }        protected override void OnModelCreating(ModelBuilder builder)        {            builder.HasAnnotation("ProductVersion", "2.2.0-rtm-35687");            #region Seeds            string[] titles = new string[] {                "本教程由Siegrain倾情奉献?️",                "感谢大家关注~",                "博客地址为 http://siegrain.wang",                "本教程Github地址为 https://github.com/Seanwong933/.NET-Core-with-Docker"            };            for (var i = 0; i < titles.Length; i++)            {                builder.Entity<Post>().HasData(new Post                {                    Id = i + 1,                    Title = titles[i],                    Content = Guid.NewGuid().ToString()                });            }            #endregion        }    }}

一个叫Post,作为我们的示例实体:

using System.ComponentModel.DataAnnotations;using System.ComponentModel.DataAnnotations.Schema;namespace Core.Entity{    public class Post    {        [Key]        [DatabaseGenerated(DatabaseGeneratedOption.Identity)]        public int Id { get; set; }        [Required]        public string Title { get; set; }        public string Content { get; set; }    }}接下来在`Core.API`中添加`Core.Entity`的项目依赖,然后在程序包控制台执行以下命令:add-migration initialupdate-database它会创建你的初始迁移文件,然后将其更新到数据库中。![](Untitled-c6fc13c0-281f-434a-a86b-9dcc4a2059cd.png)如果报错了,检查一下`appsettings.Development.json`中的链接字符串是否正确。接下来,我们需要在`Startup.cs`的`ConfigureServices`和`Configure`方法中进行一些修改,并设置`EFCore`在发现没有数据库或数据库过期时自动迁移。public void ConfigureServices(IServiceCollection services){    services.AddMvc().SetCompatibilityVersion(CompatibilityVersion.Version_2_2);        services.AddScoped<CoreContext, CoreContext>();        services.AddDbContext<CoreContext>(options =>    {        options.UseSqlServer(Configuration["ConnectionString"]);    });}public void Configure(IApplicationBuilder app, IHostingEnvironment env){    if (env.IsDevelopment())    {        app.UseDeveloperExceptionPage();    }    else    {                app.UseHsts();    }        using (var serviceScope = app.ApplicationServices.GetService<IServiceScopeFactory>().CreateScope())    {        var context = serviceScope.ServiceProvider.GetRequiredService<CoreContext>();        context.Database.Migrate();    }    app.UseHttpsRedirection();    app.UseMvc();}

然后修改一下ValuesController,好让其获取我们想要的数据:

[Route("api/[controller]")][ApiController]public class ValuesController : ControllerBase{    private readonly CoreContext _context;    public ValuesController(CoreContext context)    {        _context = context;    }        [HttpGet]    public IActionResult Get()    {        return Ok(_context.Post.ToList());    }        [HttpGet("{id}")]    public IActionResult Get(int id)    {        var entity = _context.Post.Find(id);        if (entity == null) return NotFound();        return Ok(entity);    }}

我们再次运行看下是否能够正确获取了。

创建 docker-compose 文件

接下来,我们要用docker-compose在容其中将webapiSQL Server一并运行起来。

在解决方案文件夹下创建 docker-compose.yml 文件:

粘贴以下内容:

version: '3.3'services:  coreapi:    container_name: coreapi    image: siegrainwong/coreapi:latest    ports:      - 5000:5000    depends_on:      - sqlserver    links:      - sqlserver    volumes:      - ./Core.API/appsettings.docker.json:/app/appsettings.json:ro    restart: always  sqlserver:    image: mcr.microsoft.com/mssql/server:2017-latest    container_name: sqlserver    restart: always    environment:      ACCEPT_EULA: Y      MSSQL_PID: Developer      SA_PASSWORD: 'NetCore123!@#'    ports:      - 1433

然后在当前目录执行docker-compose up -d

这时候再看下是不是正常运行了。

但此时SQL Server的数据也是只在容器中的,意味着容器被移除后数据就会丢失,所以我们要通过挂载volume的方式持久化数据。

docker-compose文件中添加箭头处的代码:

version: '3.3'services:  coreapi:    container_name: coreapi    image: siegrainwong/coreapi:latest    ports:      - 5000:5000    depends_on:      - sqlserver    links:      - sqlserver    volumes:      - ./Core.API/appsettings.docker.json:/app/appsettings.json:ro    restart: always  sqlserver:    image: mcr.microsoft.com/mssql/server:2017-latest    container_name: sqlserver    restart: always    environment:      ACCEPT_EULA: Y      MSSQL_PID: Developer      SA_PASSWORD: 'NetCore123!@#'    volumes:      - coredata:/var/opt/mssql # <--    ports:      - 1433volumes:  coredata: # <--

此时我们可以先将容器用docker rm -f coreapi移除,再跑起来后用docker logs coreapi命令看看有没有EFCore的迁移日志就知道数据有没有被持久化了。

帮助信息

实用的 docker 命令

docker psdocker imagesdocker rm -f [container_name]docker exec [container_name] [commands]docker exec -it [container_name] bashdocker logs [container_name]

带注释的docker-compose.yml文件

因为编码问题带中文注释的不太容易被识别,所以没有放进源码中

案例参考

这是我正在开发的一个开源博客系统,该系列文章的这套架构就出自这个项目,觉得不错的话希望可以帮我点颗星鼓励一下;如果你是从 https://siegrain.wang 看见这篇文章的,那么你现在所看见的就是这个项目: )

https://github.com/siegrainwong/ancorazor

项目源代码

https://github.com/Seanwong933/.NET-Core-with-Docker/tree/master/Part1

本篇到此为止,下一篇文章将带领大家在容器中集成skywalking监控webapi,不了解的同学可以先去了解一下skywalking是什么,能做什么。

原文地址:https://siegrain.wang/article/2019/06/24/launch-netcore-webapi-and-sqlserver-by-docker-compose

用 docker-compose 启动 WebApi 和 SQL Server相关推荐

  1. 怎样在dos窗口中启动mysql服务器_如何在dos命令中启动mysql或sql server 服务器的一些操作...

    ========================dos命令启动mysql或者sql srever 的步骤================= 一.dos命令启动mysql 1.进入dos命令窗口 2.启 ...

  2. Docker 容器部署 SQL Server AlwaysOn AG

    SQL Server 2016 开始支持 Linux.随着2017 和2019 版本的推出,它开始支持Linux和Container平台上的HA/DR.Kubernetes和大数据集群解决方案. 今天 ...

  3. 基于 Docker Compose 实践 .NET Core 的现代化架构 2:在容器中集成 Skywalking APM

    本章节代码已经上传至 https://github.com/siegrainwong/.NET-Core-with-Docker/tree/master/Part2 系列大纲 还是先介绍一下目录,这次 ...

  4. Docker部署SQL Server 2019 Always On集群

    Docker部署Always on集群 SQL Server在2016年开始支持Linux.随着2017和2019版本的发布,它开始支持Linux和容器平台上的HA/DR.Kubernetes和大数据 ...

  5. 使用SQL Server 2017 Docker容器在.NET Core中进行本地Web API开发

    目录 介绍 先决条件 最好事先知道 假设 动机 跨平台 快速安装 经济有效 不同版本/多个实例 速度 持久性 找到SQL Server 2017镜像并在本地下载它 在没有卷挂载的情况下在本地执行SQ​ ...

  6. 创建自己SQL Server Docker映像

    In this article, we will review how to create custom SQL Server docker images and run the containers ...

  7. 在没有Docker容器的Ubuntu上安装SQL Server 2019

    Until now, we learned to install and configure SQL Server 2019 using the Docker container. In this a ...

  8. 开箱即用的 SQL Server Docker

    SQL Server 真是越来越有看头.当我们还在为 Linux 上运行 SQL Server 而兴奋的时候,SQL Server 已经开启了 容器化之路,至此才能看清微软的胸怀,开始拥抱更大的世界. ...

  9. 使用 Docker 运行 SQL Server 容器映像 在Windows操作系统上,重设置密码和操作数库

    快速入门:使用 Docker 运行 SQL Server 容器映像 2020/09/07 V O G M Choose your command shell 适用于: 是SQL Server(所有支持 ...

最新文章

  1. java 判断是否是日期_java判断是否为日期的方法(附代码)
  2. html5 loader,7种基于GSAP的SVG Loader加载动画特效
  3. linux系统自签发免费ssl证书,为nginx生成自签名ssl证书
  4. ddr传输 pl ps_Vitis ZYNQ开发秘籍 PS 端任意控制 VGA 显示画面最终实现
  5. ajax传递json对象 php,ajax 和 php 相互传递 JSON对象(转载)
  6. jQuery——入门(四)JQuery 事件
  7. 【云速建站】后台配置邮费
  8. java aciss_C语言ACISS表.doc
  9. 社群经济:如何利用社群做营销?
  10. CImage 获取图片RGB 、图片高和宽;
  11. Android关于Paint你所知道的和不知道的一切
  12. 3-产品经理学习笔记之产品经理的工作职责和能力模型
  13. Mockplus原型设计工具介绍
  14. coreldraw橙子怎么画_CDR绘制橙子和冰块教程
  15. html中<img src=““ alt=““>标签里面alt的作用
  16. 由于找不到iutils.dll无法继续执行代码?
  17. 简单三步下载网页微博中的视频
  18. 【MineCraft】-- 如何开设我的世界服务器
  19. 学习了罗昭锋的文献管理与信息分析的感受
  20. 联想笔记本ideapad 320C 15IKB笔记本电脑改装总结

热门文章

  1. 设置单元格填充方式_单元格的选择及设置单元格格式
  2. 程序员笔记(知识)管理的一点经验
  3. Spring Boot 入门小目标 3 --- 先来试着热部署
  4. mysql出现连接错误不识别 utf8mb4
  5. Winform VS2015打包
  6. 2013-10-10
  7. XP下Virtualbox虚拟Ubuntu共享文件夹
  8. C# 扩展集合ObservableCollection使集合在添加、删除、值变更后触发事件
  9. 如何实现 asp.net core 安全优雅退出 ?
  10. 十个现象,识别程序员的“水份”