Post

디스코드 뮤직 봇 개발 (2)

디스코드 뮤직 봇 개발 (2)

이번엔 디스코드 봇을 24/7 가동하기위한 무료 호스팅 서버를 구축하고자 한다. 여러가지 후보군 중 GCP를 선택했다. 일단 평생 무료 + 300$ 크레딧이 가장 압도적인 이유고 쓰기 편하기도 하기 때문에 선정했다.

참고로 300$ 크레딧은 3달 지속된다. 그 뒤엔 무료플랜 사용으로 적용된다.

좀 더 자세한 사용 요건을 보고싶다면 Google Cloud Free cloud features and trial offer 에서 무료플랜 조건을 보자.

먼저 구글 클라우드 플랫폼 에 접속해 사용할 구글 계정으로 로그인하고 결제수단까지 등록한다. 이것도 안하고 300$로만 낼름하려고 한 심보에 반성했다.

무료 인스턴스 생성

사용을 눌러준다.

인스턴스 만들기로 들어가자.

인스턴스 구성하기

이제 인스턴스 정보를 입력해줄건데 프리티어 조건 을 여기서 봤기때문에 똑같이 넣어줄것이다.

  • 리전 : us-west1 (오리건)
  • 영역 : a, b, c 중 아무거나
  • E2
  • 머신유형 : e2-micro

을 선택해주자.

다음으로 부팅디스크다.

필수조건은

  • 표준 영구 디스크
  • 30GB

로 설정해주고 OS는 사용하고자 하는 것으로 선택하자. 우분투 최신버전 중 범용적인 22.04 LTS 선택했다.

모든 설정이 끝났고 만들어주면 된다.

*PS ARM64랑 x86/64는 무슨차이?

이건 CPU 아키텍쳐 종류다.

  • x86/64 (=x64, AMD64)
    • 전통적인 데스크톱/랩톱 CPU 아키텍처
    • Intel, AMD의 일반적인 프로세서
    • 소프트웨어 호환성이 매우 높음
    • 대부분의 서버용 소프트웨어가 기본적으로 지원
  • ARM64
    • 모바일 기기에서 시작된 아키텍처
    • 전력 효율이 좋음
    • Apple M1/M2, 서버용 AWS Graviton 등
    • 일부 소프트웨어는 호환성 확인 필요

디스코드 봇을 python으로 개발한 상황에서 x86/64가 더 안전하다고 판단했다. 이유로는

  • Python 패키지들이 x86/64에서 더 광범위하게 테스트되고 지원된다.
  • 일부 Python 패키지들은 ARM64용 미리 컴파일된 바이너리를 제공하지 않을 수 있다.
  • 특히 C 확장을 사용하는 패키지들(numpy, pandas 등)의 경우 x86/64에서 설치가 더 수월하다.

사실 별 차이는 없다. discord.py같은 기본적인 것만 사용하면 별로 상관없지만 향후 확장성 고려하면 x86/64가 안전한 선택이다.

생성 후 대시보드

결제요금부터 눈에 띄도록 위치 커스텀해줬다.

이제 VM 인스턴스를 다시 들어가서 SSH를 눌러보면 브라우저 콘솔로 터미널을 접속해 편하게 SSH 접속을 할 수 있다.

배포

일단 작성할 명령어를 설명하면서 진행해보겠다

  • sudo apt update
  • sudo apt install python3-pip python3-venv git tmux -y

는 우분투 패키지 관리자다. 우리가 쓸 파이썬 패키지관리자 pip, 파이썬 가상환경 생성도구 venv, 레포 관리할 git, 터미널 세션관리하는 tmux (24/7 돌리기) 를 사용하기에 install로 설치해줬으며 -y는 모두 y로 자동응답하는 키워드다.

그 다음에 혹시 이런 화면이 뜰수도 있는데, 우분투 패키지 구성 화면이라 일부 서비스 재시작할 수 있다는것이라 기본값대로 ok선택하고 Enter 눌러주면된다.

파일을 불러오기 위해 git을 사용해 클론해준다.

  • git clone https://github.com/Kguswo/MeloD.git

필자처럼 디폴트 브랜치가 아닌 특정 개발 브랜치에 있다면 checkout을 해주자.

cd로 이동해준다.

  • cd MeloD

이제 가상환경을 설정해줄것이다. 활성화해준다.

  • python3 -m venv meloD_venv
  • source meloD_venv/bin/activate

그리고 우리가 로컬에서 개발했던 환경과 같에 만들어주고 실행해야하니까 이후 필요한 라이브러리도 받아준다. 이는 requirements.txt에 정리되어있으므로

  • pip install -r requirements.txt 로 다운받아준다.

디스코드 토큰을 넣기 위해 환경변수 파일 .env가 필요하다. 다음을 통해 생성 후 작성하자.

  • nano .env : 파일생성
  • DISCORD_TOKEN= 디스코드 봇 토큰으로 넣기

이후 cat .env로 체크해보자!

어느정도 준비는 끝났다. 이제 tmux로 파일을 실행할건데 새로운 세션을 만들어준다. tmux new -s meloD 그리고 여기서 파일을 실행한다. python3 main.py

이제 이 세션에서 계속 파일이 실행되고있기에 터미널을 닫아도 괜찮다!

