AWS CLI를 사용하여 AWS S3에 Hugo 사이트 배포하기

AWS S3로 허구(Hugo) 배포 자동화

Page content

AWS CLI를 사용하여 Hugo 정적 사이트를 AWS S3에 배포하면 웹사이트를 호스팅하는 데 견고하고 확장 가능한 솔루션을 제공합니다. 이 가이드는 초기 설정부터 고급 자동화 및 캐시 관리 전략까지 완전한 배포 프로세스를 다룹니다.

테이블 위의 컬러 테트리스

AWS CLI를 사용한 배포는 hugo 배포가 표준 패키지에서 deploy 명령을 제거하면서 점점 g-to 접근 방식이 되고 있습니다. 로컬에서 실행하면서 여전히 hugo deploy를 사용하고자 한다면 How to Install Ubuntu 24.04 & useful tools에서 extendedwithdeploy에 대해 확인하세요.

사전 조건

Hugo 사이트를 AWS S3에 배포하기 전에 다음을 확인하세요:

  • 배포 준비가 된 Hugo 사이트 (사이트 생성이 필요하다면 Hugo quickstart guide를 참조하세요)
  • 적절한 권한을 가진 AWS 계정
  • 설치 및 구성된 AWS CLI
  • 명령줄 작업에 대한 기본 지식

Hugo 사이트 빌드

Hugo 사이트를 배포하는 첫 단계는 정적 파일을 생성하는 것입니다. 사용 가능한 명령어 및 옵션에 대한 참조는 Hugo Cheat Sheet를 참조하세요.

최적화 플래그와 함께 사이트를 빌드합니다:

hugo --gc --minify

--gc 플래그는 사용되지 않은 캐시 파일을 제거하고, --minify 플래그는 HTML, CSS, JavaScript를 최적화된 상태로 압축합니다. 이는 public/ 디렉토리에 정적 사이트를 생성하고, 이 디렉토리를 S3에 배포하게 됩니다.

AWS CLI 구성

AWS CLI를 구성하지 않았다면 다음 명령어를 실행하세요:

aws configure

다음 항목을 입력하라는 메시지가 나타납니다:

  • AWS Access Key ID: AWS 액세스 키
  • AWS Secret Access Key: 비밀 액세스 키
  • Default region: 선호하는 AWS 리전 (예: us-east-1, ap-southeast-2)
  • Default output format: json (권장)

프로그램적 액세스를 위해 IAM 사용자가 다음 권한을 가져야 합니다:

  • s3:PutObject
  • s3:GetObject
  • s3:DeleteObject
  • s3:ListBucket
  • cloudfront:CreateInvalidation (CloudFront를 사용하는 경우)

S3 버킷 생성 및 구성

버킷 생성

AWS CLI를 사용하여 S3 버킷을 생성합니다:

aws s3 mb s3://your-bucket-name --region us-east-1

중요: 전역적으로 고유한 버킷 이름을 선택하세요. 커스텀 도메인을 사용하여 버킷을 웹사이트 호스팅에 사용할 계획이라면, 버킷 이름이 도메인 이름과 일치해야 합니다.

정적 웹사이트 호스팅 구성

정적 웹사이트 호스팅을 활성화합니다:

aws s3 website s3://your-bucket-name \
  --index-document index.html \
  --error-document 404.html

버킷 정책 설정

공개 읽기 권한이 필요한 경우 (CloudFront를 사용하지 않는 경우), 버킷 정책을 생성합니다:

{
  "Version": "2012-10-17",
  "Statement": [
    {
      "Sid": "PublicReadGetObject",
      "Effect": "Allow",
      "Principal": "*",
      "Action": "s3:GetObject",
      "Resource": "arn:aws:s3:::your-bucket-name/*"
    }
  ]
}

정책을 적용합니다:

aws s3api put-bucket-policy \
  --bucket your-bucket-name \
  --policy file://bucket-policy.json

보안 참고: CloudFront를 사용하는 경우 (권장), S3 버킷 액세스를 CloudFront에만 제한하여 공개 읽기 권한이 필요하지 않게 만들 수 있습니다.

AWS CLI를 사용한 S3 배포

