• 通过 Docker Compose 组合 ASP NET Core 和 SQL Server


    本文模拟一个比较完整的项目,包括前端(MVC), 后端(WebApi)和数据库(mssql-server-linux)。通过Docker Compose 定义,组合并执行它们。涉及到 Docker Compose 安装,命令,docker-compose.yml文件编写,WebApi 和 MVC 项目编写,Dockfile编写等

    Docker Compose

    简介

    Docker Compose是Docker三剑客之一,用于定义和运行多个Docker容器应用,负责实现对 Docker 容器集群的快速编排。

    我们可以通过Dockerfile定义一个单独的应用容器。然而在日常工作中,经常会碰到需要多个容器相互配合来完成某项任务的情况。例如要实现一个 Web 项目,除了 Web 服务容器本身,往往还需要再加上后端的数据库服务容器等。

    Compose 恰好满足了这样的需求。它允许用户通过一个单独的 docker-compose.yml 配置板文件(YAML 格式)来定义一组相关联的应用容器。然后使用使用单个命令,就可以根据配置中创建并启动所有服务。

    安装

    1. curl 下载 Docker Compose
    sudo curl -L https://github.com/docker/compose/releases/download/{{site.compose_version}}/docker-compose-$(uname -s)-$(uname -m) -o /usr/local/bin/docker-compose
    

    替换{{site.compose_version}}为最新的版本号

    1. 赋执行权限
    sudo chmod +x /usr/local/bin/docker-compose
    
    1. 测试是否安装成功
    docker-compose --version
    

    WebApi 项目

    创建项目

    1. 参考微软示例Create a Web API 创建一个基于 net core 2.1的WebApi项目,命名为Todo.Api. 参照示例添加 model 和 database context。

    2. 在 ConfigureServices 里注册 database context.

    services.AddDbContext<TodoContext>(options =>
        options.UseSqlServer(Configuration["ConnectionString"]));
    
    1. 参考微软示例Work with SQL Server LocalDB 添加 Seed 类并在Program.cs里面添加 seed initializer等。
    public static void Main(string[] args)
        {
            var host = CreateWebHostBuilder(args).Build();
    
            using (var scope = host.Services.CreateScope())
            {
                var services = scope.ServiceProvider;
    
                try
                {
                    var context = services.GetRequiredService<TodoContext>();
                    if (context.Database.GetPendingMigrations().Any())
                    {
                        context.Database.Migrate();
                        SeedData.Initialize(services);
                    }
                }
                catch (Exception ex)
                {
                    var logger = services.GetRequiredService<ILogger<Program>>();
                    logger.LogError(ex, "An error occurred seeding the DB.");
                }
            }
    
            host.Run();
        }
    

    只需要运行Add-Migration命令生成迁移。无需执行Update-Database命令,因为程序运行起来时候会通过context.Database.Migrate()来执行迁移。

    编写Dockfile

    FROM microsoft/dotnet:2.1-aspnetcore-runtime
    
    WORKDIR /app
    
    EXPOSE 80/tcp
    
    ENTRYPOINT ["dotnet", "Todo.Api.dll"]
    

    Web MVC 项目

    创建项目

    1. 创建一个基于 net core 2.1的Web MVC项目,命名为webMVC.

    2. 添加 Service 去调用 WebApi 开放的接口。

    public class TodoService : ITodoService
        {
            private readonly HttpClient _apiClient;
            private readonly IOptions<ApiConfig> _setting;
    
            public TodoService(HttpClient httpClient, IOptions<ApiConfig> settings)
            {
                _apiClient = httpClient;
                _setting = settings;
            }
    
            public async Task<IEnumerable<TodoViewModel>> GetTodos()
            {
                var url = $"{_setting.Value.TodoApiUrl}/api/todo";
                var dataString = await _apiClient.GetStringAsync(url);
                return JsonConvert.DeserializeObject<IEnumerable<TodoViewModel>>(dataString);
            }
    
            public async Task<IEnumerable<string>> GetMachineNames()
            {
                var url = $"{_setting.Value.TodoApiUrl}/api/machine";
                var dataString = await _apiClient.GetStringAsync(url);
                return JsonConvert.DeserializeObject<IEnumerable<string>>(dataString);
            }
        }
    

    编写Dockfile

    FROM microsoft/dotnet:2.1-aspnetcore-runtime
    
    WORKDIR /app
    
    EXPOSE 80/tcp
    
    ENTRYPOINT ["dotnet", "WebMVC.dll"]
    

    编写 docker-compose.yml文件

    version: "3"
    
    services:
      webmvc:
        image: webmvc
        environment:
          - ASPNETCORE_URLS=http://0.0.0.0:80
        build:
          context: ./WebMVC
          dockerfile: Dockerfile
        ports: 
        - "8080:80"
        volumes: 
          - ./WebMVC/bin/pub/:/app
        container_name: webmvc
        depends_on:
          - todo.api
    
      todo.api:
        image: todo.api
        environment:
          - ASPNETCORE_URLS=http://0.0.0.0:80
          - ConnectionString=Server=sql.data;User=sa;Password=Pass@word;Database=WebAPI_SQL_Docker_Demo;    
        build:
          context: ./Todo.Api
          dockerfile: Dockerfile
        ports: 
          - "8081:80"
        volumes: 
          - ./Todo.Api/bin/pub/:/app
        container_name: todo.api
        depends_on:
          - sql.data
    
      sql.data:
        image: microsoft/mssql-server-linux:2017-latest
        environment:
          - SA_PASSWORD=Pass@word
          - ACCEPT_EULA=Y
        ports:
          - "1433:1433"
    

    image: 指定镜像或构建生成镜像的名字
    build:构建生成镜像。context 指令指定 Dockerfile 所在文件夹的路径,dockerfile 指令指定 Dockerfile 文件名
    environment:设置环境变量
    ports:暴露端口信息。使用宿主端口:容器端口 (HOST:CONTAINER) 格式
    volumes:数据卷所挂载路径设置。可以设置宿主机路径 (HOST:CONTAINER)
    container_name:指定容器名称。默认将会使用 项目名称_服务名称_序号 这样的格式
    depends_on:解决容器的依赖、启动先后的问题

    详细请参考 Compose file version 3 reference

    运行项目

    1. 在docker-compose.yml文件通目录下执行docker-compose build构建项目中的服务容器.
    docker-compose build
    
    1. 通过 docker-compose up 创建,关联并启动服务.
    docker-compose up
    

    -d 在后台运行服务容器。
    --scale SERVICE=NUM 创建服务的N个实例。

    详细请参考 Compose (docker-compose) CLI reference

    源代码

    参考

  • 相关阅读:
    解析大型.NET ERP系统 20条数据库设计规范
    vi显示行号
    shell awk
    Linux使用Shell脚本实现ftp的自动上传下载
    MySQL Replication的Reset slave重置命令
    怎么样调整FreeBSD时区问题
    Basic Memory Structures
    States of Integrity Constraints
    Merging into a Table: Example
    oracle 单独开始一个事物的写法 。
  • 原文地址:https://www.cnblogs.com/royzshare/p/9359343.html
Copyright © 2020-2023  润新知