# Multi Server Setup

Complete guide for configuring AnnouncementGUI across multiple servers in a network.

## 📋 Overview

AnnouncementGUI supports multi-server networks with real-time synchronization using MySQL. Create announcements on one server and they automatically sync to all others.

## 🎯 Key Concepts

### Server IDs

Each server in your network has a unique identifier:

```yaml
localServerId: "lobby"      # This server's ID
```

### Target Selection

Announcements can target:

* **Specific Server**: e.g., "lobby", "survival", "creative"
* **ALL Servers**: Broadcasts network-wide

### Synchronization

With MySQL storage:

* **Create** on one server → Appears on all
* **Edit** on any server → Updates everywhere
* **Delete** on any server → Removed from all
* **Toggle** on any server → Status syncs everywhere

## 🏗️ Network Architecture

### Example Network

```
┌─────────────────────────────────────────┐
│          MySQL Database                 │
│      (Central Storage)                  │
└─────────────────────────────────────────┘
           ↕️          ↕️          ↕️
    ┌──────────┐ ┌──────────┐ ┌──────────┐
    │  Lobby   │ │ Survival │ │ Creative │
    │ Server   │ │  Server  │ │  Server  │
    └──────────┘ └──────────┘ └──────────┘
```

Components:

1. MySQL Database: Central storage for all announcements
2. Lobby Server: localServerId = "lobby"
3. Survival Server: localServerId = "survival"
4. Creative Server: localServerId = "creative"

## 📦 Prerequisites

### Required

* 2+ Minecraft Servers: Paper 1.21+ or Folia
* MySQL Server: 5.7+ or MariaDB 10.2+
* Network Connectivity: All servers can reach MySQL
* AnnouncementGUI: Installed on all servers

### Recommended

* Dedicated MySQL Server: Better performance
* Low Latency: Fast network between servers and MySQL
* Backup System: Regular MySQL backups

## 🚀 Setup Process

{% stepper %}
{% step %}

### Install MySQL (Step 1)

#### Option A: Self-Hosted MySQL

Ubuntu/Debian:

{% code title="Ubuntu/Debian" %}

```bash
sudo apt update
sudo apt install mysql-server
sudo mysql_secure_installation
```

{% endcode %}

CentOS/RHEL:

{% code title="CentOS/RHEL" %}

```bash
sudo yum install mysql-server
sudo systemctl start mysqld
sudo mysql_secure_installation
```

{% endcode %}