핵심 배포 명령은 aws s3 sync를 사용하여 사이트를 업로드합니다:

aws s3 sync public/ s3://your-bucket-name/ \
  --delete \
  --cache-control max-age=60

주요 파라미터 설명

  • public/: 로컬 Hugo 출력 디렉토리
  • s3://your-bucket-name/: S3 버킷 목적지
  • --delete: 로컬에 없는 파일을 S3에서 제거하여 버킷이 빌드와 동기화되도록 합니다
  • --cache-control max-age=60: 캐시 헤더를 설정 (이 예시에서는 60초)

고급 싱크 옵션

배포에 대한 더 많은 제어를 원한다면:

aws s3 sync public/ s3://your-bucket-name/ \
  --delete \
  --cache-control "public, max-age=31536000, immutable" \
  --exclude "*.html" \
  --cache-control "public, max-age=60" \
  --include "*.html" \
  --exclude "*.js" \
  --cache-control "public, max-age=31536000, immutable" \
  --include "*.js"

이 예시에서는 HTML 파일에 대해 60초의 캐시 기간을 설정하고 정적 자산(예: JavaScript)에 대해서는 1년의 캐시 기간을 설정합니다. 이는 일반적인 최적화 전략입니다.

CloudFront 분배 설정

S3가 직접적으로 정적 웹사이트를 호스팅할 수 있지만, Amazon CloudFront를 CDN으로 사용하면 성능, 보안, 글로벌 분배가 향상됩니다.

CloudFront 분배 생성

aws cloudfront create-distribution \
  --distribution-config file://cloudfront-config.json

기본적인 CloudFront 구성에는 다음과 같은 항목이 포함됩니다:

  • S3 버킷을 원본으로 사용
  • 기본 캐시 행동
  • SSL/TLS 인증서 (AWS Certificate Manager에서)
  • 커스텀 도메인 구성 (선택 사항)

캐시 관리 전략

CloudFront를 통해 배포할 경우 다음 캐시 전략을 고려하세요:

  1. 최대 TTL 설정: CloudFront의 최대 TTL을 설정하여 엣지 위치에서 콘텐츠가 얼마나 오래 캐시되는지 제어합니다.
  2. 콘텐츠 버전 관리: 파일 이름에 버전 식별자(예: style-v2.css)를 사용하여 캐시 업데이트를 강제합니다.
  3. 캐시-컨트롤 헤더 설정: S3 싱크 동안 적절한 헤더를 설정 (이전에 보여드린 예시와 같습니다)
  4. 선택적 무효화: 전체 캐시가 아닌 변경된 경로만 무효화합니다.

캐시 무효화

업데이트를 배포한 후 CloudFront 캐시를 무효화하여 최신 콘텐츠를 제공합니다:

aws cloudfront create-invalidation \
  --distribution-id YOUR_DISTRIBUTION_ID \
  --paths "/*"

더 정확한 무효화를 원한다면:

aws cloudfront create-invalidation \
  --distribution-id YOUR_DISTRIBUTION_ID \
  --paths "/index.html" "/blog/*"

비용 고려 사항: 월별 첫 1,000개의 무효화 경로는 무료입니다. 이후에는 각 경로당 $0.005가 부과됩니다. 선택적 무효화를 사용하여 비용을 최소화하세요.

CI/CD를 통한 자동화

작은 프로젝트에서는 수동 배포가 작동하지만, 프로덕션 워크플로우에서는 자동화가 필수적입니다. 이 배포 프로세스를 Gitea Actions to deploy Hugo website to AWS S3 또는 유사한 CI/CD 파이프라인과 통합할 수 있습니다.

기본 배포 스크립트

간단한 배포 스크립트를 생성합니다:

#!/bin/bash
set -e

# Hugo 사이트 빌드
echo "Building Hugo site..."
hugo --gc --minify

# S3에 배포
echo "Deploying to S3..."
aws s3 sync public/ s3://your-bucket-name/ \
  --delete \
  --cache-control max-age=60

# CloudFront 캐시 무효화
echo "Invalidating CloudFront cache..."
aws cloudfront create-invalidation \
  --distribution-id YOUR_DISTRIBUTION_ID \
  --paths "/*"

