使用 LocalStack 和 Docker 開發及測試 AWS 雲端應用程式

在現代應用程式開發中,在部署到正式環境前先在本地測試雲端應用程式,有助於以更快的速度和更高的信心交付產品。這種方法涉及在本地模擬服務、儘早識別並修復問題,以及在無需支付費用或面對完整雲端環境複雜性的情況下快速迭代。像 LocalStack 這樣的工具在此過程中變得極具價值,使您能夠模擬 AWS 服務並將應用程式容器化,以實現一致、隔離的測試環境。

在本指南中,您將學習如何:

  • 使用 Docker 啟動一個 LocalStack 容器
  • 從非容器化應用程式連接至 LocalStack
  • 從容器化應用程式連接至 LocalStack

什麼是 LocalStack?

LocalStack 是一個雲端服務模擬器,可在您筆記型電腦上的單個容器中執行。它為在本地測試和開發基於 AWS 的應用程式提供了一種功能強大、靈活且具成本效益的方式。

為什麼要使用 LocalStack?

在本地模擬 AWS 服務可讓您測試應用程式如何與 S3、Lambda 和 DynamoDB 等服務互動,而無需連接到真實的 AWS 雲端。您可以快速迭代開發,避免此階段部署到雲端的成本和複雜性。

透過在本地模仿這些服務的行為,LocalStack 實現了更快的反饋循環。您的應用程式可以與外部 API 互動,但所有內容都在本地執行,無需處理雲端配置或網路延遲。

這使得驗證整合和測試雲端場景變得更加容易,而無需在正式環境中配置 IAM 角色或原則。您可以在本地模擬複雜的雲端架構,並僅在準備就緒時才將更改推送到 AWS。

在 Docker 中使用 LocalStack

LocalStack 的官方 Docker 映像提供了一種在開發機器上執行 LocalStack 的便捷方式。它免費使用,且執行時不需要任何 API 金鑰。您甚至可以使用 LocalStack Docker 擴充功能,透過圖形使用者介面使用 LocalStack。

先決條件

若要跟隨本操作指南,需要具備以下先決條件:

啟動 LocalStack

透過以下步驟啟動 LocalStack 的快速演示

  1. 首先複製一個範例應用程式。開啟終端機並執行以下指令

    $ git clone https://github.com/dockersamples/todo-list-localstack-docker
    $ cd todo-list-localstack-docker
    
  2. 啟動 LocalStack

    執行以下指令來啟動 LocalStack。

    $ docker compose -f compose-native.yml up -d
    

    此 Compose 檔案也包含了所需 Mongo 資料庫的規格。您可以透過造訪 Docker Desktop 儀表板來驗證服務是否已啟動並執行。

    Diagram showing the LocalStack and Mongo container up and running on Docker Desktop
  3. 選取容器並檢查日誌,以驗證 LocalStack 是否已啟動並執行。

    Diagram showing the logs of LocalStack container
  4. 建立一個本地 Amazon S3 儲存貯體 (Bucket)

    當您使用 LocalStack 建立本地 S3 儲存貯體時,您基本上是在模擬 AWS 上 S3 儲存貯體的建立過程。這讓您無需實際的 AWS 帳號,即可測試和開發與 S3 互動的應用程式。

    若要建立本地 Amazon S3 儲存貯體,您需要在系統上安裝 awscli-local 套件。此套件提供了 awslocal 指令,它是 AWS 命令列介面的輕量級封裝,專為 LocalStack 設計。它讓您能夠在本地機器上的模擬環境中進行測試與開發,而無需存取真實的 AWS 服務。您可以點擊此處進一步了解此工具。

    $ pip install awscli-local
    

    使用以下指令在 LocalStack 環境中建立一個新的 S3 儲存貯體

    $ awslocal s3 mb s3://mysamplebucket
    

    指令 s3 mb s3://mysamplebucket 告訴 AWS CLI 建立一個名為 mysamplebucket 的新 S3 儲存貯體(mb 代表 make bucket)。

    您可以透過在 Docker Desktop 儀表板上選取 LocalStack 容器並檢視日誌,來驗證 S3 儲存貯體是否已建立。日誌會顯示您的 LocalStack 環境已正確設定,現在您可以將 mysamplebucket 用於儲存和擷取物件。

    Diagram showing the logs of LocalStack that highlights the S3 bucket being created successfully

在開發中使用 LocalStack

