디스코드-봇 클라우드 환경 호스팅 구축 과정/가이드

이재영·2025년 5월 6일
post-thumbnail

👾 Intro.

최근에 구현한 gemini 모델을 사용하여 디스코드 채널 메세지를 시간/메세지갯수 별로 요약해주는 디스코드-봇을 클라우드 환경에 배포하는 과정을 담아보았습니다! Python 코드를 Docker를 사용하여 컨테이너화하고, AWS ECR(Elastic Container Registry)에 이미지를 publish한 후, AWS EC2(Elastic Compute Cloud) 인스턴스에 배포하여 호스팅하는 전 과정을 쓱 다뤄보겠습니다...

이 글의 구축 과정은 소규모 24/7 호스팅에 적합하며, 최대한 AWS 프리 티어(Free Tier) 범위 내에서 운영하여 비용 발생을 최소화하는 것을 목표로 하므로 참고바랍니다!


🔸 사전 준비:

  1. AWS 계정: 프리 티어를 활용할 수 있는 AWS 계정이 필요합니다. (가입 후 12개월간 특정 서비스 무료 제공)
  2. GitHub Repository 로컬 클론: 배포할 봇의 소스 코드를 로컬 컴퓨터에 받아야 합니다.
    git clone https://github.com/squatboy/gemini-discord-summarizer-bot.git
    cd gemini-discord-summarizer-bot
  3. Discord 봇 토큰: Discord Developer Portal에서 봇을 생성하고 토큰을 발급받아야 합니다. 토큰은 절대 외부에 노출되지 않도록 주의하세요!!
  4. Google Gemini API 키: Google AI Studio 에서 API 키를 발급받아야 합니다. API 키도 절대 외부에 노출되지 않도록 주의하세요!
  5. Docker Desktop 설치: 로컬 컴퓨터에 Docker 이미지를 빌드하기 위해 Docker Desktop이 설치되어 있어야 합니다. Docker 공식 홈페이지에서 다운로드 및 설치
  6. AWS CLI 설치 및 구성: 로컬 컴퓨터 및 EC2 인스턴스에서 AWS 서비스와 상호작용하기 위해 AWS Command Line Interface(CLI)가 필요합니다.
    • AWS CLI 설치 가이드
    • 설치 후, IAM 사용자의 Access Key ID와 Secret Access Key를 사용하여 구성합니다. ECR Push 권한이 있는 IAM 사용자를 사용하는 것이 좋습니다.
      aws configure
      # AWS Access Key ID 입력
      # AWS Secret Access Key 입력
      # Default region name 입력 (예: ap-northeast-2)
      # Default output format 입력 (예: json)

🔹 배포 단계:

🔸 1) Dockerfile 생성

프로젝트 루트 디렉토리(gemini-discord-summarizer-bot)에 Dockerfile이라는 이름의 파일을 생성하고 다음 내용을 작성합니다. 이 파일은 Docker 이미지를 빌드하는 방법을 정의합니다.

# 1. 베이스 이미지 선택 (Python 3.10 슬림 버전 사용)
FROM python:3.10-slim

# 2. 작업 디렉토리 설정
WORKDIR /app

# 3. 필요한 파일 복사 (먼저 requirements.txt만 복사하여 의존성 캐싱 활용)
COPY requirements.txt ./

# 4. Python 의존성 설치
# --no-cache-dir: 불필요한 캐시 저장 방지하여 이미지 크기 줄임
# --upgrade pip: pip 최신 버전으로 업그레이드
RUN pip install --no-cache-dir --upgrade pip && \
    pip install --no-cache-dir -r requirements.txt

# 5. 나머지 프로젝트 파일 복사
COPY . .

# 6. 환경 변수 설정 (실제 값은 실행 시 주입)
# Dockerfile에는 실제 키를 넣지 않습니다!
ENV DISCORD_BOT_TOKEN=YOUR_DISCORD_BOT_TOKEN_PLACEHOLDER
ENV GOOGLE_API_KEY=YOUR_GOOGLE_API_KEY_PLACEHOLDER

