zoukankan      html  css  js  c++  java
  • .Net Core in Docker极简入门(下篇)

    Tips:本篇已加入系列文章阅读目录,可点击查看更多相关文章。

    前言

    上一篇【.Net Core in Docker极简入门(上篇)】讲解了docker的一些基本命令和操作,并成功构建了自己的asp.net core web应用的镜像,启动容器。本篇继续。

    开始

    上一篇的项目例子非常简单,通常我们的实际项目要复杂的多。项目中会依赖各种组件服务,比如数据库,MQ,缓存等等。这就会涉及到多个容器,如果手动用docker命令去一个一个的启动就很麻烦了,那么这时候就可以使用Docker-Compose来完成多个容器的管理。

    Docker-Compose

    什么是Docker Compose?

    Compose 是用于定义和运行多容器 Docker 应用程序的工具。通过 Compose,您可以使用 YML 文件来配置应用程序需要的所有服务。然后,使用一个命令,就可以从 YML 文件配置中创建并启动所有服务。

    简单来理解,Compose类似一个批量工具,可以执行一组命令,支持批量构建镜像,批量启动容器,批量删除容器等等功能。

    Windows的Docker Desktop中已经包括了Compose,Linux下Compose则需要单独安装一下。

    下面在项目中添加一些数据库操作的相关代码便于测试,使用EF Core+SQL Server。

    代码修改

    安装EF Code相关的包:

    修改代码:

    public class WeatherForecast
    {
        [Key]
        public int Id { get; set; }
    
        public DateTime Date { get; set; }
    
        public int TemperatureC { get; set; }
    
        public int TemperatureF { get; set; }
    
        public string Summary { get; set; }
    }
    
    public class DemoContext : DbContext
    {
        public DemoContext(DbContextOptions<DemoContext> options)
            : base(options)
        {
    
        }
    
        public DbSet<WeatherForecast> WeatherForecasts { get; set; }
    
        protected override void OnModelCreating(ModelBuilder modelBuilder)
        {
            base.OnModelCreating(modelBuilder);
            //初始化种子数据
            modelBuilder.Entity<WeatherForecast>().HasData(new WeatherForecast
            {
                Id = 1,
                Date = DateTime.Now,
                Summary = "none",
                TemperatureC = 20,
                TemperatureF = 32 + (int)(20 / 0.5556)
            }, new WeatherForecast
            {
                Id = 2,
                Date = DateTime.Now.AddDays(1),
                Summary = "none",
                TemperatureC = 25,
                TemperatureF = 32 + (int)(25 / 0.5556)
            });
        }
    }
    
    public class Startup
    {
        ......
            
        public void ConfigureServices(IServiceCollection services)
        {
            services.AddControllers();
    
            services.AddDbContext<DemoContext>(opt => opt.UseSqlServer(Configuration.GetConnectionString("DemoContext")));
        }
        
        public void Configure(IApplicationBuilder app, IWebHostEnvironment env, DemoContext context)
        {
            //自动迁移
            context.Database.Migrate();
    
            ......
        }
    }
    
    public class WeatherForecastController : ControllerBase
    {
        private readonly ILogger<WeatherForecastController> _logger;
        private readonly DemoContext _context;
    
        public WeatherForecastController(ILogger<WeatherForecastController> logger, DemoContext context)
        {
            _logger = logger;
            _context = context;
        }
    
        [HttpGet]
        public IEnumerable<WeatherForecast> Get()
        {
            return _context.WeatherForecasts.ToArray();
        }
    }
    

    appsettings.json添加数据库连接字符串配置:

    {
      ......
      
      "ConnectionStrings": {
        "DemoContext": "Server=sql-server;Database=DemoDB;User Id=sa;Password=Password@2020;"
      }
    }
    

    注意:Server=sql-server,这个sql-server是需要在docker-compose.yml中定义的,下面再说。

    添加迁移:

    yml file

    右键项目-添加-容器业务流程协调程序支持

    添加后会生成docker-compose相关文件:

    其中的docker-compose.yml文件需要修改一下:

    version: '3.4'
    
    services:
      webapplication1:
        image: ${DOCKER_REGISTRY-}webapplication1
        build:
          context: .
          dockerfile: WebApplication1/Dockerfile
        ports: 
          - '5000:80'
        networks:
          - my-net
        depends_on:
          - sql-server
    
      sql-server:
        image: mcr.microsoft.com/mssql/server:2019-CU5-ubuntu-18.04
        ports: 
          - '1434:1433'
        environment: 
          ACCEPT_EULA: Y
          SA_PASSWORD: Password@2020
        networks: 
          - my-net
    
    networks: 
      my-net: 
        driver: bridge 
    

    services下定义了2个服务webapplication1、sql-server,相当于2个容器。webapplication1是基于WebApplication1/Dockerfile构建的镜像${DOCKER_REGISTRY-}webapplication1来启动,depends_on用于指定依赖的服务,这里的webapplication1服务依赖于sql-server服务。networks用于指定网络,因为docker中容器之间默认是无法直接通信的,这里创建了一个bridge模式的网络my-net,webapplication1和sql-server都在my-net网络中,那么他们之间就可以通过服务名来通信。所以在上面webapplication1的数据库连接字符串中就可以写:Server=sql-server。通常数据库的数据目录会挂载到主机上,防止容器发生意外导致数据丢失。

    上一篇有小伙伴问容器内能不能访问容器外的数据库,这个是可以访问的。访问宿主机的话直接用IP访问就可以,或者用host.docker.internal,这个host.docker.internal是docker安装时会写入到你的hosts文件里的一个主机名,实际还是指向你的主机IP。

    以上的yml内容还是比较简单,yml文件是使用Compose必不可少的,语法可以自行学习一下。掌握其语法关键字后,你就可以在docker-compose.yml文件中定义更复杂的环境。

    up & down

    来到项目根目录,启动PowerShell或cmd执行docker命令。

    执行docker-compose up,也可以加-d参数,让他在后台运行

    启动完成后,浏览器访问:http://localhost:5000/weatherforecast

    成功。这里省略了docker-compose build命令,你也可以在up前先执行build。

    docker-compose是不是很方便呢,即使你的系统环境部署再复杂,也只需要一个up指令。

    如果你想摧毁这个环境只需要执行docker-compose down即可

    同样的,以上操作也可以直接在vs2019中完成,无需手动执行指令,只需要将docker-compose项目设为启动项,然后直接运行即可,还支持代码调试哦。不过由于网络等问题,可能会遇到一些坑。。。

    镜像仓库

    我们也可以把自己的镜像推送到远程仓库,然后在其他机器上直接就能通过命令拉取了。国内阿里云之类的都有docker镜像仓库服务,也可以搭建私有仓库,本文就推送到docker的官方仓库docker hub。首先需要在docker官网https://www.docker.com/注册账号。

    重新构建镜像:docker build -t xhznl/webapp1 -f ./WebApplication1/Dockerfile .

    其中xhznl是我的docker用户名。

    登录docker: docker login,输入自己的用户名密码。

    登录成功后即可推送镜像,执行:docker push xhznl/webapp1

    推送成功,在docker官网可以查看镜像:

    这样在其他机器的docker中也可以通过docker pull xhznl/webapp1来拉取这个镜像。

    修改docker-compose.yml文件,将webapplication1服务的image改为xhznl/webapp1,然后把这个docker-compose.yml文件放到任何装有docker的机器上,只需执行docker-compose up,即可启动程序的所有环境,是不是很神奇。

    services:
      webapplication1:
        image: xhznl/webapp1
        ports: 
          - '5000:80'
        networks:
          - my-net
        depends_on:
          - sql-server
    

    最后推荐一波vs code,安装docker相关插件,无论是编写yml文件还是管理docker都很方便, 很多操作都不用手敲命令啦。。。

    最后

    Docker作为当今最流行的容器技术,是很多技术架构的基础。它有很多的优点,使用中也会面临各种问题,希望本篇入门文章能够帮助到一些初学的小伙伴。

  • 相关阅读:
    爱情五十三课,爱情银行
    [技术][JavaScript] <<JQuery 实战(Jquery in Action)>> Bear Bibeault & Yehuda Katz(美)
    [生活][健康] <<点食成金>> 范志红
    专一不是一辈子只喜欢一个人,是喜欢一个人的时候一心一意。
    【生活智慧】001.追求实在的东西
    【生活智慧】002.以上帝的"特选子民"自居
    【生活智慧】003.不能为了一顿鸡鸭鱼肉而让其他日子挨饿
    爱情五十四课,最需要的一刻
    爱情五十课,牵手的力量
    爱情五十五课,选择可以承担的
  • 原文地址:https://www.cnblogs.com/xhznl/p/13357781.html
Copyright © 2011-2022 走看看