구글 클라우드(GCP) VM 인스턴스 생성 사전 준비 과정부터 게임 서버 빌드, 디스코드 관리 봇 연동, 실시간 현황판, 1:1 DM 기반 대화형 설정 관리 및 Rclone 기반 구글 드라이브 원격 백업 시스템 운영까지의 전 과정을 정리한 문서입니다.
(AI 에이전트를 위한 개발 제약 및 컨벤션은 루트 경로의 AGENTS.md 파일을 참조하십시오.)
- 1. 시스템 구성 및 주요 개선 기능 요약
- 2. 전체 시스템 구조 및 통신 흐름
- 3. 보안 및 안전성 설계 (Security & Safety)
- 4. 면책 조항 및 책임의 한계 (Disclaimer)
- 5. 디렉토리 구조 및 구성 파일 상세
- 6. 환경 변수 이중화 가이드 (env vs .env)
- 7. 사전 준비 및 클라우드 세팅 가이드
- 8. 단계별 구축 가이드
- 9. 실시간 현황판 대시보드 및 지능형 엔진 상세 메커니즘
- 10. 알림, 로그 및 정기 채널 정돈 시스템
- 11. 1:1 DM 기반 대화형 .env 설정 관리 및 롤백 시스템
- 12. 실시간 운영 및 모니터링 명령어 가이드
- 13. 디스코드 슬래시 명령어 가이드
-
RCON Save 데이터 플러시 유예 대기 및 데이터 정합성 보장
- 백업, 재시작, 컨테이너 정지/업데이트 시 RCON
Save커맨드를 전송한 후 즉시 프로세스를 멈추지 않고 3초~10초간의 디스크 플러시 유예 대기 시간(asyncio.sleep)을 보장합니다. - 디스크 I/O 속도 차이로 인해 임시 메모리 세션 잔여 데이터가 유실되거나 세이브 파일이 깨지는 현상을 원천 차단합니다.
- 백업, 재시작, 컨테이너 정지/업데이트 시 RCON
-
비동기 락(asyncio.Lock) 기반 현황판 중복 생성 및 경합 상태(Race Condition) 방지
- 짧은 주기에 다중 이벤트(유저 입퇴장, 시스템 주기 루틴, 수동 버튼 클릭)가 동시 실행될 때 현황판이 중복 생성되는 현상을 막기 위해
self.dashboard_lock = asyncio.Lock()비동기 락을 적용했습니다. - 현황판 정보 수집 및 갱신 작업을 오직 단일 순차(Thread-safe)로만 수행하여 대시보드 임베드의 엉킴을 완벽히 예방합니다.
- 짧은 주기에 다중 이벤트(유저 입퇴장, 시스템 주기 루틴, 수동 버튼 클릭)가 동시 실행될 때 현황판이 중복 생성되는 현상을 막기 위해
-
실시간 물리 메모리 모니터링 및 자동 재부팅 (Memory Leak Protection)
psutil라이브러리를 통해 가상 서버의 RAM 사용률을 실시간 추적하며, 임계치(MEMORY_RESTART_THRESHOLD, 기본 80%) 초과 시 자동으로 인게임 안내 방송 및 RCON 저장을 수행하고 도커 컨테이너를 재배치(docker-compose up -d --force-recreate)합니다.- 재시작 직후 연속 재부팅 루프에 빠지지 않도록 30분(1800초)의 재시작 쿨다운 타임스탬프 보호 로직이 함께 구동됩니다.
-
고정 메시지(Pinned Message) 보호 기반 채널 수동/정기 정돈
/clean명령어 실행 시 및 4시간마다 자동 구동되는 정기 채널 정돈 태스크(scheduled_4hr_clean_task) 수행 시 디스코드channel.pins()목록을 파싱합니다.- 관리자가 채널 상단에 고정해둔 가이드 메시지 및 활성화된 대시보드 메시지를 지능적으로 감지하여 삭제 대상에서 제외(Filter)함으로써 중요 공지를 안전하게 보호합니다.
-
스팀 지정 시간 업데이트 체크 및 유저 퇴장 연동 시퀀스
- 매일 지정된 시간(
02:00,04:00,09:00,17:00)에 스팀 API(AppID: 2394010)를 정밀 조회하여 게임 최신 빌드 업데이트 여부를 판별합니다. - 업데이트 감지 시 접속자가 0명이면 즉시 1분 후 자동 업데이트를 진행하고, 플레이어가 존재할 경우 안내 방송을 송출한 뒤
update_pending_on_players플래그를 수립하여 모든 유저가 퇴장하는 즉시 자동으로 업데이트 시퀀스를 가동합니다.
- 매일 지정된 시간(
-
디스코드 1:1 DM 기반 대화형
.env설정 관리 및 자동 백업/롤백- 관리자가 봇에게 개인 메시지(DM)로
.env,설정메시지를 보내면 현재 가상 서버에 적용된.env파일을 첨부 파일로 즉시 전달받습니다. - 수정된
.env파일을 DM 창에 업로드하면 봇이 이전 설정과의 차이점(Diff)을 파악하여 임베드로 출력하고, RCON 저장 ➔ 데이터 백업 ➔ 컨테이너 재배치를 자동 수행합니다. - 컨테이너 재배치 시 오류가 발생하면 자동으로 백업본(
.env.bak)을 통해 이전 정상 작동 설정으로 즉시 자동 롤백(Rollback)합니다.
- 관리자가 봇에게 개인 메시지(DM)로
-
게임 내장 백업 폴더 압축 제외 및 2차 구글 드라이브 비동기 전송
.tar.gz아카이빙 시 게임 자체 내장 백업 폴더(SaveGames/0/<world_id>/backup)를 압축 대상에서 필터링(exclude_internal_backup)하여 이중 압축으로 인한 용량 낭비 및 파일 증발 예외(Errno 2)를 방지합니다.- 백업 파일 생성 직후 Rclone 비동기 서브프로세스를 호출하여 구글 드라이브(
gdrive:backup)로 사본을 전송합니다.
-
서버 내장 임시 백업 폴더 및 만료 원격 파일 자동 소거
- 설정된 보존 기한(
BACKUP_RETENTION_DAYS)을 초과한 로컬 백업 파일(tar.gz)과 구글 드라이브 원격지의 오래된 백업을rclone delete --min-age명령으로 소거합니다. - 세이브 폴더 내부의 내장 백업 폴더들까지
shutil.rmtree로 추적 소거하여 가상 서버 디스크 용량을 추가로 확보합니다.
- 설정된 보존 기한(
-
Fast-Path 최적화 현황판 갱신 및 자가 치유(Self-Healing) 스캔
- 기존 메시지 ID를 활용한 Direct Edit(1회 API 호출) Fast-Path 방식을 우선 적용하며, 메시지가 유실된 경우 상위 50개 내역을 역탐색하여 대시보드를 자가 복구하고 중복 메시지를 청소합니다.
-
환경 설정 일괄 변경 및 이중 승인 (
/설정변경)- 여러 환경 변수(
.env) 값을 쉼표(,)로 구분하여 한 번에 변경하고, 입력 키 유효성 검증 및 변경 확인 임베드와 승인 버튼을 통해 안전한 이중 절차를 제공합니다.
- 여러 환경 변수(
-
12시간 주기 디스크 잔량 모니터링 및 실시간 디스크 조회 (
/디스크)- 12시간마다 디스크 사용률을 진단하여 80% 초과 시 알림을 송출하며,
/디스크명령을 통해 실시간 전체/사용/잔여 용량을 즉시 확인할 수 있습니다.
- 12시간마다 디스크 사용률을 진단하여 80% 초과 시 알림을 송출하며,
Discord User / Admin (DM & Slash Commands)
│
▼
Discord Bot (main.py)
│
┌───────┼───────┬──────────────┐
│ │ │ │
▼ ▼ ▼ ▼
Backup Docker Monitor Config (DM/Slash)
│ │ │ │
│ │ └─► Steam API └─► .env Read/Write
│ │
▼ ▼
Local Backup Rclone Upload (gdrive:backup)
│ │
▼ ▼
[Saved Path] [Google Drive Remote]
[디스코드 사용자 / 관리자] ──(슬래시 명령어 / DM / UI 버튼)──> [PalworldBot (main.py)]
│
┌──────────────────────────────────────────────────┼─────────────────────────────────────────────────┐
│ (MCRcon TCP 25575) │ (REST API TCP 8212) │ (docker.from_env API / subprocess)
▼ ▼ ▼
[팰월드 서버 컨테이너] [REST API 수집 엔진] [Docker Engine]
│ │
│ (RCON Save 플러시 및 백업) │ (컨테이너 상태 제어)
└───────────────────────────────────────────> [Saved 데이터 폴더] │
│ │
▼ (타르 압축 아카이빙) ▼
[backups/ 디렉토리] <─────────────────────────────────┘
│
▼ (rclone copy 비동기 실행)
[구글 드라이브 원격 백업]
본 시스템은 외부 해킹 공격 및 허가되지 않은 사용자의 서버 오용을 방지하기 위해 다음과 같은 다중 보안 설계가 적용되어 있습니다.
-
1. 폐쇄형 내부망 통신 (Localhost Isolation)
- 봇(
main.py)과 게임 서버 컨테이너는 동일 가상 서버 내에 상주하며, REST API 포트(8212)와 RCON 포트(25575)는 외부 IP가 아닌 로컬 루프백 주소(127.0.0.1)를 통해서만 내부 통신합니다.
- 봇(
-
2. 가상 서버 방화벽 최소화 (Port Protection)
- 게임 플레이를 위해 열어두어야 하는 게임 포트(UDP 8211) 외의 모든 제어 포트는 외부로부터 차단할 수 있습니다.
- 구글 클라우드 방화벽 설정 시 RCON 및 REST API 포트를 외부에 개방하지 않아도 내부 통신망을 통해 봇이 직접 정보를 제어합니다.
-
3. 디스코드 관리자 ID 검증 (Role Verification)
- 주요 제어 명령,
/설정변경, DM을 통한.env파일 송수신 및 적용 기능은env내 지정된ADMIN_IDS숫자 ID와 대조하여 미인증 사용자의 접근을 엄격히 차단합니다.
- 주요 제어 명령,
-
4. 사전 환경 변수 검증 (Fail-Fast Validation)
- 봇 기동 시
validator.py를 호출하여 디스코드 토큰, 채널 ID, 경로 존재 유무, 포트 범위(1~65535), 정수형 수치를 사전 검증하며, 유효하지 않은 항목 발견 시 봇 구동을 즉각 중단하여 오작동을 차단합니다.
- 봇 기동 시
-
5. 안전한 Subprocess 실행 및 쉘 인젝션 방지
- 쉘 주입 취약점을 차단하기 위해
os.system()대신subprocess.run()또는asyncio.create_subprocess_exec()에 리스트 인자 형태(["docker", "exec", ...])를 적용하여 안전하게 구동합니다. - RCON 실행 시 백그라운드 환경 TTY 오류를 방지하기 위해
-it옵션을 배제하고 비동기 프로세스로 처리합니다.
- 쉘 주입 취약점을 차단하기 위해
-
6. 회전식 파일 로깅 및 예외 추적 (RotatingFileHandler & Traceback)
logger.py를 통해palworld_bot.log에 로그를 저장하며, 5MB 달성 시 자동 순환(최대 3개 파일 보존)하여 디스크 오버플로우를 예방합니다.- 모든 예외 발생 시 상세한 에러 로그와 호출 스택(
traceback)을 기록하도록 정비되어 있습니다.
- 제공 목적: 본 프로젝트에서 제공하는 스크립트 및 가이드는 서버 관리 편의를 돕기 위한 참고용 오픈소스 자료입니다.
- 보증의 부재: 본 시스템은 명시적/묵시적 보증 없이 "있는 그대로(As-Is)" 제공됩니다. 개발자는 시스템의 무결성, 안정성 및 특정 목적에 대한 적합성을 보증하지 않습니다.
- 책임의 귀속: 시스템 설치, 운용 중 발생하는 데이터 유실, VM 오작동, GCP 과금 발생 등의 모든 결과에 대한 법적, 재정적, 기술적 책임은 전적으로 서버를 구축하고 운영하는 사용자 본인에게 있습니다.
- 권장 조치: 시스템 변경이나 설정 적용 전 중요 세이브 데이터는 외부 저장소에 별도 수동 백업을 받아두는 것을 강력히 권장합니다.
가상 서버의 프로젝트 디렉토리 내부 구조와 하위 구성 파일들의 물리적 역할 명세입니다.
/home/<사용자_계정명>/palworld/
├── AGENTS.md # AI 에이전트(LLM)용 개발 규칙, 컨벤션 및 모듈 수정 순서 가이드
├── docker-compose.yml # 팰월드 도커 컨테이너 및 TCP 헬스체크 검사 정의 파일
├── env # 디스코드 봇 구동 및 가상 서버 경로 설정용 환경 변수 (점 없음)
├── .env # 팰월드 게임 내부 동작 규칙(경험치, 포획률 등) 설정용 환경 변수 (점 있음)
├── main.py # 봇 진입점, 백그라운드 스케줄러 태스크 및 이벤트/슬래시 커맨드 핸들러
├── setup.sh # 의존성 패키지 설치, 가상환경 구축 및 시스템 서비스 등록 스크립트
├── status.json # 현황판 메시지 ID, 빌드 정보 및 최종 상태값 캐싱 파일 (자동 생성)
├── palworld_bot.log # 봇 실행 로그 파일 (자동 생성, RotatingFileHandler 적용)
├── backups/ # 세이브 압축 파일이 저장되는 백업 폴더 (자동 생성, 구글 드라이브 연동)
├── utils/ # 유틸리티 모듈 집합
│ ├── __init__.py # utils 패키지 초기화 파일
│ ├── logger.py # 5MB 제한, 3개 파일 보존 기준의 RotatingFileHandler 로깅 구성
│ └── validator.py # 봇 기동 전 필수 환경 변수 누락 및 포트 범위(1~65535) 무결성 검증
├── services/ # 비즈니스 로직 서비스 모듈 집합
│ ├── __init__.py # services 패키지 초기화 파일
│ ├── config_service.py # env 및 .env 파일 읽기/쓰기, DM 파일 발송/수신 적용 및 동적 리로드
│ ├── status_service.py # status.json 구조의 로드 및 쓰기 무결성 관리
│ ├── docker_service.py # Docker API 엔진 연동 및 비동기 RCON 명령어 전송 처리
│ ├── backup_service.py # RCON Save 플러시, 세이브 압축 백업, Rclone 업로드 및 내장/원격 정리
│ └── monitor_service.py # 스팀 API 최신 빌드 조회, REST API 수집 및 시스템 리소스 모니터링
└── bot/ # 디스코드 봇 UI/UX 모듈 집합
├── __init__.py # bot 패키지 초기화 파일
├── embeds.py # ONLINE/STARTING/OFFLINE 상태별 대시보드 임베드 디자인
└── views.py # 대시보드 수동 업데이트 버튼 및 설정 변경 confirmation 뷰 정의
본 시스템은 관리 편의성과 보안성을 극대화하기 위해 환경 변수 파일을 완전히 이중화하여 독립적으로 운영합니다.
| 파일 이름 | 점(.) 여부 |
주요 역할 및 대상 코드 | 포함되는 주요 변수 예시 |
|---|---|---|---|
env |
없음 | 디스코드 봇의 시스템 관리 및 물리 구동을 위한 핵심 환경 설정 (봇 구동 서비스 실행 시 직접 로드) | DISCORD_TOKEN, ADMIN_IDS, CHANNEL_ID, LOG_CHANNEL_ID, BASE_PATH, SAVE_DATA_PATH, BACKUP_PATH, MEMORY_RESTART_THRESHOLD |
.env |
있음 | 팰월드 게임 서버 컨테이너 내부 동작 규칙 조정 (도커 컴포즈 빌드 시 컨테이너 내부로 환경 변수 주입) | EXP_RATE, CATCH_RATE, PAL_EGG_DEFAULT_HATCHING_TIME, SERVER_PASSWORD, ADMIN_PASSWORD |
- 💡 주의사항: DM을 통한 설정 관리나
/설정변경명령어는 게임 룰 조정을 목적으로 있음(.env) 파일을 수정하고 동기화합니다. 반면 봇 구동 토큰이나 디스코드 채널 ID 등을 수정할 때는 없음(env) 파일을 직접 수정해야 합니다.
팰월드 서버를 원활히 구동하고 관리하기 위해 가상 서버 생성 이전에 아래의 세팅을 순서대로 진행해야 합니다.
- 구글 클라우드 플랫폼(GCP)에 접속하여 신규 계정을 등록하고 무료 체험 크레딧 또는 티어 조건을 확인합니다.
- Compute Engine > VM 인스턴스 메뉴에서 가상 서버 인스턴스를 하나 생성합니다.
- OS: Ubuntu 22.04 LTS (최신 x86/64 이미지)
- 권장 하드웨어 사양: e2-standard-4 (4 vCPU, 16GB RAM) 이상
게임 클라이언트 접속을 허용하기 위해 인스턴스 네트워크 설정에 다음 규칙을 추가해야 합니다.
- 게임 접속 포트: UDP 8211 (소스로부터의 IP 범위: 0.0.0.0/0 - 전체 개방)
- 주의: 보안을 위해 RCON 포트(TCP 25575) 및 REST API 포트(TCP 8212)는 구글 방화벽 상에서 외부로 노출되지 않도록 폐쇄하고 로컬 내부에서만 통신하도록 설정하십시오.
- Discord Developer Portal(https://discord.com/developers/applications)에 접속하여 New Application을 생성합니다.
- 왼쪽 Bot 탭으로 이동하여 봇 계정을 생성하고 Token을 안전한 곳에 복사해 둡니다. (
DISCORD_TOKEN) - 같은 Bot 탭 화면 하단의 Privileged Gateway Intents 섹션에서 다음 세 가지 필수 권한을 활성화합니다.
- Presence Intent
- Server Members Intent
- Message Content Intent
- 왼쪽 OAuth2 > URL Generator 탭으로 이동합니다.
- Scopes: bot, applications.commands 체크
- Bot Permissions: Administrator (또는 채널 읽기/쓰기, 역할 제어 권한 필수 체크)
- 하단에 자동 생성된 URL 주소를 복사하여 브라우저에 접속한 뒤 본인이 관리하는 디스코드 서버에 봇을 초대합니다.
- MobaXterm 상단 메뉴에서 Tools > MobaKeyGen (SSH Key Generator)을 실행합니다.
- 하단의 Parameters 항목에서 RSA를 선택하고 Generate 버튼을 클릭합니다.
- 진행 표시줄이 차오르는 동안 마우스를 무작위로 계속 움직여 임의의 난수를 생성합니다.
- 키 생성이 완료되면 화면 중간의 Key comment 부분을 원하는
<사용자_계정명>으로 변경합니다. (예: gcp-user 등 영어 소문자 권장) - Save private key 버튼을 클릭하여 안전한 로컬 폴더에 비공개 키 파일(.ppk)을 저장합니다.
- 맨 위 회색 텍스트 상자(Public key for pasting into OpenSSH...) 안에 있는 긴 문자열 전체를 복사합니다.
- GCP 콘솔의 Compute Engine > VM 인스턴스 상세 페이지에서 상단의 수정 버튼을 클릭합니다.
- 화면을 아래로 내려 SSH 키 항목을 찾은 후 항목 추가를 누릅니다.
- 위에서 복사한 공개 키 전체를 입력란에 그대로 붙여넣습니다. (정상 등록 시 끝에 입력한 계정명이 감지됩니다.)
- 맨 아래로 내려 저장을 누릅니다.
- MobaXterm 왼쪽 위 Session 버튼을 누르고 SSH 세션을 추가합니다.
- Remote host: GCP에서 할당된 가상 서버의 외부 IP 주소를 입력합니다.
- Specify username: 키 생성 시 Key comment에 입력했던
<사용자_계정명>을 그대로 입력합니다. - Advanced SSH settings 탭을 클릭한 뒤 Use private key 항목을 체크하고 저장해 두었던 비공개 키 파일(.ppk)을 등록합니다.
- OK를 누르면 가상 서버에 암호 입력 없이 안전하게 최초 접속됩니다.
가상 서버 백업 데이터를 구글 드라이브 원격 저장소에 업로드하기 위한 사전 작업입니다.
-
Rclone 설치 프로그램 실행:
sudo -v && curl https://rclone.org/install.sh | sudo bash
-
설정 생성 마법사 진입:
rclone config
-
아래 입력 단계에 맞게 매핑을 진행합니다:
- New Remote 선택을 위해
n입력 후 엔터 - 저장소 식별 이름 입력:
gdrive입력 후 엔터 (대소문자 일치 필수) - 스토리지 유형 선택:
drive또는 목록에 안내되는 구글 드라이브 고유 번호 입력 후 엔터 - client_id 및 client_secret: 공백으로 엔터 (기본값 사용)
- 권한 범위(scope):
1입력 후 엔터 (전체 접근 권한 부여) - root_folder_id 및 service_account_file: 공백으로 엔터
- Edit advanced config?:
n입력 후 엔터 - Use auto-config?:
n입력 후 엔터 (가상 서버 환경이므로 필수n)
- New Remote 선택을 위해
-
개인 PC에서의 연동 인증 완료 절차:
- 인스턴스 화면에 표시되는
rclone authorize "drive"구문을 확인합니다. - 본인의 개인 로컬 PC(Windows 또는 Mac) 터미널 창을 열고
rclone authorize "drive"명령어를 똑같이 입력하여 가동합니다. - 연동을 원하는 구글 계정 브라우저 승인 창이 열리면 허용을 마칩니다.
- 로컬 PC 터미널 상에 출력되는 긴 JSON 토큰 코드(
{"access_token": ...})를 처음부터 끝까지 정밀하게 복사합니다. - 다시 구글 가상 서버 SSH 터미널로 돌아와 복사한 코드 문자열 전체를
result>창에 붙여넣고 엔터를 클릭합니다. - Shared Drive 구성 여부:
n입력 후 엔터 - 정상 입력 결과 확인 후
y입력으로 최종 마무리하고q를 눌러 마법사를 종료합니다.
- 인스턴스 화면에 표시되는
-
테스트로 연동 확인:
rclone lsd gdrive:
GCP 터미널(사용자@호스트명:~$)에 접속하자마자 실행합니다. 파일 업로드 및 도커 구동 과정에서 권한 충돌이 일어나지 않도록 폴더 소유권을 사전에 지정하는 과정입니다.
mkdir -p ~/palworld
sudo chown -R $USER:$USER ~/palworld
chmod 755 ~/palworld
cd ~/palworld
MobaXterm 왼쪽 파일 탐색 패널을 새로고침하여 생성된 /home/<사용자_계정명>/palworld 폴더로 진입한 후 준비된 파일들과 폴더들을 업로드합니다.
env 파일은 디스코드 봇 및 경로 매핑을 위한 파일입니다. 아래 포맷 예시에 맞추어 정보를 입력하여 업로드하십시오.
# --- 디스코드 설정 ---
DISCORD_TOKEN=발급받은_디스코드_봇_토큰
ADMIN_IDS=관리자_디스코드_숫자_ID (여러 명일 시 콤마 구분 예: 1234,5678)
CHANNEL_ID=현황판_출력용_디스코드_채널_숫자_ID
LOG_CHANNEL_ID=백업 및 시스템_로그_수신용_채널_숫자_ID
# --- 서버 정보 ---
SERVER_NAME=Palworld Korea
SERVER_IP=자신의_GCP_외부_IP_주소
SERVER_PORT=8211
# --- 게임 내부 설정 ---
ADMIN_PASSWORD=원하는_RCON_비밀번호
RCON_PORT=25575
REST_API_PORT=8212
# --- 경로 설정 (<사용자_계정명> 자리에는 본인의 실제 계정명을 입력하십시오) ---
BASE_PATH=/home/<사용자_계정명>/palworld
SAVE_DATA_PATH=/home/<사용자_계정명>/palworld/palworld/Pal/Saved
BACKUP_PATH=/home/<사용자_계정명>/palworld/backups
# --- 운영 정책 ---
BACKUP_RETENTION_DAYS=2 # 백업 파일 보존 기간 (일 단위)
MEMORY_RESTART_THRESHOLD=80 # RAM 사용량 n% 초과 시 자동 재시작
RESTART_TIME=04:00 # 매일 서버 자동 재시작 시간 (HH:MM)
도커 컨테이너가 단순히 작동 중인 것과 실제 게임 서버 내부 프로세스가 정상적으로 통신을 받아들일 수 있는 상태인 것은 다릅니다. 이를 정밀하게 검증하기 위해 RCON 포트 감지 기반의 헬스체크 설정을 포함하여 구성합니다.
version: '3.8'
services:
palworld:
image: thijsvanloef/palworld-server-docker:latest
container_name: palworld-server
stop_grace_period: 30s
ports:
- 8211:8211/udp
- 27015:27015/udp
- 25575:25575/tcp
- 8212:8212/tcp
environment:
- TZ=Asia/Seoul
- PUID=1000
- PGID=1000
env_file:
- .env
volumes:
- ./palworld:/palworld/
healthcheck:
test: ["CMD-SHELL", "timeout 5s bash -c 'cat < /dev/null > /dev/tcp/127.0.0.1/25575' || exit 1"]
interval: 10s
timeout: 5s
retries: 3
start_period: 60s
- test (진단 명령): 컨테이너 내부의 로컬 루프백 주소(
127.0.0.1)와 RCON 제어 포트(25575) 간의 TCP 연결이 유효한지 검사합니다. Bash 내장/dev/tcp채널을 통해 빈 데이터(cat < /dev/null)를 전송하여 리소스 소모를 최소화합니다. - interval: 컨테이너 구동 이후 매 10초 간격으로 진단 명령을 반복 수행합니다.
- timeout: 진단 명령 지시 후 5초 이내에 정상적인 TCP 응답이 도달하지 않으면 실패 처리됩니다.
- retries: 연속 3회 이상 검증 실패 시 도커 엔진은 컨테이너의 건강 상태를
unhealthy로 최종 격하합니다. - start_period: 컨테이너 기동 직후 첫 60초 동안은 상태 검사가 실패하더라도 누적 실패 횟수에서 배제하여 초기 로딩 중 재시작 루프에 빠지는 현상을 방지합니다.
업로드가 완료되었다면 터미널 창에서 윈도우 스타일 줄바꿈 문자(CRLF) 정화 작업을 거친 뒤 설치 스크립트를 구동합니다.
sed -i 's/\r$//' setup.sh env .env
chmod +x setup.sh
./setup.sh
설치 스크립트가 완전히 끝나면 상시 가동 중인 디스코드 봇이 sudo 없이도 도커 백업 명령어(docker exec)를 안전하게 지시할 수 있도록 권한을 보완합니다.
sudo usermod -aG docker $USER
newgrp docker
sudo systemctl restart palbot.service
[OFFLINE] (도커 컨테이너 정지 상태)
│
▼ (컨테이너 기동 / docker-compose up)
[STARTING] (도커 running / 헬스체크 starting)
│
▼ (REST API /v1/api/info 성공)
[ONLINE] (현황판 녹색 갱신 및 정상 구동)
│
├─► [0명 유지 15분 경과 / 동적 백업] ───────────► [BACKUP & GDRIVE COPY]
├─► [메모리 임계치 초과 (80%) / 쿨다운 30분] ────► [AUTO REBOOT]
└─► [스팀 API 빌드 불일치 감지] ───────────────► [UPDATING PENDING]
- 이중 단계 상태 검증: 도커 엔진 상태가
starting이면 대시보드를STARTING으로 매핑하고 접속자 텍스트를 "로딩 중..."으로 표기합니다. REST API 정상 응답 시ONLINE으로 전환됩니다. - 비동기 락(asyncio.Lock) 보호:
refresh_dashboard호출 시dashboard_lock을 획득하여 동시 갱신 명령이 겹치더라도 대시보드 메시지가 중복 발행되는 현상을 차단합니다. - Fast-Path 및 자가 치유(Self-Healing):
status.json에 저장된msg_id로get_partial_message를 수행해 1회 API 호출로 즉시 수정합니다. 메시지가 유실된 경우 최근 50개 내역을 스캔하여 복구하며 중복 대시보드는 삭제 처리합니다. - 실시간 메모리 모니터링 및 30분 쿨다운:
psutil.virtual_memory()로 점유율을 계산하며 80% 초과 시 RCON 저장을 거쳐 컨테이너를 재배치합니다.last_restart_time타임스탬프를 대조하여 재시작 후 30분(1800초)간은 추가 자동 재부팅을 유예합니다. - 지정 시간 스팀 업데이트 대조 스케줄러: 매일
02:00,04:00,09:00,17:00에 스팀 API를 조회하며 최신 빌드 변경 시 접속자가 0명이면 즉시 업데이트를 실행하고, 유저가 존재하면 퇴장 대기(update_pending_on_players) 모드로 전환합니다.
[가상 서버 물리 RAM 80% 점유율 초과 감지]
│
▼
[인게임 RCON 경고 방송] ("Server is stopping for maintenance" 공지)
│
▼
[세이브 플러시 (Force Flush)] (RCON Save 커맨드 실행 및 유예 대기)
│
▼
[컨테이너 강제 완전 중지 및 재배치] (docker-compose up -d --force-recreate)
│
▼
[REST API 헬스 폴링 실행] (API 정상 응답 감지 시까지 STARTING 상태 고정)
│
▼
[ONLINE 전환 및 30분 쿨다운 설정] (현황판 갱신 및 디스코드 로그 전송 완료)
- 대시보드 채널 (
CHANNEL_ID): 현황판 대시보드 임베드와 업데이트 수동 실행 버튼만 고정 가동됩니다. 이 채널에 발행되는 제어 공지 등 임시 메시지는 15분(900초) 후 자동 자폭 삭제 처리됩니다. - 백업/로그 전용 채널 (
LOG_CHANNEL_ID): 세이브 백업 결과, 구글 드라이브 업로드 보고, 만료 백업 정리, 디스크 용량 경고 등의 기록이 영구 보관됩니다.
- ① 정기 점검/업데이트 루틴: 점검 5분 전, 1분 전, 30초 전 RCON 방송 및 공지 송출 ➔ RCON
Save전송 후 3~10초 플러시 대기 ➔ 컨테이너 정지 ➔ 로컬 및 구글 드라이브 백업 ➔docker-compose pull및up -d --force-recreate실행. - ② 세이브 백업 및 구글 드라이브 복사 보고: 로컬
.tar.gz생성 완료 후 Rclone 업로드 결과를 하나의 통합 메시지로 발송. - ③ 서버 디스크 스페이스 초과 조기 경보: 12시간 주기로 디스크 사용률 진단 ➔ 80% 초과 시 적색 경고 임베드 송출.
- ④ 설정값 수동 일괄 변경 이중 검증 (
/설정변경): 입력 키 유효성 검증 ➔ 승인 버튼 패널 송출 ➔ 승인 시 세이브 저장, 백업, 재기동 실행. - ⑤ 4시간 정기 채널 정돈 태스크 (
scheduled_4hr_clean_task): 4시간마다channel.pins()파싱 ➔ 고정 메시지 및 활성화된 대시보드를 제외한 임시 메시지 일괄 청소.
디스코드 봇과의 1:1 개인 메시지(DM)를 사용하여 가상 서버의 게임 설정(.env)을 안전하게 조회하고 직접 교체 및 반영할 수 있습니다.
[관리자 DM] ───(".env" / "설정" 메시지 전송)───► [PalworldBot]
│
[관리자 DM] ◄───(현재 적용 중인 .env 파일 발송)─────┘
│
▼ (수정된 .env 파일을 DM 창에 드래그 앤 드롭 업로드)
[PalworldBot]
│
├─► 1. 기존 .env를 .env.bak으로 임시 백업 보관
├─► 2. 이전 설정과 신규 설정 변경점(Diff) 정밀 대조 및 임베드 출력
├─► 3. RCON "Broadcast" 및 "Save" 명령 전송 (플러시 유예 대기)
├─► 4. 안전 백업(run_backup) 실행 및 구글 드라이브 전송
├─► 5. docker-compose up -d --force-recreate 무중단 재배치
└─► 6. 재배치 에러 발생 시 .env.bak 파일로 자동 롤백 (Rollback)
디스코드 봇은 가상 서버가 켜질 때 자동 실행되는 systemd 서비스로 등록되어 있습니다.
-
봇 상태 확인:
sudo systemctl status palbot.service
-
봇 재시작:
sudo systemctl restart palbot.service
백업 진행 상황, Rclone 연동 상태, 접속자 변경 감지, 메모리/디스크 경고 로그를 모니터링할 수 있습니다.
-
실시간 로그 지켜보기 (종료:
Ctrl + C):tail -f /home/<사용자_계정명>/palworld/palworld_bot.log
-
실행 중인 컨테이너 목록 확인:
docker ps
-
게임 서버 강제 정지:
cd ~/palworld && docker-compose down
-
게임 서버 재생성 재기동:
cd ~/palworld && docker-compose up -d --force-recreate
봇을 서버에 초대할 때 bot과 applications.commands 권한을 체크했다면 디스코드 채널에서 슬래시(/)를 입력해 관리 명령어를 호출할 수 있습니다. (ADMIN_IDS에 등록된 관리자 전용)
- /start: 정지된 팰월드 서버를 시작합니다.
- /stop: 인게임 안내 방송 송출 후 저장을 거쳐 서버를 안전하게 정지합니다. (약 10초 소요)
- /restart: 인게임 방송 ➔ 저장을 거쳐 안전 백업을 수행한 후 도커 컨테이너를 재배치하여 재시작합니다.
- /backup: 팰월드 세이브 데이터를 즉시 저장을 거쳐 타르 압축한 후 로컬 백업 폴더 및 구글 드라이브로 동시 수동 백업합니다.
- /clean: 채널 상단 고정(Pinned) 메시지 및 대시보드를 제외한 임시 메시지들을 삭제 정리합니다.
- /디스크: 현재 서버의 전체 디스크 용량, 사용 중인 용량, 사용률(%)을 실시간 임베드로 조회합니다.
- /설정변경 :
- 사용 예:
/설정변경 query:EXP_RATE=2.0, CATCH_RATE=1.5 .env설정값을 변경하고 변경 내역 확인 임베드 및 승인 버튼을 통해 안전하게 반영 후 서버를 재시작합니다.
- 사용 예:
버그 신고 및 기능 개선 제안은 GitHub Issue를 이용해 주세요.
설치 또는 운용 중 문제가 발생할 경우 palworld_bot.log 파일의 예외 로그 내역을 함께 첨부해 주시면 신속한 분석이 가능합니다.