# 7. 컨테이너 실행 시 실행될 명령어 정의 (봇 실행 파일 확인 필요, 여기서는 bot.py로 가정)
CMD ["python", "bot.py"]

주의:

  • bot.py가 봇을 실행하는 메인 파이썬 파일이 맞는지 확인하세요. 만약 다른 파일이라면 CMD 부분을 수정해야 합니다.
  • ENV 부분은 플레이스홀더이며, 실제 토큰/키는 보안을 위해 컨테이너 실행 시점에 주입할 것입니다. 절대 Dockerfile에 실제 키를 하드코딩하지 마세요.

🔸 2) AWS ECR 리포지토리 생성

Docker 이미지를 저장할 ECR 리포지토리를 생성합니다.

  1. AWS Management Console에 로그인합니다.
  2. 서비스 검색창에서 ECR (Elastic Container Registry)을 검색하고 선택합니다.
  3. 리포지토리를 생성할 리전(Region)을 선택합니다. (예: 서울 ap-northeast-2) EC2 인스턴스와 같은 리전을 사용하는 것이 좋습니다.
  4. 리포지토리 생성(Create repository) 버튼을 클릭합니다.
  5. 가시성 설정(Visibility settings): 프라이빗(Private) (기본값, 권장)
  6. 리포지토리 이름(Repository name): 원하는 이름을 지정합니다. (예: gemini-discord-bot)
  7. 나머지 설정은 기본값으로 두고 리포지토리 생성(Create repository) 버튼을 클릭합니다.
  8. 생성된 리포지토리를 클릭하면 URI 정보가 표시됩니다. 이 URI는 다음 단계에서 이미지를 태그하고 푸시할 때 필요합니다. (형태: ACCOUNT_ID.dkr.ecr.REGION.amazonaws.com/REPOSITORY_NAME)

🔸 3) Docker 이미지 빌드 및 ECR 푸시

로컬 컴퓨터에서 Docker 이미지를 빌드하고 생성된 ECR 리포지토리로 푸시합니다.

  1. ECR 로그인: 로컬 Docker CLI가 ECR에 인증하도록 합니다. 터미널에서 다음 명령어를 실행합니다. (AWS CLI가 구성되어 있어야 함)

    • <REGION>: ECR 리포지토리를 생성한 리전 (예: ap-northeast-2)
    • <ACCOUNT_ID>: 본인의 AWS 계정 ID
    aws ecr get-login-password --region <REGION> | docker login --username AWS --password-stdin <ACCOUNT_ID>.dkr.ecr.<REGION>.amazonaws.com

    "Login Succeeded" 메시지가 표시되면 성공입니다.

  2. Docker 이미지 빌드: Dockerfile이 있는 디렉토리(gemini-discord-summarizer-bot)에서 다음 명령어를 실행합니다.

    • <REPOSITORY_URI>: 2단계에서 확인한 ECR 리포지토리 URI (예: 123456789012.dkr.ecr.ap-northeast-2.amazonaws.com/gemini-discord-bot)
    • <TAG>: 이미지 버전 또는 식별자 (예: latest)
    docker build -t <REPOSITORY_URI>:<TAG> .
    

⚠️ 주의!! EC2에 맞는 amd64(x86_64) 아키텍처로 이미지 빌드해야됨!!
저는 buildx를 사용해 멀티 아키텍처 이미지를 빌드했습니다!

예시:

docker buildx build --platform linux/amd64 \
  -t 123456789012.dkr.ecr.ap-northeast-2.amazonaws.com/discord-summary-bot:latest \
  --push .
  1. Docker 이미지 푸시: 빌드된 이미지를 ECR로 푸시합니다.

    docker push <REPOSITORY_URI>:<TAG>

    예시:

    docker push 123456789012.dkr.ecr.ap-northeast-2.amazonaws.com/gemini-discord-bot:latest

    푸시가 완료되면 AWS ECR 콘솔에서 해당 리포지토리에 이미지가 업로드된 것을 확인할 수 있습니다


