Skip to main content

Docs

이 문서는 프로젝트의 인프라 구성 및 서비스 배포 방법에 대해 설명합니다.

문서 서버 배포 현황​

Main 브랜치 (Production) - AWS​

현재 AWS 기반의 문서 서버 배포가 완료되었습니다.

  • 접속 주소: https://d27m5suuea0hki.cloudfront.net/
  • 배포 방식: docs 서브모듈 Github 레포지토리의 main 브랜치에 Push가 발생하면, Github Actions가 자동으로 빌드 및 S3 배포, CloudFront 캐시 무효화를 수행합니다. (CI/CD 적용 완료)

Development 브랜치 (Preview) - Vercel​

개발 및 테스트를 위한 development 브랜치의 Preview 배포가 Vercel을 통해 새로 구성되었습니다.

  • 접속 주소: (Vercel 배포 후 확인된 주소로 업데이트 예정)
  • 배포 방식: docs 서브모듈 Github 레포지토리의 development 브랜치에 Push가 발생하면, Vercel이 자동으로 빌드 및 배포를 수행합니다.

문서 사이트 아키텍처 (AWS)​

문서 사이트는 S3 + CloudFront 조합의 아키텍처를 사용합니다.

  • AWS S3 (스토리지 및 호스팅): Docusaurus 빌드 결과물(HTML, CSS, JS 등 정적 파일)을 저장하고, 정적 웹사이트 호스팅을 담당합니다.

  • Amazon CloudFront (CDN 및 보안): 사용자의 모든 요청을 받는 단일 진입점입니다. HTTPS 보안을 적용하고, 전 세계 사용자에게 콘텐츠를 빠르게 전송(CDN)하며, OAC(Origin Access Control) 설정을 통해 S3 버킷에 대한 접근을 CloudFront로만 제한하여 보안을 강화합니다.


배포 방법​

자동 배포 (Github Actions 권장)​

docs 레포지토리의 main 브랜치에 변경사항을 Push하는 것만으로 배포의 모든 과정이 자동으로 처리됩니다.

  • 트리거: docs Github 레포지토리의 main 브랜치에 코드가 Push될 때마다 파이프라인이 자동으로 실행됩니다.
  • 실행 과정:
    1. Github Actions 워크플로우가 실행됩니다. (docs/.github/workflows/deploy.yml)
    2. Docusaurus 사이트를 빌드합니다. (npm run build)
    3. 빌드 결과물을 S3 버킷(vivid-ai-docs-dev)에 업로드합니다.
    4. CloudFront 캐시를 무효화(Invalidation)하여 사용자가 즉시 최신 내용을 볼 수 있도록 합니다.
  • 확인: 배포 과정은 docs 레포지토리의 Actions 탭에서 실시간으로 확인할 수 있습니다.

구현 시나리오​

  1. IAM 사용자 및 권한 설정: Github Actions가 AWS 리소스에 접근할 수 있도록, 최소한의 권한(s3:PutObject, cloudfront:CreateInvalidation 등)을 가진 전용 IAM 사용자를 생성합니다.

  2. Github Secrets 등록: 생성된 IAM 사용자의 액세스 키(AWS_ACCESS_KEY_ID, AWS_SECRET_ACCESS_KEY)를 docs 레포지토리의 Settings > Secrets에 안전하게 등록합니다.

  3. 워크플로우 실행:

    • 트리거: docs Github 레포지토리의 main 브랜치에 코드가 Push될 때마다 .github/workflows/deploy.yml 파일에 정의된 파이프라인이 자동으로 실행됩니다.
    • 실행 과정:
      1. Docusaurus 사이트를 빌드합니다. (npm run build)
      2. 빌드 결과물을 S3 버킷(vivid-ai-docs-dev)에 업로드합니다.
      3. CloudFront 캐시를 무효화(Invalidation)하여 사용자가 즉시 최신 내용을 볼 수 있도록 합니다.

수동 배포​

