#!/usr/bin/env bash set -euo pipefail ROOT_DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)" ENV_FILE="${ENV_FILE:-$ROOT_DIR/.env}" BUILD_FLAG="--build" FOLLOW_LOGS=0 if [[ -f "$ENV_FILE" ]]; then set -a # shellcheck disable=SC1090 source "$ENV_FILE" set +a fi usage() { cat <&2 docker compose logs --tail=120 "$service" >&2 || true printf '\n' >&2 } wait_for_healthy() { local container_name="$1" local timeout_seconds="${2:-180}" local start_ts now status start_ts="$(date +%s)" while :; do status="$(docker inspect -f '{{if .State.Health}}{{.State.Health.Status}}{{else}}{{.State.Status}}{{end}}' "$container_name" 2>/dev/null || true)" case "$status" in healthy|running) return 0 ;; unhealthy|exited|dead) return 1 ;; esac now="$(date +%s)" if (( now - start_ts >= timeout_seconds )); then return 1 fi sleep 2 done } run_one_shot_service() { local service="$1" local container_name="$2" if [[ -n "$BUILD_FLAG" ]]; then if ! docker compose up --build --no-deps "$service"; then print_service_logs "$service" printf '%s failed during startup\n' "$service" >&2 exit 1 fi else if ! docker compose up --no-deps "$service"; then print_service_logs "$service" printf '%s failed during startup\n' "$service" >&2 exit 1 fi fi local exit_code exit_code="$(docker inspect -f '{{.State.ExitCode}}' "$container_name" 2>/dev/null || printf '1')" if [[ "$exit_code" != "0" ]]; then print_service_logs "$service" printf '%s failed with exit code %s\n' "$service" "$exit_code" >&2 exit 1 fi } require_docker() { if ! command -v docker >/dev/null 2>&1; then printf 'docker is not installed or not in PATH\n' >&2 exit 1 fi if ! docker compose version >/dev/null 2>&1; then printf 'docker compose plugin is not available\n' >&2 printf 'On Ubuntu install: docker-compose-plugin\n' >&2 exit 1 fi if ! docker info >/dev/null 2>&1; then printf 'docker daemon is not reachable\n' >&2 printf 'On Ubuntu run: sudo systemctl enable --now docker\n' >&2 printf 'If docker is running but you are a non-root user, add your user to the docker group:\n' >&2 printf ' sudo usermod -aG docker $USER && newgrp docker\n' >&2 exit 1 fi } while (($#)); do case "$1" in --no-build) BUILD_FLAG="" ;; --logs) FOLLOW_LOGS=1 ;; -h|--help) usage exit 0 ;; *) printf 'Unknown option: %s\n\n' "$1" >&2 usage >&2 exit 1 ;; esac shift done cd "$ROOT_DIR" require_docker log "applying module configuration" bash "$ROOT_DIR/setup-modules.sh" log "starting database" if [[ -n "$BUILD_FLAG" ]]; then docker compose up -d --build ac-database else docker compose up -d ac-database fi if ! wait_for_healthy "ac-database" 180; then print_service_logs "ac-database" printf 'ac-database did not become healthy\n' >&2 exit 1 fi log "running database import" run_one_shot_service "ac-db-import" "ac-db-import" log "initializing client data" run_one_shot_service "ac-client-data-init" "ac-client-data-init" log "starting authserver and worldserver" if [[ -n "$BUILD_FLAG" ]]; then docker compose up -d --build ac-authserver ac-worldserver else docker compose up -d ac-authserver ac-worldserver fi log "synchronizing realmlist" bash "$ROOT_DIR/sync-realmlist.sh" log "current service status" docker compose ps printf '\n' printf 'Realm: %s:%s\n' "${ACORE_REALMLIST_PUBLIC_ADDRESS:-127.0.0.1}" "${ACORE_REALMLIST_PORT:-${DOCKER_WORLD_EXTERNAL_PORT:-8085}}" printf 'World: 127.0.0.1:%s\n' "${DOCKER_WORLD_EXTERNAL_PORT:-8085}" printf 'Auth: 127.0.0.1:%s\n' "${DOCKER_AUTH_EXTERNAL_PORT:-3724}" printf 'SOAP: 127.0.0.1:%s\n' "${DOCKER_SOAP_EXTERNAL_PORT:-7878}" printf 'Account: ./create-account.sh admin your_password\n' printf 'RealmDB: ./sync-realmlist.sh\n' printf 'Logs: docker compose logs -f ac-worldserver ac-authserver\n' if (( FOLLOW_LOGS )); then docker compose logs -f ac-worldserver ac-authserver fi