🔸 4) EC2 인스턴스 생성 (프리 티어 활용)

봇을 실행할 EC2 인스턴스를 생성합니다.

  1. AWS Management Console에서 EC2 서비스를 선택합니다.

  2. ECR 리포지토리를 생성한 리전과 동일한 리전을 선택합니다.

  3. 인스턴스 시작(Launch instances) 버튼을 클릭합니다.

  4. 이름 및 태그(Name and tags): 인스턴스를 식별할 이름을 입력합니다. (예: discord-bot-server)

  5. 애플리케이션 및 OS 이미지(AMI): 프리 티어 사용 가능 옵션을 선택합니다.

    • Amazon Linux 2 AMI (HVM) - Kernel 5.10, SSD Volume Type (권장, 프리 티어)
    • Ubuntu Server 20.04 LTS (HVM), SSD Volume Type (프리 티어)
  6. 인스턴스 유형(Instance type): t2.micro 또는 t3.micro (리전에 따라 프리 티어 제공 여부 확인)를 선택합니다. t2.micro가 가장 일반적인 프리 티어 옵션입니다.

  7. 키 페어(로그인)(Key pair (login)): SSH 접속에 사용할 키 페어를 생성하거나 기존 키 페어를 선택합니다.

    • 새 키 페어 생성: 키 페어 이름을 입력하고 .pem 파일을 다운로드하여 안전한 곳에 보관합니다. 이 파일은 인스턴스 접속에 필수적이므로 분실하지 않도록 주의하세요.
  8. 네트워크 설정(Network settings):

    • 방화벽(보안 그룹)(Firewall (security groups)):
      • 보안 그룹 생성(Create security group) 선택 (또는 기존 그룹 사용)
      • 보안 그룹 이름설명 입력 (예: discord-bot-sg)
      • 인바운드 보안 그룹 규칙(Inbound security group rules):
        • SSH 규칙: 기본적으로 추가되어 있습니다. 소스를 내 IP(My IP)로 변경하여 본인의 IP 주소에서만 접속 가능하도록 제한하는 것이 보안상 안전합니다. (고정 IP가 아닌 경우, 접속할 때마다 IP를 업데이트해야 할 수 있습니다.)
        • Discord 봇은 일반적으로 외부에서 인스턴스로 들어오는 연결(Inbound)을 필요로 하지 않습니다. Discord API 서버로 나가는 연결(Outbound)만 사용하므로, 추가적인 인바운드 규칙은 필요 없을 가능성이 높습니다.
    • 고급 네트워크 구성(Advanced network configuration): 기본 VPC 및 서브넷 설정을 그대로 사용해도 무방합니다.
  9. 스토리지 구성(Configure storage): 프리 티어는 최대 30GB의 EBS 범용(SSD) 스토리지를 제공합니다. 기본값(8GB 또는 10GB)으로도 충분합니다.

  10. 고급 세부 정보(Advanced details): IAM 인스턴스 프로파일(IAM instance profile) 항목이 중요합니다.

    • IAM 역할 생성: EC2 인스턴스가 별도의 자격 증명 없이 ECR에서 이미지를 가져올 수 있도록 IAM 역할을 생성하고 연결하는 것이 가장 안전하고 편리합니다.
      • AWS Console에서 IAM 서비스로 이동합니다.
      • 역할(Roles) -> 역할 만들기(Create role) 클릭합니다.
      • 신뢰할 수 있는 엔터티 유형(Trusted entity type): AWS 서비스 선택
      • 사용 사례(Use case): EC2 선택 후 다음.
      • 권한 추가(Add permissions): AmazonEC2ContainerRegistryReadOnly 정책을 검색하여 선택합니다. 이 정책은 ECR에서 이미지를 가져올(pull) 수 있는 권한만 부여합니다.
      • 다음 -> 역할 이름 입력 (예: EC2-ECR-Pull-Role) -> 역할 만들기(Create role).
    • 다시 EC2 인스턴스 생성 화면으로 돌아와 고급 세부 정보IAM 인스턴스 프로파일에서 방금 생성한 역할(예: EC2-ECR-Pull-Role)을 선택합니다.
  11. 요약(Summary): 설정을 검토하고 인스턴스 시작(Launch instance) 버튼을 클릭합니다.


