1. 程式人生 > >通過 Docker Compose 組合 ASP NET Core 和 SQL Server

通過 Docker Compose 組合 ASP NET Core 和 SQL Server

dock syn point mode 只需要 acc uil test usr

目錄

  • Docker Compose
    • 簡介
    • 安裝
  • WebApi 項目
    • 創建項目
    • 編寫Dockfile
  • Web MVC 項目
    • 創建項目
    • 編寫Dockfile
  • 編寫 docker-compose.yml文件
  • 運行項目
  • 源代碼
  • 參考

本文模擬一個比較完整的項目,包括前端(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

源代碼

  • github

參考

  • compose gitHub
  • Quickstart: Compose and ASP.NET Core with SQL Server
  • Get Started Building Microservices with ASP.NET Core and Docker in Visual Studio Code
  • Docker Compose 項目

通過 Docker Compose 組合 ASP NET Core 和 SQL Server