echo "Deployment complete!"

실행 가능한 파일로 만들어 실행합니다:

chmod +x deploy.sh
./deploy.sh

GitHub Actions 예시

GitHub 저장소를 위해 .github/workflows/deploy.yml을 생성합니다:

name: Deploy to AWS S3

on:
  push:
    branches: [ main ]

jobs:
  deploy:
    runs-on: ubuntu-latest
    steps:
      - uses: actions/checkout@v3
      
      - name: Setup Hugo
        uses: peaceiris/actions-hugo@v2
        with:
          hugo-version: 'latest'
      
      - name: Build
        run: hugo --gc --minify
      
      - name: Configure AWS credentials
        uses: aws-actions/configure-aws-credentials@v2
        with:
          aws-access-key-id: ${{ secrets.AWS_ACCESS_KEY_ID }}
          aws-secret-access-key: ${{ secrets.AWS_SECRET_ACCESS_KEY }}
          aws-region: us-east-1
      
      - name: Deploy to S3
        run: |
          aws s3 sync public/ s3://your-bucket-name/ \
            --delete \
            --cache-control max-age=60          
      
      - name: Invalidate CloudFront
        run: |
          aws cloudfront create-invalidation \
            --distribution-id ${{ secrets.CLOUDFRONT_DISTRIBUTION_ID }} \
            --paths "/*"          

모니터링 및 최적화

로깅 활성화

접근 패턴을 추적하기 위해 S3 및 CloudFront 로깅을 구성합니다:

# S3 액세스 로깅 활성화
aws s3api put-bucket-logging \
  --bucket your-bucket-name \
  --bucket-logging-status file://logging.json

CloudWatch 알림 설정

CloudWatch를 사용하여 배포를 모니터링합니다:

aws cloudwatch put-metric-alarm \
  --alarm-name high-error-rate \
  --alarm-description "Alert on high error rate" \
  --metric-name 4xxError \
  --namespace AWS/CloudFront \
  --statistic Sum \
  --period 300 \
  --threshold 10 \
  --comparison-operator GreaterThanThreshold

일반적인 문제 해결

파일이 업데이트되지 않음

변경사항이 반영되지 않는다면 다음을 확인하세요:

  1. CloudFront 캐시 무효화 상태 확인
  2. 싱크 명령어에 --delete 플래그가 사용되었는지 확인
  3. 브라우저 캐시를 지우거나 익명 모드에서 테스트
  4. S3 버킷 권한 확인

느린 배포

싱크 성능을 최적화하세요:

  • --exclude--include를 사용하여 불필요한 파일을 건너뛰세요
  • --size-only를 사용하여 비교를 더 빠르게 수행
  • --cli-read-timeout--cli-write-timeout과 함께 병렬 업로드를 사용

권한 오류

IAM 사용자가 다음 권한을 가져야 합니다:

  • S3 버킷 액세스 권한
  • CloudFront 무효화 권한 (적용 가능 시)
  • 올바른 버킷 정책 구성

최선의 실천 요약

  1. 항상 --delete를 사용하세요 - 로컬 빌드와 S3를 동기화하기 위해
  2. 파일 유형에 따라 적절한 캐시 헤더를 설정하세요
  3. 프로덕션 배포에 CloudFront를 사용하세요
  4. CI/CD 파이프라인을 통해 배포를 자동화하세요
  5. 비용을 모니터링하세요 - CloudFront 무효화 비용에 주의하세요
  6. 배포를 버전화하세요 - 롤백이 쉬운 방식으로 릴리스를 태그하세요
  7. 로컬에서 테스트하세요 - 배포하기 전에 Hugo 빌드를 확인하세요

관련 자료

Hugo 배포에 대한 더 상세한 정보는 deploying Hugo-generated website to AWS S3에 있는 포괄적인 가이드를 참조하세요. 이 가이드는 추가 배포 옵션 및 구성 사항을 다룹니다.

내용을 작성할 때, 코드 예제를 위해 Markdown code blocks을 사용하고, Comprehensive Markdown Cheatsheet를 참조하여 포맷 가이드라인을 따르세요.

유용한 링크

외부 참고 자료