🔸 5) EC2 인스턴스 접속 및 Docker 설정

생성된 EC2 인스턴스에 SSH로 접속하여 Docker를 설치하고 설정합니다.

  1. EC2 인스턴스 상태 확인: EC2 대시보드에서 인스턴스 상태가 실행 중(Running)이 될 때까지 기다립니다.
  2. 인스턴스 연결 정보 확인: 해당 인스턴스를 선택하고 연결(Connect) 버튼을 클릭합니다. SSH 클라이언트 탭에 표시된 예제 명령어를 복사합니다. (예: ssh -i "your-key.pem" ec2-user@ec2-XX-XX-XX-XX.REGION.compute.amazonaws.com)
  1. SSH 접속: 로컬 컴퓨터 터미널에서 .pem 키 파일이 있는 디렉토리로 이동한 후, 복사한 명령어를 실행하여 인스턴스에 접속합니다. (키 파일 권한 오류 시 chmod 400 your-key.pem 실행)
    • Amazon Linux 2: 사용자 이름은 ec2-user
    • Ubuntu: 사용자 이름은 ubuntu
  2. 시스템 업데이트:
    • Amazon Linux 2:
      sudo yum update -y
    • Ubuntu:
      sudo apt update && sudo apt upgrade -y
  3. Docker 설치:
    • Amazon Linux 2:
      sudo yum install docker -y
      sudo systemctl start docker
      sudo systemctl enable docker # 부팅 시 Docker 자동 시작
      sudo usermod -a -G docker ec2-user # ec2-user가 sudo 없이 docker 명령어 사용하도록 (재로그인 필요)
      newgrp docker # 현재 세션에 그룹 변경 적용 (또는 재로그인)
    • Ubuntu:
      sudo apt install docker.io -y
      sudo systemctl start docker
      sudo systemctl enable docker
      sudo usermod -aG docker ubuntu # ubuntu 사용자를 docker 그룹에 추가 (재로그인 필요)
      newgrp docker # 현재 세션에 그룹 변경 적용 (또는 재로그인)
  4. Docker 설치 확인:
    docker --version

🔸 6) EC2에서 Docker 컨테이너 실행

EC2 인스턴스에서 ECR 이미지를 가져와 Discord 봇 컨테이너를 실행합니다.

  1. (선택사항 - IAM 역할 미사용 시) ECR 로그인: 4단계에서 IAM 역할을 설정했다면 이 단계는 필요 없습니다. 역할을 사용하지 않았다면, EC2 인스턴스에 AWS CLI를 설치하고 구성한 후 다음 명령어로 ECR에 로그인해야 합니다.

    # AWS CLI 설치 (Amazon Linux 2에는 보통 기본 설치됨)
    # sudo yum install aws-cli -y  (Amazon Linux)
    # sudo apt install awscli -y   (Ubuntu)
    
    # AWS CLI 구성 (Access Key/Secret Key 입력)
    # aws configure
    
    # ECR 로그인
    aws ecr get-login-password --region <REGION> | docker login --username AWS --password-stdin <ACCOUNT_ID>.dkr.ecr.<REGION>.amazonaws.com

    보안상 IAM 역할을 사용하는 것이 강력히 권장됩니다.

  2. ECR 이미지 가져오기(Pull):

    docker pull <REPOSITORY_URI>:<TAG>

    예시:

    docker pull 123456789012.dkr.ecr.ap-northeast-2.amazonaws.com/gemini-discord-bot:latest
  3. Docker 컨테이너 실행: -e 옵션을 사용하여 환경 변수(봇 토큰, API 키)를 주입하고, -d 옵션으로 백그라운드에서 실행합니다. --restart unless-stopped 옵션은 예기치 않게 컨테이너가 종료되거나 서버가 재부팅될 경우 자동으로 컨테이너를 다시 시작해줍니다.

    docker run -d \
      --name gemini-discord-bot \
      -e DISCORD_BOT_TOKEN="여기에_실제_디스코드_봇_토큰_입력" \
      -e GOOGLE_API_KEY="여기에_실제_구글_API_키_입력" \
      --restart unless-stopped \
      <REPOSITORY_URI>:<TAG>

    예시:

    docker run -d \
      --name gemini-discord-bot \
      -e DISCORD_BOT_TOKEN="Mxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx" \
      -e GOOGLE_API_KEY="AIzaxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx" \
      --restart unless-stopped \
      123456789012.dkr.ecr.ap-northeast-2.amazonaws.com/gemini-discord-bot:latest

    명령어 입력 시 실제 토큰과 키 값으로 바꿔주세요!