既然您已經熟悉了 LocalStack,現在是時候看看它的實際應用了。在此演示中,您將使用一個包含 React 前端和 Node.js 後端的範例應用程式。此應用程式堆疊使用了以下組件

  • React:用於存取待辦事項清單應用程式的使用者友善前端
  • Node:負責處理 HTTP 請求的後端。
  • MongoDB:用於儲存所有待辦事項資料的資料庫
  • LocalStack:模擬 Amazon S3 服務,用於儲存和擷取圖片。
Diagram showing the tech stack of the sample todo-list application that includes LocalStack, frontend and backend services

從非容器化應用程式連接至 LocalStack

現在是時候將您的應用程式連接到 LocalStack 了。位於 backend/ 目錄下的 index.js 檔案是後端應用程式的主要入口點。

該程式碼會與 LocalStack 的 S3 服務互動,此服務透過 S3_ENDPOINT_URL 環境變數定義的端點存取,該變數在本機開發中通常設定為 https://:4556

來自 AWS SDK 的 S3Client 被設定為使用此 LocalStack 端點,以及同樣來自環境變數的測試憑證(AWS_ACCESS_KEY_IDAWS_SECRET_ACCESS_KEY)。此設定讓應用程式能夠在本地模擬的 S3 服務上執行操作,就如同與真實的 AWS S3 互動一般,使程式碼能靈活適應不同環境。

該程式碼使用 multermulter-s3 來處理檔案上傳。當使用者透過 /upload 路由上傳圖片時,檔案會直接儲存在 LocalStack 模擬的 S3 儲存貯體中。儲存貯體名稱從環境變數 S3_BUCKET_NAME 中取得。每個上傳的檔案會透過在原始檔名後附加當前時間戳來命名,以確保唯一性。該路由隨後會傳回本地 S3 服務中上傳檔案的 URL,使其存取方式與託管在真實 AWS S3 儲存貯體中時相同。

讓我們實際操作一下。首先啟動 Node.js 後端服務。

  1. 切換至 backend/ 目錄

    $ cd backend/
    
  2. 安裝所需的相依套件

    $ npm install
    
  3. 設定 AWS 環境變數

    位於 backend/ 目錄下的 .env 檔案已經包含了 LocalStack 用來模擬 AWS 服務的預留憑證和配置值。AWS_ACCESS_KEY_IDAWS_SECRET_ACCESS_KEY 是預留憑證,而 S3_BUCKET_NAMES3_ENDPOINT_URL 則是配置設定。無需進行任何變更,因為這些值已經針對 LocalStack 正確設定。

    提示

    鑑於您是在 Docker 容器中執行 Mongo,且後端 Node 應用程式是在您的主機上原生執行,請確保您的 .env 檔案中已設定 MONGODB_URI=mongodb://:27017/todos

    MONGODB_URI=mongodb://:27017/todos
    AWS_ACCESS_KEY_ID=test
    AWS_SECRET_ACCESS_KEY=test
    S3_BUCKET_NAME=mysamplebucket
    S3_ENDPOINT_URL=https://:4566
    AWS_REGION=us-east-1

    雖然 AWS SDK 通常可能會使用以 AWS_ 開頭的環境變數,但此特定應用程式在 index.js 檔案(位於 backend/ 目錄下)中直接參照了以下 S3_* 變數來配置 S3Client

    const s3 = new S3Client({
      endpoint: process.env.S3_ENDPOINT_URL, // Use the provided endpoint or fallback to defaults
      credentials: {
        accessKeyId: process.env.AWS_ACCESS_KEY_ID || 'default_access_key', // Default values for development
        secretAccessKey: process.env.AWS_SECRET_ACCESS_KEY || 'default_secret_key',  
      },
    });
  4. 啟動後端伺服器

    $ node index.js
    

    您將看到後端服務已在連接埠 5000 成功啟動的訊息。

啟動前端服務

若要啟動前端服務,請開啟一個新的終端機並執行以下步驟

  1. 導航至 frontend 目錄

    $ cd frontend
    
  2. 安裝所需的相依套件

    $ npm install
    
  3. 啟動前端服務

    $ npm run dev
    

    現在,您應該會看到以下訊息

    VITE v5.4.2  ready in 110 ms
    ➜  Local: https://:5173/
    ➜  Network: use --host to expose
    ➜  press h + enter to show help
    

    您現在可以透過 https://:5173 存取該應用程式。繼續操作,選擇一個圖片檔案並點擊上傳 (Upload) 按鈕來上傳圖片。

    Diagram showing a working todo-list application

    您可以透過檢查 LocalStack 容器日誌,驗證圖片是否已上傳至 S3 儲存貯體

    Diagram showing the logs of the LocalStack that highlights image uploaded to the emulated S3 bucket

    200 狀態碼表示 putObject 操作(即將物件上傳至 S3 儲存貯體)已在 LocalStack 環境中成功執行。LocalStack 會記錄此條目,以便提供所執行操作的可見性。這有助於偵錯並確認您的應用程式正正確地與模擬的 AWS 服務互動。

    由於 LocalStack 旨在於本地模擬 AWS 服務,此日誌條目顯示您的應用程式在本地沙箱環境中執行雲端操作時,功能符合預期。

