共用方式為


從 Docker Compose 移轉至 Aspire

本指南可協助您瞭解如何將應用程式從 Docker Compose 遷移至 Aspire,並醒目提示重要的概念差異,並提供常見移轉案例的實用範例。

了解差異

雖然 Docker Compose 和 Aspire 在一眼看起來可能很類似,但它們有不同的用途,並在不同的抽象層級運作。

Docker 組合 vs Aspire

Docker 組成 Aspire
主要用途 容器編排 開發時間協調流程和應用程序組合。
範圍 容器焦點 多資源(容器、 .NET 專案、雲端資源)。
配置 基於 YAML 以 C# 為基礎的強型別。
目標環境 任何 Docker 運行時間 開發和雲端部署。
服務探索 DNS 型容器探索 內建服務探索與環境變數。
開發體驗 手動容器管理 整合式工具、儀錶板和遙測。

如需詳細資訊,請參閱 Docker Compose to Aspire AppHost API 文件

主要概念性轉變

從 Docker Compose 移轉至 Aspire時,請考慮下列概念性差異:

  • 從 YAML 到 C#:組態會從宣告式 YAML 移至命令式強型別 C# 程式代碼。
  • 從容器到資源: Aspire 不僅會管理容器,而且 .NET 管理專案、可執行文件、參數,全部做為資源。
  • 從手動聯網到服務發現: Aspire 自動配置服務發現和連接字串。
  • 從開發差距到整合體驗: Aspire 提供儀表板、遙測和偵錯整合。

如需撰寫 YAML 語法與 C# API 呼叫的完整參考對應Docker,請參閱Aspire。Docker

相關連結:

常見的移轉模式

本節示範從 Docker Compose 移至 Aspire時可能會遇到的實際移轉案例。 每個模式都會顯示完整的 Docker Compose 範例及其 Aspire 等價範例,並突出顯示遷移的主要差異和優點。

涵蓋的模式包括:

  • 具有前端、API 和資料庫元件的多服務 Web 應用程式
  • 使用現有映像的容器型服務
  • 環境變數和組態 管理策略。
  • 用於數據持續性和服務隔離的自定義網路和磁碟區。

這些範例代表最常見的使用案例,但 Aspire的彈性允許許多其他案例。 如果此處未涵蓋您的特定使用案例,您可以結合這些模式,或參考上述的完整 API 參考。

多服務 Web 應用程式

Docker 撰寫範例:

version: '3.8'
services:
  frontend:
    build: ./frontend
    ports:
      - "3000:3000"
    depends_on:
      - api
    environment:
      - API_URL=http://api:5000

  api:
    build: ./api
    ports:
      - "5000:5000"
    depends_on:
      - database
    environment:
      - ConnectionStrings__DefaultConnection=Host=database;Database=myapp;Username=postgres;Password=secret

  database:
    image: postgres:15
    environment:
      - POSTGRES_DB=myapp
      - POSTGRES_USER=postgres
      - POSTGRES_PASSWORD=secret
    volumes:
      - postgres_data:/var/lib/postgresql/data

volumes:
  postgres_data:

Aspire 等效:

var builder = DistributedApplication.CreateBuilder(args);

// Add the database
var database = builder.AddPostgres("postgres")
    .WithEnvironment("POSTGRES_DB", "myapp")
    .AddDatabase("myapp");

// Add the API project
var api = builder.AddProject<Projects.MyApp_Api>("api")
    .WithReference(database);

// Add the frontend project  
var frontend = builder.AddProject<Projects.MyApp_Frontend>("frontend")
    .WithReference(api);

builder.Build().Run();

主要差異:

  • 服務相依性depends_on 更改為 WithReference(),並且也會設定服務發現。
  • 環境變數:會自動產生並插入連接字串。
  • 建置內容:建置內容能夠使用 Dockerfiles、 .NET 專案、 Node.js 應用程式等等,而不只是 Dockerfile 組建。
  • 資料持續性:磁碟區由 Aspire自動管理。

容器式服務

Docker 撰寫範例:

version: '3.8'
services:
  web:
    build: .
    ports:
      - "8080:8080"
    depends_on:
      - redis
      - postgres

  redis:
    image: redis:7
    ports:
      - "6379:6379"

  postgres:
    image: postgres:15
    environment:
      POSTGRES_PASSWORD: secret
    volumes:
      - postgres_data:/var/lib/postgresql/data

volumes:
  postgres_data:

Aspire 等效:

var builder = DistributedApplication.CreateBuilder(args);

// Add backing services
var cache = builder.AddRedis("redis");
var database = builder.AddPostgres("postgres", password: "secret")
    .AddDatabase("main");

// Add the containerized web application
var web = builder.AddContainer("web", "myapp:latest")
    .WithHttpEndpoint(port: 8080, targetPort: 8080)
    .WithReference(cache)
    .WithReference(database);

builder.Build().Run();

環境變數和組態

Docker 撰寫方法:

services:
  app:
    image: myapp:latest
    environment:
      - DATABASE_URL=postgresql://user:pass@db:5432/myapp
      - REDIS_URL=redis://cache:6379
      - API_KEY=${API_KEY}
      - LOG_LEVEL=info

Aspire 方法:

