@minecraft-docker/mcctl 1.6.13 → 1.6.15

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -0,0 +1,266 @@
1
+ #!/bin/bash
2
+ # =============================================================================
3
+ # delete-server.sh - Delete a Minecraft server
4
+ # =============================================================================
5
+ # Usage: ./scripts/delete-server.sh <server-name> [options]
6
+ #
7
+ # This script removes a server created by create-server.sh:
8
+ # - Stops and removes the Docker container
9
+ # - Removes server from servers/compose.yml
10
+ # - Removes hostname from avahi-daemon
11
+ # - Deletes server directory (servers/<server-name>/)
12
+ #
13
+ # IMPORTANT: World data in worlds/ directory is PRESERVED.
14
+ #
15
+ # Options:
16
+ # -f, --force Skip confirmation prompt
17
+ # -y, --yes Same as --force
18
+ # --keep-avahi Don't remove avahi hostname entry
19
+ #
20
+ # Examples:
21
+ # ./scripts/delete-server.sh myserver
22
+ # ./scripts/delete-server.sh myserver --force
23
+ # =============================================================================
24
+
25
+ set -e
26
+
27
+ # Colors for output
28
+ RED='\033[0;31m'
29
+ GREEN='\033[0;32m'
30
+ YELLOW='\033[1;33m'
31
+ BLUE='\033[0;34m'
32
+ NC='\033[0m' # No Color
33
+
34
+ # Get script/platform directories
35
+ # Support both direct execution and npm package execution (mcctl CLI)
36
+ if [[ -n "${MCCTL_ROOT:-}" ]]; then
37
+ # Running via npm package
38
+ PLATFORM_DIR="$MCCTL_ROOT"
39
+ SCRIPT_DIR="${MCCTL_SCRIPTS:-$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)}"
40
+ else
41
+ # Running directly (development mode)
42
+ SCRIPT_DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)"
43
+ PLATFORM_DIR="$(dirname "$SCRIPT_DIR")"
44
+ fi
45
+
46
+ # Source common functions
47
+ source "$SCRIPT_DIR/lib/common.sh"
48
+
49
+ SERVERS_DIR="$PLATFORM_DIR/servers"
50
+ SERVERS_COMPOSE="$SERVERS_DIR/compose.yml"
51
+ MAIN_COMPOSE="$PLATFORM_DIR/docker-compose.yml"
52
+ AVAHI_HOSTS="/etc/avahi/hosts"
53
+
54
+ # Default values
55
+ FORCE_DELETE="false"
56
+ KEEP_AVAHI="false"
57
+
58
+ # Show usage
59
+ show_usage() {
60
+ echo "Usage: $0 <server-name> [options]"
61
+ echo ""
62
+ echo "Delete a Minecraft server (worlds are preserved)."
63
+ echo ""
64
+ echo "Options:"
65
+ echo " -f, --force Skip confirmation prompt"
66
+ echo " -y, --yes Same as --force"
67
+ echo " --keep-avahi Don't remove avahi hostname entry"
68
+ echo ""
69
+ echo "Examples:"
70
+ echo " $0 myserver"
71
+ echo " $0 myserver --force"
72
+ }
73
+
74
+ # Check if first argument exists
75
+ if [ -z "$1" ]; then
76
+ echo -e "${RED}Error: Server name is required${NC}"
77
+ echo ""
78
+ show_usage
79
+ exit 1
80
+ fi
81
+
82
+ # Check for help flag first
83
+ if [ "$1" = "-h" ] || [ "$1" = "--help" ]; then
84
+ show_usage
85
+ exit 0
86
+ fi
87
+
88
+ # First argument is server name
89
+ SERVER_NAME="$1"
90
+ shift
91
+
92
+ # Parse remaining arguments
93
+ while [[ $# -gt 0 ]]; do
94
+ case $1 in
95
+ -f|--force|-y|--yes)
96
+ FORCE_DELETE="true"
97
+ shift
98
+ ;;
99
+ --keep-avahi)
100
+ KEEP_AVAHI="true"
101
+ shift
102
+ ;;
103
+ -h|--help)
104
+ show_usage
105
+ exit 0
106
+ ;;
107
+ *)
108
+ echo -e "${RED}Error: Unknown option: $1${NC}"
109
+ echo ""
110
+ show_usage
111
+ exit 1
112
+ ;;
113
+ esac
114
+ done
115
+
116
+ # Validate server name
117
+ SERVER_DIR="$SERVERS_DIR/$SERVER_NAME"
118
+ if [ ! -d "$SERVER_DIR" ]; then
119
+ echo -e "${RED}Error: Server '$SERVER_NAME' not found at $SERVER_DIR${NC}"
120
+ exit 1
121
+ fi
122
+
123
+ # Confirmation prompt
124
+ if [ "$FORCE_DELETE" != "true" ]; then
125
+ echo -e "${YELLOW}WARNING: This will delete server '$SERVER_NAME'${NC}"
126
+ echo ""
127
+ echo "The following will be removed:"
128
+ echo " - Docker container: mc-$SERVER_NAME"
129
+ echo " - Server directory: servers/$SERVER_NAME/"
130
+ echo " - servers/compose.yml entry"
131
+ if [ "$KEEP_AVAHI" != "true" ]; then
132
+ echo " - avahi hostname: $SERVER_NAME.local"
133
+ fi
134
+ echo ""
135
+ echo -e "${GREEN}World data in worlds/ will be PRESERVED.${NC}"
136
+ echo ""
137
+ read -p "Are you sure? (y/N): " confirm
138
+ if [[ ! "$confirm" =~ ^[Yy]$ ]]; then
139
+ echo "Cancelled."
140
+ exit 0
141
+ fi
142
+ fi
143
+
144
+ echo ""
145
+ echo -e "${RED}Deleting server: $SERVER_NAME${NC}"
146
+ echo ""
147
+
148
+ # =============================================================================
149
+ # Step 1: Stop Docker container
150
+ # =============================================================================
151
+ echo -e "${BLUE}[1/4]${NC} Stopping Docker container..."
152
+ cd "$PLATFORM_DIR"
153
+ if docker compose ps "mc-$SERVER_NAME" 2>/dev/null | grep -q "mc-$SERVER_NAME"; then
154
+ docker compose stop "mc-$SERVER_NAME" 2>/dev/null || true
155
+ docker compose rm -f "mc-$SERVER_NAME" 2>/dev/null || true
156
+ echo " Container mc-$SERVER_NAME stopped and removed"
157
+ else
158
+ # Check if container exists but not managed by compose (exited state)
159
+ if docker ps -a --format '{{.Names}}' | grep -q "^mc-$SERVER_NAME$"; then
160
+ docker rm -f "mc-$SERVER_NAME" 2>/dev/null || true
161
+ echo " Container mc-$SERVER_NAME removed"
162
+ else
163
+ echo " Container mc-$SERVER_NAME not found"
164
+ fi
165
+ fi
166
+
167
+ # =============================================================================
168
+ # Step 2: Update servers/compose.yml
169
+ # =============================================================================
170
+ echo -e "${BLUE}[2/4]${NC} Updating servers/compose.yml..."
171
+
172
+ if [ -f "$SERVERS_COMPOSE" ]; then
173
+ # Backup original
174
+ cp "$SERVERS_COMPOSE" "$SERVERS_COMPOSE.bak"
175
+
176
+ # Remove include entry
177
+ if grep -q "$SERVER_NAME/docker-compose.yml" "$SERVERS_COMPOSE"; then
178
+ sed -i "\|$SERVER_NAME/docker-compose.yml|d" "$SERVERS_COMPOSE"
179
+ echo " Removed from include section"
180
+
181
+ # If no more includes, remove the include: line
182
+ if ! grep -q "^ - " "$SERVERS_COMPOSE"; then
183
+ sed -i '/^include:/d' "$SERVERS_COMPOSE"
184
+ echo " Removed empty include section"
185
+ fi
186
+ else
187
+ echo " Server not found in compose.yml"
188
+ fi
189
+
190
+ # Verify the changes
191
+ if docker compose -f "$MAIN_COMPOSE" config --quiet 2>/dev/null; then
192
+ echo -e " ${GREEN}Configuration validated successfully${NC}"
193
+ rm -f "$SERVERS_COMPOSE.bak"
194
+ else
195
+ echo -e "${RED} Error: Configuration validation failed!${NC}"
196
+ echo " Restoring backup..."
197
+ mv "$SERVERS_COMPOSE.bak" "$SERVERS_COMPOSE"
198
+ echo " Please check the configuration manually."
199
+ exit 1
200
+ fi
201
+ else
202
+ echo " servers/compose.yml not found (nothing to update)"
203
+ fi
204
+
205
+ # =============================================================================
206
+ # Step 3: Remove from avahi-daemon
207
+ # =============================================================================
208
+ echo -e "${BLUE}[3/4]${NC} Removing mDNS hostname..."
209
+ if [ "$KEEP_AVAHI" = "true" ]; then
210
+ echo " Skipped (--keep-avahi specified)"
211
+ elif [ -f "$AVAHI_HOSTS" ]; then
212
+ if grep -q "$SERVER_NAME.local" "$AVAHI_HOSTS" 2>/dev/null; then
213
+ if run_with_sudo sed -i "/$SERVER_NAME\.local/d" "$AVAHI_HOSTS" 2>/dev/null; then
214
+ run_with_sudo systemctl restart avahi-daemon 2>/dev/null || true
215
+ echo -e " ${GREEN}Removed $SERVER_NAME.local from avahi${NC}"
216
+ else
217
+ echo -e "${YELLOW} Warning: Failed to update avahi (sudo required)${NC}"
218
+ if has_sudo_password; then
219
+ echo " Check if MCCTL_SUDO_PASSWORD is correct"
220
+ else
221
+ echo " Set MCCTL_SUDO_PASSWORD env var or remove manually: sudo sed -i '/$SERVER_NAME.local/d' $AVAHI_HOSTS"
222
+ fi
223
+ fi
224
+ else
225
+ echo " Hostname not found in avahi"
226
+ fi
227
+ else
228
+ echo " avahi not configured"
229
+ fi
230
+
231
+ # =============================================================================
232
+ # Step 4: Delete server directory
233
+ # =============================================================================
234
+ echo -e "${BLUE}[4/4]${NC} Deleting server directory..."
235
+
236
+ # Check for symlinked worlds and warn
237
+ if [ -d "$SERVER_DIR/data" ]; then
238
+ for link in "$SERVER_DIR/data"/*; do
239
+ if [ -L "$link" ]; then
240
+ target=$(readlink "$link")
241
+ echo " Note: Symlink found: $(basename "$link") -> $target (preserved in worlds/)"
242
+ fi
243
+ done
244
+ fi
245
+
246
+ rm -rf "$SERVER_DIR"
247
+ echo -e " ${GREEN}Deleted servers/$SERVER_NAME/${NC}"
248
+
249
+ # =============================================================================
250
+ # Summary
251
+ # =============================================================================
252
+ echo ""
253
+ echo -e "${GREEN}========================================${NC}"
254
+ echo -e "${GREEN}Server '$SERVER_NAME' deleted successfully!${NC}"
255
+ echo -e "${GREEN}========================================${NC}"
256
+ echo ""
257
+ echo "Removed:"
258
+ echo " - Container: mc-$SERVER_NAME"
259
+ echo " - Directory: servers/$SERVER_NAME/"
260
+ echo " - servers/compose.yml entry"
261
+ if [ "$KEEP_AVAHI" != "true" ]; then
262
+ echo " - avahi hostname: $SERVER_NAME.local"
263
+ fi
264
+ echo ""
265
+ echo -e "${GREEN}World data in worlds/ has been preserved.${NC}"
266
+ echo ""
@@ -0,0 +1,390 @@
1
+ #!/bin/bash
2
+ # =============================================================================
3
+ # init.sh - Initialize Minecraft Platform for First Run
4
+ # =============================================================================
5
+ # This script prepares the platform for initial operation:
6
+ # 1. Validates Docker and Docker Compose installation
7
+ # 2. Validates avahi-daemon for mDNS support
8
+ # 3. Creates/validates .env configuration
9
+ # 4. Creates required directories
10
+ # 5. Creates Docker network and volumes
11
+ # 6. Performs initial docker-compose config validation
12
+ #
13
+ # Usage:
14
+ # ./scripts/init.sh [options]
15
+ #
16
+ # Options:
17
+ # --create-server NAME [TYPE] Create initial server after setup
18
+ # --skip-validation Skip Docker/Compose validation
19
+ # --skip-avahi Skip avahi-daemon validation
20
+ # --skip-compose-up Only initialize, don't start services
21
+ # -h, --help Show this help
22
+ #
23
+ # Example:
24
+ # ./scripts/init.sh
25
+ # ./scripts/init.sh --create-server myserver PAPER
26
+ # =============================================================================
27
+
28
+ set -e
29
+
30
+ # Colors for output
31
+ RED='\033[0;31m'
32
+ GREEN='\033[0;32m'
33
+ YELLOW='\033[1;33m'
34
+ BLUE='\033[0;34m'
35
+ MAGENTA='\033[0;35m'
36
+ NC='\033[0m' # No Color
37
+
38
+ # Get script/platform directories
39
+ # Support both direct execution and npm package execution (mcctl CLI)
40
+ if [[ -n "${MCCTL_ROOT:-}" ]]; then
41
+ # Running via npm package
42
+ PLATFORM_DIR="$MCCTL_ROOT"
43
+ SCRIPT_DIR="${MCCTL_SCRIPTS:-$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)}"
44
+ TEMPLATE_DIR="${MCCTL_TEMPLATES:-$PLATFORM_DIR/servers/_template}/servers/_template"
45
+ else
46
+ # Running directly (development mode)
47
+ SCRIPT_DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)"
48
+ PLATFORM_DIR="$(dirname "$SCRIPT_DIR")"
49
+ TEMPLATE_DIR="$PLATFORM_DIR/servers/_template"
50
+ fi
51
+
52
+ ENV_FILE="$PLATFORM_DIR/.env"
53
+ ENV_EXAMPLE="$PLATFORM_DIR/.env.example"
54
+
55
+ # Default options
56
+ VALIDATE_DOCKER=true
57
+ VALIDATE_AVAHI=true
58
+ START_SERVICES=true
59
+ CREATE_SERVER_NAME=""
60
+ CREATE_SERVER_TYPE="PAPER"
61
+
62
+ # Parse arguments
63
+ while [[ $# -gt 0 ]]; do
64
+ case $1 in
65
+ --create-server)
66
+ CREATE_SERVER_NAME="$2"
67
+ CREATE_SERVER_TYPE="${3:-PAPER}"
68
+ shift 3
69
+ ;;
70
+ --skip-validation)
71
+ VALIDATE_DOCKER=false
72
+ shift
73
+ ;;
74
+ --skip-avahi)
75
+ VALIDATE_AVAHI=false
76
+ shift
77
+ ;;
78
+ --skip-compose-up)
79
+ START_SERVICES=false
80
+ shift
81
+ ;;
82
+ -h|--help)
83
+ sed -n '/^# Usage:/,/^$/p' "$0" | sed 's/^# *//'
84
+ exit 0
85
+ ;;
86
+ *)
87
+ echo -e "${RED}Error: Unknown option $1${NC}"
88
+ exit 1
89
+ ;;
90
+ esac
91
+ done
92
+
93
+ # =============================================================================
94
+ # Helper Functions
95
+ # =============================================================================
96
+
97
+ print_header() {
98
+ echo ""
99
+ echo -e "${MAGENTA}━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━${NC}"
100
+ echo -e "${MAGENTA} $1${NC}"
101
+ echo -e "${MAGENTA}━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━${NC}"
102
+ echo ""
103
+ }
104
+
105
+ print_step() {
106
+ echo -e "${BLUE}▶ $1${NC}"
107
+ }
108
+
109
+ print_success() {
110
+ echo -e "${GREEN}✓ $1${NC}"
111
+ }
112
+
113
+ print_warning() {
114
+ echo -e "${YELLOW}⚠ $1${NC}"
115
+ }
116
+
117
+ print_error() {
118
+ echo -e "${RED}✗ $1${NC}"
119
+ }
120
+
121
+ # =============================================================================
122
+ # 1. Validate Docker and Docker Compose
123
+ # =============================================================================
124
+
125
+ if [ "$VALIDATE_DOCKER" = true ]; then
126
+ print_header "Step 1: Validating Docker and Docker Compose"
127
+
128
+ print_step "Checking Docker installation..."
129
+ if ! command -v docker &> /dev/null; then
130
+ print_error "Docker not found. Please install Docker Engine 20.10+"
131
+ exit 1
132
+ fi
133
+ DOCKER_VERSION=$(docker --version | grep -oP '\d+\.\d+' | head -1)
134
+ print_success "Docker $DOCKER_VERSION found"
135
+
136
+ print_step "Checking Docker Compose installation..."
137
+ if ! command -v docker compose &> /dev/null && ! command -v docker-compose &> /dev/null; then
138
+ print_error "Docker Compose not found. Please install Docker Compose v2.0+"
139
+ exit 1
140
+ fi
141
+ if command -v docker compose &> /dev/null; then
142
+ COMPOSE_VERSION=$(docker compose version 2>&1 | grep -oP '\d+\.\d+' | head -1 || echo "unknown")
143
+ DOCKER_COMPOSE_CMD="docker compose"
144
+ else
145
+ COMPOSE_VERSION=$(docker-compose --version 2>&1 | grep -oP '\d+\.\d+' | head -1 || echo "unknown")
146
+ DOCKER_COMPOSE_CMD="docker-compose"
147
+ fi
148
+ print_success "Docker Compose $COMPOSE_VERSION found"
149
+
150
+ print_step "Checking Docker daemon..."
151
+ if ! docker info &> /dev/null; then
152
+ print_error "Cannot connect to Docker daemon. Please ensure Docker is running"
153
+ exit 1
154
+ fi
155
+ print_success "Docker daemon is running"
156
+ fi
157
+
158
+ # =============================================================================
159
+ # 2. Validate avahi-daemon (mDNS support)
160
+ # =============================================================================
161
+
162
+ if [ "$VALIDATE_AVAHI" = true ]; then
163
+ print_header "Step 2: Validating avahi-daemon (mDNS)"
164
+
165
+ print_step "Checking avahi-daemon installation..."
166
+ if command -v avahi-daemon &> /dev/null; then
167
+ print_success "avahi-daemon found"
168
+ else
169
+ print_warning "avahi-daemon not found"
170
+ echo ""
171
+ echo -e "${YELLOW}To install avahi-daemon:${NC}"
172
+ echo " Debian/Ubuntu: sudo apt install avahi-daemon"
173
+ echo " CentOS/RHEL: sudo dnf install avahi"
174
+ echo " Arch Linux: sudo pacman -S avahi nss-mdns"
175
+ echo " Alpine Linux: apk add avahi"
176
+ echo ""
177
+ fi
178
+
179
+ print_step "Checking avahi-daemon status..."
180
+ if systemctl is-active --quiet avahi-daemon 2>/dev/null; then
181
+ print_success "avahi-daemon is running"
182
+ elif rc-service avahi-daemon status &>/dev/null; then
183
+ print_success "avahi-daemon is running (OpenRC)"
184
+ else
185
+ print_warning "avahi-daemon is not running"
186
+ echo ""
187
+ echo -e "${YELLOW}To start avahi-daemon:${NC}"
188
+ echo " Systemd: sudo systemctl enable --now avahi-daemon"
189
+ echo " OpenRC: rc-update add avahi-daemon default && rc-service avahi-daemon start"
190
+ echo ""
191
+ fi
192
+
193
+ print_step "Checking /etc/avahi/hosts write permission..."
194
+ if [ -w /etc/avahi/hosts ] || sudo test -w /etc/avahi/hosts 2>/dev/null; then
195
+ print_success "/etc/avahi/hosts is writable"
196
+ else
197
+ print_warning "/etc/avahi/hosts may require sudo for hostname registration"
198
+ fi
199
+ fi
200
+
201
+ # =============================================================================
202
+ # 3. Setup Environment File
203
+ # =============================================================================
204
+
205
+ print_header "Step 3: Setting up environment configuration"
206
+
207
+ if [ ! -f "$ENV_FILE" ]; then
208
+ print_step "Creating .env from template..."
209
+ if [ -f "$ENV_EXAMPLE" ]; then
210
+ cp "$ENV_EXAMPLE" "$ENV_FILE"
211
+ print_success ".env created from .env.example"
212
+ else
213
+ print_warning ".env.example not found, creating minimal .env"
214
+ cat > "$ENV_FILE" << 'EOF'
215
+ # Multi-Server Minecraft Management
216
+ MINECRAFT_NETWORK=minecraft-net
217
+ MINECRAFT_SUBNET=172.28.0.0/16
218
+ DEFAULT_MEMORY=4G
219
+ DEFAULT_VERSION=1.20.4
220
+ TZ=Asia/Seoul
221
+ RCON_PASSWORD=changeme
222
+ COMPOSE_PROJECT_NAME=minecraft
223
+ EOF
224
+ print_success "Minimal .env created"
225
+ fi
226
+ print_warning "Please review and update .env with your settings"
227
+ else
228
+ print_success ".env already exists"
229
+ fi
230
+
231
+ # =============================================================================
232
+ # 4. Create Required Directories
233
+ # =============================================================================
234
+
235
+ print_header "Step 4: Creating required directories"
236
+
237
+ DIRS=(
238
+ "$PLATFORM_DIR/servers"
239
+ "$PLATFORM_DIR/shared/plugins"
240
+ "$PLATFORM_DIR/shared/mods"
241
+ "$PLATFORM_DIR/worlds"
242
+ "$PLATFORM_DIR/worlds/.locks"
243
+ "$PLATFORM_DIR/backups/servers"
244
+ "$PLATFORM_DIR/backups/worlds"
245
+ )
246
+
247
+ for dir in "${DIRS[@]}"; do
248
+ if [ ! -d "$dir" ]; then
249
+ mkdir -p "$dir"
250
+ print_step "Created: $dir"
251
+ fi
252
+ done
253
+
254
+ print_success "All directories validated/created"
255
+
256
+ # =============================================================================
257
+ # 5. Validate docker-compose.yml
258
+ # =============================================================================
259
+
260
+ print_header "Step 5: Validating Docker Compose configuration"
261
+
262
+ print_step "Validating $PLATFORM_DIR/docker-compose.yml..."
263
+ cd "$PLATFORM_DIR"
264
+ if ! $DOCKER_COMPOSE_CMD config > /dev/null 2>&1; then
265
+ print_error "Docker Compose configuration is invalid"
266
+ $DOCKER_COMPOSE_CMD config
267
+ exit 1
268
+ fi
269
+ print_success "Docker Compose configuration is valid"
270
+
271
+ # =============================================================================
272
+ # 6. Create/Verify Docker Network
273
+ # =============================================================================
274
+
275
+ print_header "Step 6: Setting up Docker network"
276
+
277
+ # Source .env to get network settings
278
+ set -a
279
+ source <(grep -v '^\s*#' "$ENV_FILE" | grep -v '^\s*$') 2>/dev/null || true
280
+ set +a
281
+
282
+ NETWORK_NAME="${MINECRAFT_NETWORK:-minecraft-net}"
283
+ print_step "Checking network: $NETWORK_NAME"
284
+
285
+ if ! docker network ls | grep -q "^[^ ]*${NETWORK_NAME}"; then
286
+ print_step "Creating network: $NETWORK_NAME"
287
+ docker network create \
288
+ --driver bridge \
289
+ --subnet "${MINECRAFT_SUBNET:-172.28.0.0/16}" \
290
+ "$NETWORK_NAME" 2>/dev/null || true
291
+ print_success "Network created/verified"
292
+ else
293
+ print_success "Network already exists"
294
+ fi
295
+
296
+ # =============================================================================
297
+ # 7. Create Initial Server (Optional)
298
+ # =============================================================================
299
+
300
+ if [ -n "$CREATE_SERVER_NAME" ]; then
301
+ print_header "Step 7: Creating initial server"
302
+ print_step "Creating server: $CREATE_SERVER_NAME ($CREATE_SERVER_TYPE)"
303
+
304
+ if [ -x "$SCRIPT_DIR/create-server.sh" ]; then
305
+ "$SCRIPT_DIR/create-server.sh" "$CREATE_SERVER_NAME" -t "$CREATE_SERVER_TYPE" --no-start
306
+ print_success "Server created: $CREATE_SERVER_NAME"
307
+ else
308
+ print_error "create-server.sh not found or not executable"
309
+ exit 1
310
+ fi
311
+ else
312
+ print_header "Step 7: Initial server creation"
313
+ print_warning "No initial server requested (use --create-server NAME [TYPE] to create one)"
314
+ fi
315
+
316
+ # =============================================================================
317
+ # 8. Start Services (Optional)
318
+ # =============================================================================
319
+
320
+ if [ "$START_SERVICES" = true ]; then
321
+ print_header "Step 8: Starting platform services"
322
+
323
+ print_step "Starting Docker Compose services..."
324
+ cd "$PLATFORM_DIR"
325
+ $DOCKER_COMPOSE_CMD up -d router 2>&1 | grep -E '(Creating|Created|Starting|Started)' || true
326
+
327
+ print_success "mc-router started"
328
+
329
+ # Wait for router to be ready
330
+ print_step "Waiting for router to be ready..."
331
+ for i in {1..30}; do
332
+ if docker exec mc-router nc -zv localhost 25565 &> /dev/null; then
333
+ print_success "Router is ready"
334
+ break
335
+ fi
336
+ if [ $i -eq 30 ]; then
337
+ print_warning "Router startup timeout (may still be initializing)"
338
+ fi
339
+ sleep 1
340
+ done
341
+ else
342
+ print_header "Step 8: Services not started"
343
+ print_warning "Use 'docker compose up -d' to start services manually"
344
+ fi
345
+
346
+ # =============================================================================
347
+ # 9. Summary
348
+ # =============================================================================
349
+
350
+ print_header "Initialization Complete ✓"
351
+
352
+ cat << EOF
353
+
354
+ ${GREEN}Platform Status:${NC}
355
+
356
+ 📁 Configuration: $ENV_FILE
357
+ 🐳 Network: $NETWORK_NAME
358
+ 📂 Directories: Created
359
+ 🌐 mDNS: avahi-daemon (system service)
360
+
361
+ ${GREEN}Next Steps:${NC}
362
+
363
+ 1. Create your first server:
364
+ cd $PLATFORM_DIR
365
+ ./scripts/create-server.sh myserver -t PAPER
366
+
367
+ 2. Connect to server (mDNS):
368
+ Open Minecraft and connect to: myserver.local:25565
369
+
370
+ 3. View server status:
371
+ docker compose ps
372
+
373
+ 4. View logs:
374
+ docker logs -f mc-myserver
375
+
376
+ ${YELLOW}Environment Reminder:${NC}
377
+
378
+ ⚠️ Default RCON_PASSWORD is 'changeme' - change in .env for production!
379
+ ⚠️ Ensure avahi-daemon is running for mDNS auto-discovery
380
+
381
+ ${BLUE}Documentation:${NC}
382
+
383
+ 📖 Getting Started: Read README.md
384
+ 📖 mDNS Setup: See README.md#mdns-setup-guide
385
+ 📖 Full Docs: See docs/doc-list.md
386
+
387
+ EOF
388
+
389
+ print_success "Platform ready to use!"
390
+ exit 0