🔸 7) 봇 작동 확인 및 로그 확인

  1. 컨테이너 실행 상태 확인:

    docker ps

    gemini-discord-bot 컨테이너가 Up 상태로 표시되는지 확인합니다.

  2. 컨테이너 로그 확인: 봇이 정상적으로 시작되었는지, 오류는 없는지 로그를 확인합니다.

    docker logs gemini-discord-bot

    실시간으로 로그를 보려면 -f 옵션을 추가합니다:

    docker logs -f gemini-discord-bot

    (로그 보기를 중지하려면 Ctrl + C)

  3. Discord 확인: Discord 서버에서 봇이 온라인 상태인지 확인하고, 정상적으로 작동하는지 테스트합니다.

💰 비용 고려사항 (프리 티어):

  • EC2: t2.micro 또는 t3.micro 인스턴스는 월 750시간까지 무료입니다. (한 달 내내 1개의 인스턴스를 실행하기에 충분)
  • EBS: 최대 30GB의 범용(SSD) 스토리지가 무료입니다. 기본 설정으로 충분합니다.
  • ECR: 프라이빗 리포지토리는 월 500MB의 스토리지까지 무료입니다. 작은 디스코드-봇 이미지는 보통 이 용량을 넘지 않습니다. (첫 1GB 스토리지는 항상 무료라는 이야기도 있으나, 공식 문서를 확인하는 것이 좋습니다!)
  • 데이터 전송:
    • ECR에서 EC2로 이미지 Pull (같은 리전 내): 무료입니다.
    • 인터넷으로 나가는 데이터 전송: 월 100GB까지 무료입니다. (Discord API, Google API 통신량 포함) 일반적인 봇 운영에는 충분할 가능성이 높습니다.
  • 프리 티어 기간: AWS 가입 후 12개월 동안 적용됩니다. 기간이 만료되면 사용량에 따라 비용이 청구됩니다.
  • 비용 모니터링: AWS Management Console의 Billing & Cost Management 대시보드에서 예상 비용을 주기적으로 확인하고, AWS Budgets를 설정하여 예산 초과 시 알림을 받도록 설정하는 것이 좋습니다.

📌 추가

업데이트 및 유지보수:

  • 봇 코드 업데이트:
    1. 로컬에서 코드 수정 및 git push.
    2. 로컬에서 Docker 이미지 다시 빌드 (docker build ...).
    3. 빌드된 이미지를 ECR에 다시 푸시 (docker push ...).
    4. EC2 인스턴스에 접속하여 기존 컨테이너 중지 및 삭제 (docker stop gemini-discord-bot, docker rm gemini-discord-bot).
    5. 최신 이미지 Pull (docker pull ...).
    6. 새 이미지로 컨테이너 다시 실행 (docker run ...).
  • 서버 유지보수: 주기적으로 EC2 인스턴스에 접속하여 시스템 업데이트(sudo yum update 또는 sudo apt update && sudo apt upgrade)를 수행하는 것이 좋습니다.
profile
how to define. how to solve.

0개의 댓글