经过 Docker Compose 组合 ASP NET Core 和 SQL Server

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

Docker Compose

简介

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

咱们能够经过Dockerfile定义一个单独的应用容器。然而在平常工做中,常常会碰到须要多个容器相互配合来完成某项任务的状况。例如要实现一个 Web 项目,除了 Web 服务容器自己,每每还须要再加上后端的数据库服务容器等。github

Compose 刚好知足了这样的需求。它容许用户经过一个单独的 docker-compose.yml 配置板文件(YAML 格式)来定义一组相关联的应用容器。而后使用使用单个命令,就能够根据配置中建立并启动全部服务。web

安装

  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}}为最新的版本号sql

  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。docker

  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()来执行迁移。visual-studio-code

编写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

源代码

参考

相关文章
相关标签/搜索