var builder = DistributedApplication.CreateBuilder(args);

// Add external parameter
var apiKey = builder.AddParameter("apiKey", secret: true);

var database = builder.AddPostgres("db")
    .AddDatabase("myapp");
    
var cache = builder.AddRedis("cache");

var app = builder.AddContainer("app", "myapp:latest")
    .WithReference(database)      // Automatically sets DATABASE_URL
    .WithReference(cache)         // Automatically sets REDIS_URL  
    .WithEnvironment("API_KEY", apiKey)
    .WithEnvironment("LOG_LEVEL", "info");

builder.Build().Run();

主要差異:

  • 自動連接字串:系統會自動產生資料庫和快取 URL。
  • 具類型的參數:外部組態會使用強型別參數,而不是環境變數替代。
  • 服務探索:參考會自動設定正確的服務端點。

自定義網路和磁碟區

Docker 撰寫範例:

version: '3.8'
services:
  app:
    image: myapp:latest
    volumes:
      - app_data:/data
      - ./config:/app/config:ro
    networks:
      - backend

  worker:
    image: myworker:latest
    volumes:
      - app_data:/shared
    networks:
      - backend

networks:
  backend:

volumes:
  app_data:

Aspire 等效:

var builder = DistributedApplication.CreateBuilder(args);

// Create a named volume
var appData = builder.AddVolume("app-data");

var app = builder.AddContainer("app", "myapp:latest")
    .WithVolume(appData, "/data")
    .WithBindMount("./config", "/app/config", isReadOnly: true);

var worker = builder.AddContainer("worker", "myworker:latest")
    .WithVolume(appData, "/shared");

builder.Build().Run();

主要差異:

  • 簡化網路:Aspire自動處理容器網路。
  • 磁碟區管理:具名磁碟區是透過資源模型建立和管理。
  • 綁定掛載:可以使用WithBindMount()來掛載主機目錄。

相關連結:

移轉策略

成功從 Docker Compose 遷移至 Aspire 需要系統的方法。 下列步驟提供經過證實的方法,可讓您移動應用程式,同時將中斷降至最低,並確保所有元件在新環境中都能正常運作。

1.評估您目前的設定

在移轉之前,清查您的 Docker Compose 設定:

  • 服務:識別所有服務,包括資料庫、快取、API 和 Web 應用程式。
  • 相依性:繪製從 depends_on 的宣告中對應的服務相依性。
  • 數據持續性:編錄所有用於數據儲存的磁碟區和綁定掛載。
  • 環境變數:列出所有組態變數和秘密。
  • 自定義網路:識別任何自定義網路需求和組態。

2. 創建 Aspire AppHost

首先建立新 Aspire 專案:

dotnet new aspire-apphost -o MyApp.AppHost

3.以累加方式移轉服務

一個接一個地移轉服務,從備份服務(資料庫、快取)和應用程式開始:

  1. 新增支援服務,例如PostgreSQL、Redis以及其他基礎結構元件。
  2. 將應用程式轉換成.NET項目參考,以取得更好的整合。
  3. 針對現有的映像,使用 AddContainer()Docker容器。
  4. 配置相依性WithReference()來建立服務關係。
  5. 組態管理設定環境變數和參數。

4.處理數據遷移

針對永續性數據:

  • 使用 WithVolume() 用於需要持久化數據的具名磁碟區。
  • 當您需要直接存取主機檔案時,請使用 WithBindMount() 主機目錄掛接。
  • 考慮使用 WithDataVolume() 配合自動磁碟區管理來實現資料庫持久性。

5.測試及驗證

  • 啟動 Aspire AppHost 並驗證所有服務是否正確啟動。
  • 檢查儀錶板以確認服務健康情況和聯機狀態。
  • 驗證服務間通訊是否如預期般運作。
  • 使用現有的用戶端應用程式進行測試,以確保相容性。

相關連結:

移轉疑難解答

從 Docker Compose 移轉至 Aspire時,您可能會遇到一些常見的挑戰。 本節提供常見問題的解決方案,以及如何針對移轉程式期間發生的問題進行疑難解答的指引。

常見問題和解決方案

服務探索無法運作

  • 請確定您使用 WithReference() 來建立服務之間的相依性。
  • 檢查服務是否使用正確的環境變數名稱進行連線。
  • 檢閱儀錶板以確認已正確插入環境變數。

資料庫連線失敗

  • 在相依服務嘗試連線之前,請先確認資料庫已完全啟動。

  • 使用 WaitFor() 以確保適當的啟動順序:

    var api = builder.AddProject<Projects.Api>("api")
        .WithReference(database)
        .WaitFor(database);
    

磁碟區掛載問題

  • 使用絕對路徑來進行綁定掛載,以避免路徑解析問題。
  • 請確定主機目錄存在,並在掛接之前具有適當的許可權。
  • 請考慮在可能的情況下使用具名磁碟區,而非綁定掛載,以提升可移植性。

埠衝突

  • Aspire 自動分配端口以避免服務之間的衝突。
  • 使用 WithHttpEndpoint() 來指定外部存取所需的自定義埠。
  • 在開發期間檢查儀錶板中是否有實際指派的埠。

相關連結:

後續步驟

遷移到 Aspire後:

另請參閱