자동 배포 과정에 문제가 발생했거나, 긴급하게 직접 배포해야 할 경우 다음 절차를 따릅니다.

  1. 로컬에서 빌드: 로컬 PC의 docs-vivid-ai/website 폴더로 이동하여 다음 명령어를 실행합니다.

    npm run build
  2. S3에 업로드: AWS CLI가 설치되어 있다면 다음 명령어를 사용해 build 폴더의 내용물을 S3 버킷에 업로드합니다.

    aws s3 sync ./build s3://vivid-ai-docs-dev --delete
    • 만약 AWS CLI가 없다면, AWS S3 콘솔에 접속하여 vivid-ai-docs-dev 버킷에 build 폴더의 모든 내용물을 직접 드래그 앤 드롭하여 업로드합니다.
  3. CloudFront 캐시 무효화 (필수): 수동으로 S3 파일만 변경하면 CloudFront는 변경 사실을 모르고 이전 버전의 캐시를 계속 보여줍니다. 따라서 반드시 캐시를 수동으로 무효화해야 합니다.

    • AWS CloudFront 콘솔 > 해당 배포 선택 > "무효화(Invalidations)" 탭으로 이동합니다.
    • **"무효화 생성(Create invalidation)"**을 클릭하고, 객체 경로에 /* 를 입력하여 전체 캐시를 삭제합니다.

애플리케이션 배포 (EKS)​

이 섹션에서는 EKS(Elastic Kubernetes Service) 클러스터에 애플리케이션 컴포넌트(예: 백엔드, 프론트엔드, 후처리 워커)를 배포하는 방법에 대해 설명합니다.

Docker 이미지 빌드 및 관리​

EKS 클러스터에 배포될 애플리케이션은 Docker 이미지 형태로 제공됩니다.

  • 이미지 아키텍처 고려사항: EKS 워커 노드는 일반적으로 linux/amd64 (x86_64) 아키텍처를 사용합니다. 로컬 개발 환경(예: Apple Silicon Mac)에서 이미지를 빌드할 경우, 기본적으로 arm64 아키텍처용 이미지가 생성될 수 있습니다. 이 경우 EKS 노드에서 이미지를 가져오지 못하는 no match for platform in manifest 에러가 발생할 수 있습니다.

    • 해결책: 이미지를 빌드할 때 --platform linux/amd64 옵션을 명시하여 amd64 아키텍처용으로 빌드해야 합니다.
      docker build --platform linux/amd64 -t \<your-ecr-repository-uri\>:latest .
  • 보안 모범 사례 (.dockerignore): Docker 이미지를 빌드할 때 로컬 개발 환경의 민감한 파일(예: .env, secrets.yaml)이 이미지 내부에 포함되지 않도록 주의해야 합니다.

    • 위험성: .env 파일에 포함된 AWS 자격 증명이나 DB 비밀번호가 이미지 레이어에 평문으로 저장되면, 이미지를 풀(pull) 할 수 있는 누구든지 해당 정보를 열람할 수 있습니다.
    • 해결책: 프로젝트 루트에 .dockerignore 파일을 생성하고, .env 및 기타 민감한 파일을 명시하여 빌드 컨텍스트에서 제외합니다.
      .env
      .git
      *.yaml
  • 프라이빗 레지스트리: 빌드된 Docker 이미지는 AWS ECR(Elastic Container Registry)과 같은 프라이빗 컨테이너 레지스트리에 푸시하여 관리합니다. ECR은 Kubernetes 파드가 이미지를 안전하게 가져올 수 있도록 통합 인증 기능을 제공합니다.

EKS 컴포넌트 배포 (Kubernetes YAML)​

애플리케이션 컴포넌트는 Kubernetes Deployment, Service, Secret 등의 YAML 파일을 통해 EKS 클러스터에 배포됩니다.

1. 시크릿 관리 및 인증 (IRSA)​

애플리케이션이 AWS 리소스(S3, SQS 등)에 접근할 때, 환경에 따라 두 가지 인증 방식을 사용합니다.

  • Development (Dev) 환경: 간편한 구성을 위해 Kubernetes Secret에 AWS Access Key를 저장하여 환경 변수로 주입하는 방식을 사용할 수 있습니다.
    env:
    - name: AWS_ACCESS_KEY_ID
    valueFrom:
    secretKeyRef:
    name: post-processing-worker-secrets-dev
    key: AWS_ACCESS_KEY_ID
  • Production (Prod) 환경 (권장): 보안을 위해 장기(Long-term) 자격 증명을 저장하지 않는 IRSA (IAM Roles for Service Accounts) 방식을 사용합니다.
    • 장점: Access Key 노출 위험이 없으며, 권한을 IAM Role 단위로 세밀하게 제어할 수 있습니다.
    • 구성: Deployment YAML에 serviceAccountName을 명시하고, 해당 ServiceAccount에 IAM Role을 어노테이션으로 연결합니다. (상세 내용은 post-processing-worker 문서 참조)

2. ECR 이미지 풀 인증 (IRSA)​

EKS 클러스터의 파드가 ECR 프라이빗 레지스트리에서 이미지를 가져오려면 인증이 필요합니다. EKS에서는 **IRSA (IAM Role for Service Accounts)**를 사용하는 것이 가장 권장되는 방법입니다.

  • 작동 방식: Kubernetes Service Account에 ECR 이미지를 가져올 수 있는 권한을 가진 AWS IAM Role을 연결합니다. 파드는 해당 Service Account를 사용함으로써 IAM Role의 권한을 자동으로 상속받아 ECR에 인증합니다.
  • 설정 단계:
    1. IAM Policy 생성: ECR에서 이미지를 가져올 수 있는 권한을 가진 IAM Policy를 생성하거나(AmazonEC2ContainerRegistryReadOnly 관리형 정책 사용).
    2. IAM Role 생성 및 Service Account 연결: eksctl 명령어를 사용하여 Service Account에 IAM Role을 연결합니다.
      eksctl create iamserviceaccount \
      --name \<your-service-account-name\> \
      --namespace \<your-namespace\> \
      --cluster \<your-eks-cluster-name\> \
      --attach-policy-arn arn:aws:iam::aws:policy/AmazonEC2ContainerRegistryReadOnly \
      --approve
      (파드가 default Service Account를 사용한다면 --name default를 사용합니다.)
    3. Deployment에 Service Account 지정: Deployment YAML 파일의 spec.template.spec 아래에 serviceAccountName: <your-service-account-name>을 추가합니다. (만약 default Service Account를 사용한다면 이 필드를 생략할 수 있습니다.)
  • 확인 사항:
    • EKS 클러스터에 OIDC Provider가 활성화되어 있어야 합니다.
    • 연결된 IAM Role의 Trust Policy가 Service Account가 Role을 가정할 수 있도록 올바르게 구성되어 있어야 합니다.

3. 네트워크 구성 (VPC Endpoint)​

EKS 워커 노드가 프라이빗 서브넷에 배포된 경우, ECR 및 S3와 같은 AWS 서비스에 안전하게 접근하려면 VPC Endpoint 생성이 필수적입니다. VPC Endpoint가 없으면 image can't be pulled 또는 connection timed out과 같은 네트워크 관련 에러가 발생할 수 있습니다.

  • 필수 Endpoint:
    • com.amazonaws.<your-region>.ecr.api (ECR API)
    • com.amazonaws.<your-region>.ecr.dkr (ECR Docker)
    • com.amazonaws.<your-region>.s3 (S3 Gateway 또는 Interface)
  • 설정 확인: 각 Endpoint의 상태, VPC, 서브넷, 보안 그룹, 라우팅 테이블 설정이 올바른지 확인해야 합니다.

자세한 시스템 아키텍처는 아키텍처 문서를 참조하십시오.