Docker로 호스팅하기
이 가이드는 Docker를 사용하는 고급 서버 구성을 다룹니다. Linux 환경, 명령줄 인터페이스, Docker 생태계(이미지, 컨테이너, 볼륨, 네트워킹, docker-compose에 대한 탄탄한 이해 포함)에 익숙한 분만을 대상으로 합니다.
- Linux 터미널에서 자유롭게 작업할 수 있어야 합니다.
- Docker 개념, 즉 이미지가 어떻게 빌드되고 실행되는지, 컨테이너를 어떻게 관리하는지, docker-compose가 멀티 컨테이너 애플리케이션을 어떻게 오케스트레이션하는지 잘 알고 있어야 합니다.
이 구성을 진행한다는 것은 필요한 기술 지식을 갖추고 있다는 뜻입니다. 구성이 복잡하고 사용자마다 환경이 크게 다르기 때문에, 이 Docker 구성에 대한 직접 지원은 본질적으로 매우 제한적입니다. 문제가 생겼을 때의 책임은 전적으로 사용자에게 있습니다.
Spellbreak 서버를 확장 가능하고 관리하기 쉬운 방식으로 만들고 운영하고자 한다면 Docker가 든든한 선택지입니다. 이 방법에서는 docker-compose 를 사용해 멀티 컨테이너 Spellbreak 서버 애플리케이션을 정의하고 실행합니다.
사전 준비
- Docker 설치: Linux 서버에 Docker Engine과 Docker Compose가 설치되어 있어야 합니다. 아직 설치하지 않았다면 공식 Docker 문서에서 사용 중인 Linux 배포판에 맞는 안내를 참고하세요.
- 디렉터리 준비:
docker-compose.yml파일과 관련 설정 또는 데이터 영속화 매핑을 보관할 전용 디렉터리를 서버에 만드세요.
구성 활용하기:
아래 제공되는 구성은 방금 만든 디렉터리 안에 docker-compose.yml이라는 이름의 파일로 저장해야 합니다. 서비스를 실행하기 전에 반드시 docker-compose.yml 파일을 편집해, 예시로 들어 있는 비밀번호(YOUR_MYSQL_PASSWORD, YOUR_DB_ROOT_PASSWORD 등)를 모두 본인만의 강력하고 고유한 비밀번호로 바꿔야 합니다. 그러지 않으면 동작하지도 않고 안전하지도 않은 구성이 됩니다.
게임 서버 추가 및 설정
여러 게임 서버를 운영하거나 기존 서버를 수정하려면 docker-compose.yml 파일의 두 부분, 즉 elixir_service 설정과 각 게임 서버 서비스 정의를 편집해야 합니다.
elixir_service(매치메이커) 설정하기
elixir_service는 운영하려는 모든 게임 서버를 알고 있어야 합니다. environment 섹션을 다음과 같이 갱신하세요.
- GAME_SERVER_NAMES: 서버를 알아보기 쉬운 이름으로 쉼표로 구분해 나열합니다(예:
Solos-Alpha,Duos-Beta). - GAME_SERVER_HOSTS: 게임 서버의 호스트 이름을 쉼표로 구분해 나열합니다.
docker-compose.yml에서 각 게임 서버 서비스에 정의한 hostname(보통 서비스 이름과 동일)과 정확히 일치해야 합니다(예:solo1,solo2,duo1). - GAME_SERVER_PORTS: 각 게임 서버가 수신 대기하는 게임 포트를 쉼표로 구분해 나열합니다(예:
7777,7778,7779). 해당 게임 서버의GAMEPORT환경 변수와 일치해야 합니다. - GAME_MANAGER_PORTS: 각 게임 서버의 게임 매니저 포트를 쉼표로 구분해 나열합니다. 해당 게임 서버의
ELIXIRPORT환경 변수와 일치해야 합니다(예:3387,3388,3389). 중요:GAME_SERVER_NAMES,GAME_SERVER_HOSTS,GAME_SERVER_PORTS,GAME_MANAGER_PORTS의 항목 순서는 서로 대응해야 합니다. 예를 들어 첫 번째 이름, 첫 번째 호스트, 첫 번째 포트, 첫 번째 매니저 포트는 모두 같은 게임 서버 인스턴스를 가리킵니다.
바꿔야 할 부분의 예시는 다음과 같습니다.
# Inside elixir_service:
# environment:
# # ... other environment variables ...
# GAME_SERVER_NAMES: Solos-US-East,Solos-US-West
# GAME_SERVER_HOSTS: solo_use,solo_usw
# GAME_SERVER_PORTS: 7777,7778
# GAME_MANAGER_PORTS: 3387,3388
# # ... other environment variables ...
# ports: # UDP is required!
# - "7777:7777/udp"
# - "7778:7778/udp"
각 게임 서버 서비스 정의하기
게임 서버를 새로 추가할 때마다 docker-compose.yml 파일에 새 서비스 정의를 넣어야 합니다. 기본 파일에 solo1 예시 서버가 있다면 그것을 복사해 수정하거나, 아래 템플릿을 사용하세요.
your_service_name: # e.g., solo2, duo1. Conventionally matches hostname and SERVERNAME.
container_name: YOUR_CONTAINER_NAME # e.g., spellbreak_solo2
hostname: YOUR_SERVER_HOSTNAME # e.g., solo2. Must be registered in elixir_service's GAME_SERVER_HOSTS!
environment:
- GAMEMODE=GAME_MODE # Suitable options are Solo, Duo, Squad, and Capture
- GAMEPORT=7777 # e.g., 7778. Must be unique on the host if exposed & registered in elixir_service's GAME_SERVER_PORTS.
- SERVERNAME=YOUR_SERVER_NAME # e.g., solo2. Conventionally matches hostname.
- ELIXIRPORT=3387 # e.g., 3388. Game Manager Port, must be registered in elixir_service's GAME_MANAGER_PORTS.
- PATCH_ENV=prod # Or vanilla
- IDLETIMER=60
# =-=-=!!! No touchy anything below this line! >:o !!!=-=-= #
image: brendoncintas/spellbreak_game_server:stable
restart: always
volumes:
- game_logs:/spellbreak-server/BaseServer/g3/Saved/Logs/ # Shared volume for logs
networks:
- spellbreak
구성에서 눈여겨봐야 할 점은 다음과 같습니다.
- 이름 규칙:
Docker 서비스 이름(예:your_service_name), 그 서비스 안의hostname, 그리고SERVERNAME환경 변수를 모두 동일하게 맞추는 것이 일반적입니다(예: 모두solo2). - Elixir 등록: 매치메이커가 서버를 인식하고 사용할 수 있도록, 각 게임 서버의
hostname과GAMEPORT를elixir_service의 환경 변수(각각GAME_SERVER_HOSTS와GAME_SERVER_PORTS)에 정확히 등록해야 합니다. 마찬가지로ELIXIRPORT도GAME_MANAGER_PORTS의 항목과 대응해야 합니다. - 포트 개방: 플레이어가 접속하려면 각 게임 서버의
GAMEPORT가 외부에서 접근 가능해야 합니다. 새 게임 서버를 추가했다면 그 정의에 ports 섹션을 추가해야 합니다(템플릿 참고). 이렇게 하면 호스트의GAMEPORT가 컨테이너로 매핑됩니다(예:"7778:7778/udp"). 서버 방화벽에서도 이 포트를 열어 두세요. 환경 변수의GAMEPORT값은 ports 매핑에 사용한 포트 번호와 같아야 합니다.
docker-compose.yml 파일 예시
# Made with <3 by Doobs. 3/6/2025
services:
# ==================== SPELLBREAK MATCHMAKING SERVER ====================
elixir_service:
image: brendoncintas/spellbreak_matchmaking:stable
container_name: spellbreak_matchmaking
environment:
# Database connection settings (match mariadb service)
DB_HOST: spellbreak_db # This must match the hostname in the mariadb service.
DB_USER: blackmarla # This must match the MYSQL_USER in the mariadb service.
DB_PASSWORD: YOUR_MYSQL_PASSWORD # This must match the MYSQL_PASSWORD in the mariadb service.
DB_NAME: spellbreak_server
DB_PORT: "3306"
# Game server port allocation for outbound connections
OUTBOUND_PORT_START: "8000"
OUTBOUND_PORT_END: "9000"
RECYCLE_PORT_MINUTES: "240"
# Debug settings
RECORDING_ENABLED: "false"
LOG_LEVEL: "debug"
GAME_SERVER_NAMES: Solos
GAME_SERVER_HOSTS: solo1
GAME_SERVER_PORTS: 7777
GAME_MANAGER_PORTS: 3387 # Used for issuing custom commands to the game (e.g. server restarts)
volumes:
- game_logs:/app/log # Shared log directory across all game servers
restart: always
networks:
- spellbreak
# Expose game ports for external players to connect. Left side is the host (same ports in GAME_SERVER_PORTS), right side is the forward port for your game server.
# UDP is a requirement!
ports:
- "7777:7777/udp"
# ==================== DATABASE ====================
mariadb:
image: brendoncintas/spellbreak_db:stable
container_name: spellbreak_db
hostname: spellbreak_db # This must match the entry within DB_HOST for the elixir_service.
restart: always
environment:
MYSQL_ROOT_PASSWORD: YOUR_DB_ROOT_PASSWORD # Superadmin password (should not be shared).
MYSQL_DATABASE: spellbreak_server
MYSQL_USER: blackmarla
MYSQL_PASSWORD: YOUR_MYSQL_PASSWORD # Matches DB_PASSWORD in elixir_service.
volumes:
- db_data:/var/lib/mysql
networks:
- spellbreak
# ==================== GAME SERVER ====================
solo1:
container_name: solo1
hostname: solo1
environment:
- GAMEMODE=Solo
- GAMEPORT=7777
- SERVERNAME=solo1
- ELIXIRPORT=3387
- PATCH_ENV=prod
- IDLETIMER=60
# =-=-=!!! No touchy anything below this line! >:o !!!=-=-= #
image: brendoncintas/spellbreak_game_server:stable
restart: always
volumes:
- game_logs:/spellbreak-server/BaseServer/g3/Saved/Logs/
networks:
- spellbreak
# ==================== SHARED VOLUMES & NETWORKS ====================
volumes:
db_data: # Stores MySQL database files
game_logs: # Shared log directory between game servers and matchmaking
networks:
spellbreak:
driver: bridge
Elixir와 MariaDB 없이 쓰는 간소화 구성(기능 제한)
매치메이킹이나 IP 주소 기록(보통 elixir_service가 담당) 같은 기능이 필요 없는 소규모 구성이라면 더 가벼운 방식을 고려할 수 있습니다. 이 경우 게임 서버만 실행합니다.
- elixir_service 제거: docker-compose.yml 파일에서 elixir_service 정의를 통째로 삭제합니다.
- mariadb 서비스 제거: 이 스택에서 mariadb는 주로 elixir_service가 사용하므로, elixir_service를 뺀다면 함께 삭제해도 됩니다.
- 포트 직접 개방: 각 게임 서버 서비스(예: solo1이나 위 템플릿으로 정의한 사용자 지정 서버)가 ports 섹션에서 GAMEPORT를 직접 개방하도록 하세요. 예시는 다음과 같습니다.
# In your game server service definition (e.g., solo1):
# environment:
# - GAMEPORT=7777
# # ... other env vars
ports:
- "7777:7777/udp" # Exposes the game port directly
직접 호스팅의 결과와 한계:
- 데이터베이스 기능 없음: elixir_service를 통해 데이터베이스에 의존하는 기능, 즉 플레이어 데이터 보존, 통계, elixir_service가 처리하던 고급 로깅 등은 사용할 수 없습니다.
- 단순화된 호스팅: 이 구성은 기본적인 게임 인스턴스 호스팅으로 축소됩니다.
- 설정 변경: 게임 서버 서비스에서 elixir_service와 관련된 환경 변수(ELIXIRPORT나 Elixir용 SERVERNAME 등록 등)는 더 이상 필요하지 않거나 사용되지 않을 수 있습니다. 이 간소화된 방식은 절충점을 이해하고 있고, Elixir 매치메이킹과 데이터베이스가 제공하는 폭넓은 기능 없이 게임 서버 호스팅만 필요할 때에만 권장합니다.