본문으로 건너뛰기

Docker로 호스팅하기

이 가이드는 Docker를 사용하는 고급 서버 구성을 다룹니다. Linux 환경, 명령줄 인터페이스, Docker 생태계(이미지, 컨테이너, 볼륨, 네트워킹, docker-compose에 대한 탄탄한 이해 포함)에 익숙한 분만을 대상으로 합니다.

  • Linux 터미널에서 자유롭게 작업할 수 있어야 합니다.
  • Docker 개념, 즉 이미지가 어떻게 빌드되고 실행되는지, 컨테이너를 어떻게 관리하는지, docker-compose가 멀티 컨테이너 애플리케이션을 어떻게 오케스트레이션하는지 잘 알고 있어야 합니다.
위험

이 구성을 진행한다는 것은 필요한 기술 지식을 갖추고 있다는 뜻입니다. 구성이 복잡하고 사용자마다 환경이 크게 다르기 때문에, 이 Docker 구성에 대한 직접 지원은 본질적으로 매우 제한적입니다. 문제가 생겼을 때의 책임은 전적으로 사용자에게 있습니다.


Spellbreak 서버를 확장 가능하고 관리하기 쉬운 방식으로 만들고 운영하고자 한다면 Docker가 든든한 선택지입니다. 이 방법에서는 docker-compose 를 사용해 멀티 컨테이너 Spellbreak 서버 애플리케이션을 정의하고 실행합니다.

사전 준비

  1. Docker 설치: Linux 서버에 Docker Engine과 Docker Compose가 설치되어 있어야 합니다. 아직 설치하지 않았다면 공식 Docker 문서에서 사용 중인 Linux 배포판에 맞는 안내를 참고하세요.
  2. 디렉터리 준비: 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 등록: 매치메이커가 서버를 인식하고 사용할 수 있도록, 게임 서버의 hostnameGAMEPORTelixir_service의 환경 변수(각각 GAME_SERVER_HOSTSGAME_SERVER_PORTS)에 정확히 등록해야 합니다. 마찬가지로 ELIXIRPORTGAME_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가 담당) 같은 기능이 필요 없는 소규모 구성이라면 더 가벼운 방식을 고려할 수 있습니다. 이 경우 게임 서버만 실행합니다.

  1. elixir_service 제거: docker-compose.yml 파일에서 elixir_service 정의를 통째로 삭제합니다.
  2. mariadb 서비스 제거: 이 스택에서 mariadb는 주로 elixir_service가 사용하므로, elixir_service를 뺀다면 함께 삭제해도 됩니다.
  3. 포트 직접 개방: 각 게임 서버 서비스(예: 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 매치메이킹과 데이터베이스가 제공하는 폭넓은 기능 없이 게임 서버 호스팅만 필요할 때에만 권장합니다.