iT邦幫忙

2025 iThome 鐵人賽

DAY 28
0

前言

經過27天的開發與測試,我們的智慧文檔分析系統已經具備完整功能。
但要真正為使用者提供服務,我們還需要將應用部署到生產環境。
今天我們將學習如何使用AWS的各種服務,將應用程式安全、穩定地部署到雲端,並建立監控與維護機制。
延續上一天的專案
是時候把一切集大成了

基本架構

使用者請求
    ↓
CloudFront (CDN)
    ↓
Application Load Balancer
    ↓
ECS Fargate / App Runner
    ↓
├─ Bedrock (AI推論)
├─ Textract (文字識別)
├─ S3 (檔案儲存)
└─ RDS/DynamoDB (資料)
    ↓
CloudWatch (監控與日誌)

關鍵考慮因素

  • 可擴展性:自動調整資源因應流量變化
  • 可用性:多可用區部署,確保高可用
  • 安全性:加密傳輸、身份驗證、權限控制
  • 成本效益:選擇適合的服務和定價模式
  • 監控與維護:完善的日誌和告警機制

部署考量
Solution 1 : AWS app runner AWS app runner

特色 :

  • 最簡單的部署方式
  • 自動擴展和負載均衡
  • 整合CI/CD
  • 按使用量付費

使用場景

中小型應用
快速上線需求
團隊規模較小

Solution 2 : ECS Fargate

  • 無需管理伺服器
  • 更精細的控制
  • 容器化部署
  • 與其他AWS服務深度整合

使用場景

需要更多控制權
複雜的微服務架構
已有容器化經驗

Solution 3 : Lambda + API Gateway

  • 完全無伺服器
  • 按請求付費
  • 自動擴展

使用場景

間歇性流量
API服務
成本敏感型專案

讓我們開始吧

我們這裡展示 App runner 部署

這裡我們需要建立 Dockerfile

# 使用官方Python映像
FROM python:3.11-slim

# 設定工作目錄
WORKDIR /app