從容器化 Node 應用程式連接至 LocalStack

既然您已經了解如何將非容器化的 Node.js 應用程式連接到 LocalStack,現在是時候探索在容器化環境中執行完整應用程式堆疊所需的變更了。為此,您將建立一個 Compose 檔案,指定所有必需的服務 - 前端、後端、資料庫和 LocalStack。

  1. 查看 Docker Compose 檔案。

    以下 Docker Compose 檔案定義了四個服務:backendfrontendmongodblocalstackbackendfrontend 服務是您的 Node.js 應用程式,而 mongodb 提供資料庫,localstack 則模擬 S3 等 AWS 服務。

    backend 服務依賴 localstackmongodb 服務,確保它們在啟動前已執行。它也使用一個 .env 檔案來存放環境變數。前端服務依賴後端並設定了 API URL。mongodb 服務使用持久化磁碟區來儲存資料,而 localstack 已配置為執行 S3 服務。此設定讓您能夠在本地開發和測試具備類 AWS 服務的應用程式。

    services:
      backend:
        build:
          context: ./backend
          dockerfile: Dockerfile
        ports:
          - 5000:5000
        depends_on:
          - localstack
          - mongodb
        env_file:
          - backend/.env
    
      frontend:
        build:
          context: ./frontend
          dockerfile: Dockerfile
        ports:
          - 5173:5173
        depends_on:
          - backend
        environment:
          - REACT_APP_API_URL=http://backend:5000/api
    
      mongodb:
        image: mongo
        container_name: mongodb
        volumes:
          - mongodbdata:/data/db
        ports:
          - 27017:27017
    
      localstack:
        image: localstack/localstack
        container_name: localstack
        ports:
          - 4566:4566
        environment:
          - SERVICES=s3
          - GATEWAY_LISTEN=0.0.0.0:4566
        volumes:
          - ./localstack:/docker-entrypoint-initaws.d"
    
    volumes:
      mongodbdata:
  2. 修改 backend/ 目錄下的 .env 檔案,讓資源使用內部網路名稱進行連接。

    提示

    根據前面的 Compose 檔案,應用程式將使用主機名稱 localstack 連接到 LocalStack,而 Mongo 則使用主機名稱 mongodb 連接。

    MONGODB_URI=mongodb://mongodb:27017/todos
    AWS_ACCESS_KEY_ID=test
    AWS_SECRET_ACCESS_KEY=test
    S3_BUCKET_NAME=mysamplebucket
    S3_ENDPOINT_URL=http://localstack:4566
    AWS_REGION=us-east-1
  3. 停止執行的服務

    請確保透過在終端機中按「Ctrl+C」停止前一個步驟中的 Node 前端和後端服務。此外,您需要透過在 Docker Desktop 儀表板中選取它們並點擊「刪除 (Delete)」按鈕,來停止 LocalStack 和 Mongo 容器。

  4. 在您複製的專案目錄根目錄下執行以下指令,啟動應用程式堆疊

    $ docker compose -f compose.yml up -d --build
    

    稍候片刻,應用程式即可啟動並執行。

  5. 手動建立一個 S3 儲存貯體

    AWS S3 儲存貯體不會由 Compose 檔案預先建立。執行以下指令在 LocalStack 環境中建立一個新的儲存貯體

    $ awslocal s3 mb s3://mysamplebucket
    

    該指令會建立一個名為 mysamplebucket 的 S3 儲存貯體。

    開啟 https://:5173 以存取完整的待辦事項清單應用程式,並開始將圖片上傳到 Amazon S3 儲存貯體。

    提示

    為了在開發過程中優化效能並縮短上傳時間,請考慮上傳較小的圖片檔案。較大的圖片可能需要更長時間處理,並可能影響應用程式的整體回應速度。

重點回顧

本指南帶領您完成了使用 LocalStack 和 Docker 建立本地開發環境的過程。您已了解如何在本地測試基於 AWS 的應用程式,從而降低成本並提高開發工作流程的效率。

© . This site is unofficial and not affiliated with Kubernetes or Docker Inc.