디스코드 뮤직 봇 개발 (3)
출석체크 기능을 사용하다 보니 자정인데도 출석했다고 인식하는 것을 보고 직감적으로 한국 표준 시간대가 설정되지 않았다고 생각했다. 이를 적용하고자 코드를 변경하려고 했고, 그 전에 CI/CD 및 임시배포방법인 tmux 대신 systemd 로 바꾸고자 생각했다.
이에 먼저 다시 기존 설정을 확인해봤는데 이상한 점을 하나 찾았다.
가상환경 디렉토리 구조 확인
ls -la meloD_venv/bin/
현재 실행 중인 프로세스에서 python 경로 확인
ps aux | grep python
를 한 결과 2가지 특징을 발견했다.
- 가상환경 구조 : meloD_venv/bin/ 디렉토리가 존재하지만, python3가 시스템의 /usr/bin/python3로 심볼릭 링크되어 있는 특이한 구조였다.
- 현재 실행 프로세스: 프로세스 목록을 보면 python3 main.py로 실행 중이며, 가상환경 경로를 명시적으로 사용하지 않았다.
그래서 다시 제대로 틀을 잡고자 했다.
- 현재 필요한 패키지 목록 저장
pip freeze > requirements.txt
- 기존 가상환경 제거
rm -rf meloD_venv
- 새 가상환경 생성
python3 -m venv meloD_venv --system-site-packages
- 가상환경 활성화
source meloD_venv/bin/activate
- 필요한 패키지 설치
pip install -r requirements.txt
잘 설정해주었다.
다시 본론으로 돌아와서, systemd 서비스 설정을 해보자.
Systemd 서비스 설정
- GCP 인스턴스에 SSH로 접속
-
봇 코드 디렉토리로 이동
cd /path/to/your/discord/MeloD
-
systemd 서비스 파일 생성
sudo nano /etc/systemd/system/meloD.service
- 내용을 입력 (실제 경로와 사용자명으로 수정) ```cmd [Unit] Description=Discord Bot Service After=network.target
[Service] User=YOUR_USERNAME WorkingDirectory=/path/to/your/bot ExecStart=/usr/bin/python3 /path/to/your/bot/main.py Restart=always RestartSec=10 Environment=”PATH=/path/to/your/venv/bin:$PATH”
[Install] WantedBy=multi-user.target
1
2
3
4
5
6
7
8

5. 서비스 활성화 및 시작
```cmd
sudo systemctl daemon-reload # systemd 설정 파일을 새로 읽어들인다. 서비스 파일을 새로 만들거나 수정한 후에 필요한 명령어
sudo systemctl enable meloD # meloD 서비스를 시스템 부팅 시 자동으로 시작되도록 설정
sudo systemctl start meloD # meloD 서비스를 즉시 시작
GitHub Actions CI/CD 설정
- GCP 인스턴스에 SSH 키 설정
1 2 3
# 로컬 컴퓨터에서 실행 ssh-keygen -t rsa -b 4096 -C "github-actions" # (키 저장 위치와 비밀번호 입력)
- 공개 키를 GCP 인스턴스의 authorized_keys에 추가
```
로컬에서 공개 키 확인
cat ~/.ssh/id_rsa.pub
GCP 인스턴스에서 실행
echo “복사한_공개키” » ~/.ssh/authorized_keys
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
3. GitHub 저장소에 비밀 키 추가:
- GitHub 저장소 → Settings → Secrets and variables→ New repository secret
- 이름: `SSH_PRIVATE_KEY`, 값: 비밀 키 내용(~/.ssh/id_rsa 파일의 내용) ; 주석과 줄바꿈까지 그대로 복사
- 이름: `HOST`, 값: GCP 인스턴스 IP
- `curl -s ifconfig.me` 로 확인
- 이름: `USERNAME`, 값: GCP 사용자 이름
- 이름: `TARGET_DIR`, 값: 봇 코드 디렉토리 경로
- ex) /home/nowalex322/MeloD

4. `.github/workflows/deploy.yml` 파일 생성:
GitHub Actions Workflow (deploy.yml)
```yml
name: Deploy to GCP
on:
push:
branches: [ develop ] # 푸시될 브랜치를 지정, 필자는 develop 브랜치에 푸시될 때 실행
jobs:
deploy:
runs-on: ubuntu-latest
steps:
- name: Checkout code
uses: actions/checkout@v2
- name: Setup SSH
uses: webfactory/ssh-agent@v0.5.4
with:
ssh-private-key: $
- name: Add to known hosts
run: |
mkdir -p ~/.ssh
ssh-keyscan -H $ >> ~/.ssh/known_hosts
- name: Deploy to GCP
run: |
rsync -avz --delete ./ $@$:$
- name: Restart meloD Service
run: |
ssh $@$ 'sudo systemctl restart meloD'
워크플로우가 잘 작동중이다!
한국 시간대 수정 적용
- 로컬에서 코드 수정
- pip install pytz 먼저 실행
- Discord 봇 코드에 시간대 관련 수정 적용
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
# 필요한 import 추가
import pytz
# AttendanceCommands 클래스의 check_attendance 메소드 수정
@app_commands.command(name='출첵', description="출석체크")
async def check_attendance(self, interaction: discord.Interaction):
user_id = str(interaction.user.id)
# 한국 시간대 적용
korea_tz = pytz.timezone('Asia/Seoul')
today = datetime.now(korea_tz).strftime('%Y-%m-%d')
conn = sqlite3.connect('attendance.db')
c = conn.cursor()
# 오늘 출석했는지 확인
c.execute('SELECT * FROM attendance WHERE user_id = ? AND attendance_date = ?', (user_id, today))
if c.fetchone():
await interaction.response.send_message(f'{interaction.user.mention} 이미 오늘은 출석체크를 하셨어요!')
conn.close()
return
# 연속 출석 확인 - 여기도 수정
yesterday = (datetime.now(korea_tz) - timedelta(days=1)).strftime('%Y-%m-%d')
c.execute('SELECT streak, total_days FROM attendance WHERE user_id = ? ORDER BY attendance_date DESC LIMIT 1', (user_id,))
result = c.fetchone()
# 나머지 코드는 동일...
-
수정한 코드를 GitHub에 push
-
GitHub Actions가 자동으로 코드를 GCP에 배포하고 서비스를 재시작