# 安裝系統依賴
RUN apt-get update && apt-get install -y \
    gcc \
    && rm -rf /var/lib/apt/lists/*

# 複製requirements
COPY requirements.txt .

# 安裝Python依賴
RUN pip install --no-cache-dir -r requirements.txt

# 複製應用程式碼
COPY . .

# 建立非root使用者
RUN useradd -m -u 1000 appuser && \
    chown -R appuser:appuser /app
USER appuser

# 暴露端口
EXPOSE 8501

# 健康檢查
HEALTHCHECK --interval=30s --timeout=3s --start-period=40s --retries=3 \
    CMD curl -f http://localhost:8501/_stcore/health || exit 1

# 啟動應用
CMD ["streamlit", "run", "app.py", \
     "--server.port=8501", \
     "--server.address=0.0.0.0", \
     "--server.headless=true", \
     "--server.enableCORS=false", \
     "--server.enableXsrfProtection=true"]

環境變數管理

config.py

import os
from dataclasses import dataclass

@dataclass
class Config:
    """應用程式配置"""
    # AWS配置
    AWS_REGION: str = os.getenv('AWS_REGION', '<你的 region>')
    S3_BUCKET: str = os.getenv('S3_BUCKET', 'my-doc-bucket')
    
    # Bedrock配置
    BEDROCK_MODEL_ID: str = os.getenv(
        'BEDROCK_MODEL_ID',
        'anthropic.claude-3-5-sonnet-20241022-v2:0'
    )
    
    # 應用配置
    MAX_FILE_SIZE: int = int(os.getenv('MAX_FILE_SIZE', 10 * 1024 * 1024))  # 10MB
    UPLOAD_TIMEOUT: int = int(os.getenv('UPLOAD_TIMEOUT', 300))  # 5分鐘
    
    # 監控配置
    LOG_LEVEL: str = os.getenv('LOG_LEVEL', 'INFO')
    ENABLE_METRICS: bool = os.getenv('ENABLE_METRICS', 'true').lower() == 'true'
    
    # 安全配置
    ALLOWED_ORIGINS: list = os.getenv(
        'ALLOWED_ORIGINS',
        '*'
    ).split(',')

config = Config()

建立 ECR

對 docker 相關的知識以及容器化不夠熟悉的可以參考 Docker官網
並參考 AWS ECR

aws ecr create-repository \
    --repository-name document-analyzer \
    --region <你的region>

# 登入ECR
aws ecr get-login-password --region <你的Region> | \
    docker login --username AWS --password-stdin \
    <account-id>.dkr.ecr.<你的Region>.amazonaws.com

# 建構映像
docker build -t document-analyzer:latest .

# 標記映像
docker tag document-analyzer:latest \
    <account-id>.dkr.ecr.<你的Region>.amazonaws.com/document-analyzer:latest

# 推送映像
docker push <account-id>.dkr.ecr.<你的Region>.amazonaws.com/document-analyzer:latest

建立 AppRunner 配置

apprunner.yml

version: 1.0
runtime: python311

build:
  commands:
    build:
      - pip install -r requirements.txt

run:
  runtime-version: 3.11.0
  command: streamlit run app.py --server.port=8080
  network:
    port: 8080
    env: APP_PORT
  env:
    - name: AWS_REGION
      value: <你的Region>
    - name: LOG_LEVEL
      value: INFO

用 AWS cli 部署

# 建立服務
aws apprunner create-service \
    --service-name document-analyzer \
    --source-configuration '{
        "ImageRepository": {
            "ImageIdentifier": "<account-id>.dkr.ecr.<你的region>.amazonaws.com/document-analyzer:latest",
            "ImageConfiguration": {
                "Port": "8501",
                "RuntimeEnvironmentVariables": {
                    "AWS_REGION": "<你的Region>",
                    "S3_BUCKET": "my-doc-bucket"
                }
            },
            "ImageRepositoryType": "ECR"
        },
        "AutoDeploymentsEnabled": true,
        "AuthenticationConfiguration": {
            "AccessRoleArn": "arn:aws:iam::<account-id>:role/AppRunnerECRAccessRole"
        }
    }' \
    --instance-configuration '{
        "Cpu": "1 vCPU",
        "Memory": "2 GB"
    }' \
    --health-check-configuration '{
        "Protocol": "HTTP",
        "Path": "/_stcore/health",
        "Interval": 10,
        "Timeout": 5,
        "HealthyThreshold": 1,
        "UnhealthyThreshold": 5
    }' \
    --auto-scaling-configuration-arn \
        "arn:aws:apprunner:<你的Region>:<account-id>:autoscalingconfiguration/DefaultConfiguration/1/00000000000000000000000000000001"

Iam 建立 assume Role

{
    "Version": "2012-10-17",
    "Statement": [
        {
            "Effect": "Allow",
            "Principal": {
                "Service": "build.apprunner.amazonaws.com"
            },
            "Action": "sts:AssumeRole"
        }
    ]
}

policy

{
    "Version": "2012-10-17",
    "Statement": [
        {
            "Effect": "Allow",
            "Action": [
                "ecr:GetDownloadUrlForLayer",
                "ecr:BatchGetImage",
                "ecr:BatchCheckLayerAvailability",
                "ecr:GetAuthorizationToken"
            ],
            "Resource": "*"
        },
        {
            "Effect": "Allow",
            "Action": [
                "bedrock:InvokeModel"
            ],
            "Resource": "arn:aws:bedrock:*::foundation-model/*"
        },
        {
            "Effect": "Allow",
            "Action": [
                "s3:GetObject",
                "s3:PutObject",
                "s3:DeleteObject"
            ],
            "Resource": "arn:aws:s3:::my-doc-bucket/*"
        },
        {
            "Effect": "Allow",
            "Action": [
                "textract:DetectDocumentText",
                "textract:AnalyzeDocument"
            ],
            "Resource": "*"
        },
        {
            "Effect": "Allow",
            "Action": [
                "logs:CreateLogGroup",
                "logs:CreateLogStream",
                "logs:PutLogEvents"
            ],
            "Resource": "arn:aws:logs:*:*:*"
        }
    ]
}

其他部分關於成本以及監控,在先前已有展示,讀者可以自行練習

可以參考的資源


上一篇
總整合專案:智慧文檔分析系統
系列文
從零開始的AWS AI之路:用Bedrock與SageMaker打造智慧應用的30天實戰28
圖片
  熱門推薦
圖片
{{ item.channelVendor }} | {{ item.webinarstarted }} |
{{ formatDate(item.duration) }}
直播中

尚未有邦友留言

立即登入留言