다음에 터미널에 접속해 다시 이 세션에 접속하고 싶을땐 attach로 접속가능하다. 명령어는 tmux attach -t meloD 다음과 같다.

계속 이 세션이 살아있는지 보고자 tmux list-sessions 로 확인해보니 계속 동작중임을 확인했다!

SSH키를 생성하고 컴퓨터에 저장한 뒤 터미널로도 접속하고자 한다면

1. 명령어로 로컬에서 새로운 SSH키를 생성한다.

  • ssh-keygen -t rsa -b 4096 -C "이메일 주소" -f ~/.ssh/키 이름 ex) ssh-keygen -t rsa -b 4096 -C “nowalex322@gmail.com” -f ~/.ssh/meloD_gcp_key

    명령어 키워드 간단하게 보면

    • t rsa: RSA 알고리즘 사용
    • b 4096: 4096비트 키 길이
    • C "이메일 주소": 키에 대한 설명 (일반적으로 이메일)
    • f ~/.ssh/키 이름: 키 파일 경로 및 이름 (예: gcp_key)

    이 명령어를 실행하면 다음과 같은 파일이 생성된다

    • ~/.ssh/gcp_key: 개인키 (Private Key)
    • ~/.ssh/gcp_key.pub: 공개키 (Public Key)

      2. 공개키를 GCP에 등록

2.1. GCP 콘솔을 통해 등록

  1. GCP 콘솔에 로그인.
  2. Compute Engine > 메타데이터 > SSH 키 로 이동.
  3. ~/.ssh/gcp_key.pub 파일의 내용을 복사하여 붙여넣기.
    • 파일 내용 확인 방법: cat ~/.ssh/키이름.pub

    • 출력 예시: ssh-rsa AAAAB3NzaC1yc2E... 이메일주소

  4. 저장 클릭.

이후 접속 테스트해보면

  • ssh -i ~/.ssh/meloD_gcp_key nowalex322@melod-instance-20250223-152133 잘 접속된다!

트러블 슈팅

트러블슈팅은 기능 개발과 관련된 문제 해결 과정이기에 위 내용과 무관한 기능개발 내용입니다.

일단 출석체크 기능때문에 생긴 문제 해결 과정이다. 소규모 서버고 메인 기능이 아니기에 간단하게 SQLite로 가볍게 DB를 관리하고자 했기에 출석 관련 내용이 바이너리 코드로 attendance.db에 담겨있었다.

배포 후 새로 db가 생성되면서 당연하게도 출석이 1일차부터 시작하게되었다. FileZilla를 예전에 사용해본적이 있어 옮기고자 했지만 내 눈에 다른것이 눈에 띄었다.

GCP 브라우저 터미널 내부에서 자체적으로 지원하는 파일 업로드 및 다운로드였다. 너무 간편하다고 생각되어 바로 실행해줬지만 문제가 발생했다.

무조건 프로젝트 루트 디렉토리에 파일이 들어간다는 점이다. 여기서 파일을 이동시켜 덮여씌워주면서 해결했지만 다른 여러 방법들도 시도했다.

먼저 scp명령어다. scp attendance.db nowalex322@melod-instance-20250223-152133:~/MeloD/attendance.db

이런식으로 내로컬에 있는 attendance.db 파일을 서버의 attendance.db 파일로 교체하고자 scp (Secure Copy) 명령어를 사용하려고했다. 그런데 계속 can’t be established., Permission denied등 SSH보안관련 오류가 생겼다.

그래서 SSH키를 재설정해 GCP에 등록도 하고 여러번 시도를 했지만 복사가 되지 않았다.

그래서 그냥 파일 업로드 버튼을 눌러 내 로컬에 있는 attendance.db파일을 업로드했다. 루트 디렉토리에 복사되었고 이를 mv 명령어로 기존 파일이 있던 위치로 옮겨주었다. 이때 이름이 같은 파일이기 때문에 내용을 덮어쓴다.

그리고 이제 내가 원하는 데이터 파일이 있는지 확인해야한다.

SQLite 데이터베이스 파일(.db)을 조회하기 위해 Python으로 간단한 스크립트를 작성했다. 데이터베이스의 테이블 목록, 테이블 구조(컬럼명과 데이터 타입), 그리고 데이터 샘플을 조회할 수 있다. 코드는 크게 두 파일로 구성되어 있다.

  1. 헬퍼 함수 (sqlite_helper.py)
    • connect : SQLite 데이터베이스에 연결

    • execute_query : SQL 쿼리를 실행하고 결과를 딕셔너리 형태로 반환

    • get_table_info : 특정 테이블의 구조(컬럼명, 데이터 타입 등)를 조회

  2. 메인 스크립트 (check_db.py)
    • 테이블 목록 조회: sqlite_master 테이블에서 모든 테이블 이름을 가져오기

    • 테이블 구조 조회: PRAGMA table_info를 사용하여 테이블의 컬럼명과 데이터 타입을 확인

    • 데이터 샘플 조회: 각 테이블의 상위 5개 행을 조회하여 출력

결과

파일이 제대로 들어갔고 정상적으로 반영되었다. 아직 출첵 관련 기능 수정할 사항도 많고 개발해야할 기능들도 많아 갈 길이 멀다.

This post is licensed under CC BY 4.0 by the author.