Windows:\
Download and install from [MySQL Downloads](https://dev.mysql.com/downloads/mysql/)
{% endstep %}

{% step %}

### Managed MySQL Service (Alternative to Step 1)

Popular options:

* AWS RDS
* Google Cloud SQL
* Azure Database for MySQL
* DigitalOcean Managed Databases
* Aiven
  {% endstep %}

{% step %}

### Create Database (Step 2)

Connect to MySQL:

{% code title="Connect to MySQL" %}

```bash
mysql -u root -p
```

{% endcode %}

Create database and user:

{% code title="Create database and user" %}

```sql
-- Create database
CREATE DATABASE minecraft_announcements;

-- Create dedicated user
CREATE USER 'announcegui'@'%' IDENTIFIED BY 'your_strong_password_here';

-- Grant privileges
GRANT ALL PRIVILEGES ON minecraft_announcements.* TO 'announcegui'@'%';

-- Apply changes
FLUSH PRIVILEGES;

-- Exit
EXIT;
```

{% endcode %}

Security Notes:

* Replace `'your_strong_password_here'` with a strong password
* For production, consider using `'announcegui'@'specific_ip'` instead of `'%'`
  {% endstep %}

{% step %}

### Configure Firewall (Step 3)

Allow MySQL access from server IPs.

Ubuntu/Debian (ufw):

{% code title="ufw" %}

```bash
sudo ufw allow from <server-ip> to any port 3306
```

{% endcode %}

CentOS/RHEL (firewalld):

{% code title="firewalld" %}

```bash
sudo firewall-cmd --permanent --add-rich-rule='rule family="ipv4" source address="<server-ip>" port protocol="tcp" port="3306" accept'
sudo firewall-cmd --reload
```

{% endcode %}

Test connection from each Minecraft server:

{% code title="Test connection" %}

```bash
mysql -h <mysql-host> -u announcegui -p minecraft_announcements
```

{% endcode %}
{% endstep %}

{% step %}

### Install Plugin on All Servers (Step 4)

* Download AnnouncementGUI JAR
* Place in `plugins/` folder on each server
* Start each server to generate configs
* Stop all servers
  {% endstep %}

{% step %}

### Configure Each Server (Step 5)

Edit `plugins/AnnouncementGUI/config.yml` on each server.

Lobby Server Configuration:

{% code title="Lobby config.yml" %}

```yaml
# Unique ID for this server
localServerId: "lobby"

# List of all servers in network
servers:
  - "lobby"
  - "survival"
  - "creative"
  - "skyblock"

# Run ALL announcements on this server
enableAllServersAnnouncements: true

# Check for changes every 10 seconds
changePollingIntervalSeconds: 10

# MySQL storage configuration
storage:
  type: mysql
  mysql:
    host: "192.168.1.100"  # Your MySQL server IP
    port: 3306
    database: "minecraft_announcements"
    username: "announcegui"
    password: "your_strong_password_here"
    params: "useSSL=false&serverTimezone=UTC"
```

{% endcode %}

Survival Server Configuration:

{% code title="Survival config.yml" %}

```yaml
# Unique ID for this server
localServerId: "survival"

# List of all servers in network (same as lobby)
servers:
  - "lobby"
  - "survival"
  - "creative"
  - "skyblock"

# Run ALL announcements on this server
enableAllServersAnnouncements: true

# Check for changes every 10 seconds
changePollingIntervalSeconds: 10

# MySQL storage configuration (same as lobby)
storage:
  type: mysql
  mysql:
    host: "192.168.1.100"
    port: 3306
    database: "minecraft_announcements"
    username: "announcegui"
    password: "your_strong_password_here"
    params: "useSSL=false&serverTimezone=UTC"
```

{% endcode %}

Other Servers:

* Same `servers` list on all servers
* Same MySQL configuration on all servers
* Different `localServerId` for each server
* Adjust `enableAllServersAnnouncements` per server needs
  {% endstep %}

{% step %}

### Start All Servers (Step 6)

1. Start all servers
2. Check console logs for:

{% code title="Expected logs" %}

```
[AnnouncementGUI] Initializing AnnouncementGUI...
[AnnouncementGUI] Using lightweight announcement change polling...
```

{% endcode %}

3. Check for any MySQL connection errors
   {% endstep %}

{% step %}

### Test Synchronization (Step 7)

1. Connect to Lobby Server
2. Run `/announcegui`
3. Create a test announcement:
   * Name: "Test Sync"
   * Message: "Testing multi-server sync"
   * Interval: 300
   * Server: "ALL"
   * Save
4. Wait 10-15 seconds (polling interval)
5. Connect to Survival Server
6. Run `/announcegui`
7. Click "Edit" - The "Test Sync" announcement should appear!
8. Edit on Survival - Change message
9. Check on Lobby - Changes should sync within 10-15 seconds
   {% endstep %}
   {% endstepper %}

## ⚙️ Configuration Options

### Polling Interval

Controls how often servers check for changes:

```yaml
changePollingIntervalSeconds: 10  # Check every 10 seconds
```

Recommendations:

| Network Size  | Polling Interval | Rationale                 |
| ------------- | ---------------- | ------------------------- |
| 2-5 servers   | 5-10 seconds     | Fast sync, low overhead   |
| 5-10 servers  | 10-15 seconds    | Balanced                  |
| 10-20 servers | 15-30 seconds    | Reduce MySQL load         |
| 20+ servers   | 30-60 seconds    | Minimize database queries |

Trade-offs:

* Lower values: Faster sync, more database queries
* Higher values: Slower sync, fewer database queries

### Enable/Disable ALL Announcements

Control whether a server runs network-wide (ALL) announcements:

```yaml
enableAllServersAnnouncements: true  # Run ALL announcements
```

Use Cases:

Enable on Hub/Lobby:

```yaml
localServerId: "lobby"
enableAllServersAnnouncements: true  # Players see network announcements
```

Disable on Minigame Servers:

```yaml
localServerId: "bedwars"
enableAllServersAnnouncements: false  # Only bedwars-specific announcements
```

### MySQL Connection Parameters

Customize MySQL connection:

```yaml
params: "useSSL=false&serverTimezone=UTC&maxPoolSize=10"
```

Common Parameters:

| Parameter           | Purpose              | Example                  |
| ------------------- | -------------------- | ------------------------ |
| `useSSL`            | Enable/disable SSL   | `useSSL=true`            |
| `serverTimezone`    | Set timezone         | `serverTimezone=UTC`     |
| `maxPoolSize`       | Connection pool size | `maxPoolSize=10`         |
| `autoReconnect`     | Auto-reconnect       | `autoReconnect=true`     |
| `characterEncoding` | Character encoding   | `characterEncoding=utf8` |

Production Example:

```yaml
params: "useSSL=true&requireSSL=true&serverTimezone=UTC&maxPoolSize=20&autoReconnect=true"
```

## 🎯 Server Targeting Strategies

### Specific Server Announcements

Goal: Different announcements per server.

Configuration:

* Each server has unique `localServerId`
* Create announcements targeting specific servers

Example:

```
Announcement 1:
- Name: "Lobby Welcome"
- Target: "lobby"
- Message: "Welcome to the lobby!"

Announcement 2:
- Name: "Survival Rules"
- Target: "survival"
- Message: "Follow survival rules!"

Announcement 3:
- Name: "Creative Tips"
- Target: "creative"
- Message: "Be creative!"
```

Result:

* Lobby only shows "Lobby Welcome"
* Survival only shows "Survival Rules"
* Creative only shows "Creative Tips"

### Network-Wide Announcements

Goal: Same announcements everywhere.

Configuration:

* All servers have `enableAllServersAnnouncements: true`
* Create announcements targeting "ALL"

Example:

```
Announcement 1:
- Name: "Network Welcome"
- Target: "ALL"
- Message: "Welcome to our network!"
```

Result:

* All servers show the same message

### Hybrid Approach

Goal: Mix of specific and network-wide.

Configuration:

* All servers have `enableAllServersAnnouncements: true`
* Mix of specific and ALL targets

Example:

```
Announcement 1:
- Name: "Vote Reminder"
- Target: "ALL"
- Message: "Vote for rewards!"

Announcement 2:
- Name: "Survival Events"
- Target: "survival"
- Message: "Join survival events!"

Announcement 3:
- Name: "Creative Contests"
- Target: "creative"
- Message: "Creative building contest!"
```

Result:

* All servers show "Vote Reminder"
* Survival shows "Vote Reminder" + "Survival Events"
* Creative shows "Vote Reminder" + "Creative Contests"

### Hub-Only Network Announcements

Goal: Network announcements only in hub.

Configuration:

* Hub: `enableAllServersAnnouncements: true`
* Game servers: `enableAllServersAnnouncements: false`

Example:

```
Hub Config:
enableAllServersAnnouncements: true

Game Server Configs:
enableAllServersAnnouncements: false
```

Result:

* Hub shows ALL + lobby-specific announcements
* Game servers only show game-specific announcements

## 🔧 Advanced Configurations

### Multiple Database Setups

Use Case: Separate databases for different server groups.

Setup:

```
Group 1 (Survival Network):
- survival-1, survival-2, survival-3
- Database: survival_announcements

Group 2 (Creative Network):
- creative-1, creative-2
- Database: creative_announcements
```

Configuration:

Survival Servers:

```yaml
localServerId: "survival-1"  # or survival-2, survival-3
servers:
  - "survival-1"
  - "survival-2"
  - "survival-3"
storage:
  type: mysql
  mysql:
    database: "survival_announcements"
    # ... other settings
```

Creative Servers:

```yaml
localServerId: "creative-1"  # or creative-2
servers:
  - "creative-1"
  - "creative-2"
storage:
  type: mysql
  mysql:
    database: "creative_announcements"
    # ... other settings
```

### Geographic Distribution

Use Case: Servers in different regions.

Considerations:

* Latency: Higher ping to MySQL
* Polling Interval: Increase if high latency
* Replication: Consider MySQL master-slave replication

Example Setup:

```
US Region:
- MySQL Primary: us-mysql.example.com
- Servers: us-lobby, us-survival

EU Region:
- MySQL Replica: eu-mysql.example.com
- Servers: eu-lobby, eu-survival
```

### High Availability

Use Case: Ensure uptime even if MySQL fails.

Strategy:

1. MySQL Replication: Master-slave setup
2. Failover: Automatic failover to replica
3. Load Balancing: Distribute queries

Tools:

* MySQL Master-Slave Replication
* ProxySQL
* HAProxy
* Kubernetes with MySQL Operator

## 📊 Monitoring and Maintenance

### Monitoring Checklist

* [ ] MySQL server uptime
* [ ] MySQL connection count
* [ ] Announcement sync delay
* [ ] Database query performance
* [ ] Network latency between servers and MySQL
* [ ] Plugin errors in server logs

### Maintenance Tasks

Weekly:

* Check MySQL connection logs
* Verify announcements syncing
* Review server console for errors

Monthly:

* Optimize MySQL tables
* Review and clean old announcements
* Check database size
* Update MySQL credentials if needed

Quarterly:

* Full MySQL backup
* Test disaster recovery
* Review polling intervals
* Update plugin versions

### MySQL Optimization

Optimize Tables:

{% code title="Optimize tables" %}

```sql
USE minecraft_announcements;
OPTIMIZE TABLE announcements;
OPTIMIZE TABLE announcement_changelog;
```

{% endcode %}

Check Table Status:

{% code title="Table status" %}

```sql
SHOW TABLE STATUS FROM minecraft_announcements;
```

{% endcode %}

View Active Connections:

{% code title="Processlist" %}

```sql
SHOW PROCESSLIST;
```

{% endcode %}

## 🐛 Troubleshooting

### Issue: Announcements not syncing

Symptoms:

* Create on Server A, doesn't appear on Server B

Diagnosis:

1. Check `changePollingIntervalSeconds` - wait at least that long
2. Check MySQL connectivity from both servers
3. Check console logs for errors
4. Verify same database in configs

Solutions:

```bash
# Test MySQL connection from each server
mysql -h <mysql-host> -u announcegui -p minecraft_announcements

# Check config.yml
- Same MySQL host, database, username, password
- Correct localServerId for each server
- Same server list on all servers

# Check logs
- Look for "Failed to connect to MySQL"
- Look for "Failed to poll changes"
```

### Issue: Slow synchronization

Symptoms:

* Changes take minutes to sync

Causes:

* High polling interval
* Network latency
* MySQL performance issues

Solutions:

1. Reduce polling interval:

```yaml
changePollingIntervalSeconds: 5
```

2. Check network latency:

```bash
ping <mysql-host>
```

3. Optimize MySQL:

```sql
OPTIMIZE TABLE announcements;
OPTIMIZE TABLE announcement_changelog;
```

### Issue: MySQL connection errors

Symptoms:

* "Failed to connect to MySQL" in console

Solutions:

1. Verify credentials:

```bash
mysql -h <host> -u <username> -p<password> <database>
```

2. Check firewall:

```bash
telnet <mysql-host> 3306
```

3. Verify MySQL user permissions:

```sql
SHOW GRANTS FOR 'announcegui'@'%';
```

4. Check MySQL max connections:

```sql
SHOW VARIABLES LIKE 'max_connections';
```

### Issue: Duplicate announcements

Symptoms:

* Same announcement appears multiple times

Causes:

* Duplicate server IDs
* Import with duplicate IDs

Solutions:

1. Verify unique server IDs: Each server must have different `localServerId`
2. Clean database:

{% code title="Find duplicates" %}

```sql
-- Backup first!
-- Then check for duplicates
SELECT id, name, COUNT(*) 
FROM announcements 
GROUP BY id, name 
HAVING COUNT(*) > 1;
```

{% endcode %}

### Issue: Server-specific announcements not working

Symptoms:

* Announcement targeting "survival" shows on all servers

Solutions:

1. Verify target: Check announcement target is correct
2. Verify localServerId: Check each server's `localServerId`
3. Check database: Verify stored `targetServerId` in database

## 📋 Best Practices

{% stepper %}
{% step %}

### Consistent Configuration

Keep configs synchronized:

* Same server list across all servers
* Same MySQL credentials
* Consistent polling intervals
  {% endstep %}

{% step %}

### Document Server IDs

Maintain a document listing:

* Server ID → Server name → IP/hostname

Example:

```
lobby → Lobby Server → mc1.example.com
survival → Survival Server → mc2.example.com
```

{% endstep %}

{% step %}

### Test Before Production

Set up test environment:

* Test MySQL setup
* Test synchronization
* Test failover
* Then deploy to production
  {% endstep %}

{% step %}

### Monitor Sync Delays

Track how long sync takes:

* Create test announcement
* Note time
* Check other servers
* Adjust polling interval if needed
  {% endstep %}

{% step %}

### Secure MySQL

* Use strong passwords
* Limit user privileges
* Enable SSL if over internet
* Use firewall rules
* Regular security audits
  {% endstep %}

{% step %}

### Regular Backups

Backup strategy:

* Daily automated MySQL backups
* Weekly full backups
* Keep backups for 30 days
* Test restore process
  {% endstep %}

{% step %}

### Naming Conventions

Use clear server IDs:

```
✅ Good: lobby, survival, creative, skyblock
❌ Bad: server1, srv2, test, abc
```

{% endstep %}
{% endstepper %}

***

Related Documentation:

* [Configuration Guide](broken://pages/3aa20ca553281475fad1f738d6cbe4547b271ccf) - Detailed configuration
* [Installation Guide](broken://pages/7521abbcbfb74c45ea1aa1f2c6fc7a09e5c39857) - Installation steps
* [Troubleshooting](broken://pages/9f1a1d228bfdd617bed831437a6e97548140d368) - Common issues
* [Features Guide](broken://pages/37dcc4ce354262fb13b77a2a8a4646bed3b890c0) - Feature overview


---

# Agent Instructions
This documentation is published with GitBook. GitBook is the documentation platform designed so that both humans and AI agents can read, navigate, and reason over technical content effectively. Learn more at gitbook.com.

## Querying This Documentation
If you need additional information that is not directly available in this page, you can query the documentation dynamically by asking a question.

Perform an HTTP GET request on the current page URL with the `ask` query parameter:

```
GET https://announcementgui.meteordevelopments.com/multi-server-setup.md?ask=<question>
```

The question should be specific, self-contained, and written in natural language.
The response will contain a direct answer to the question and relevant excerpts and sources from the documentation.

Use this mechanism when the answer is not explicitly present in the current page, you need clarification or additional context, or you want to retrieve related documentation sections.
