Hosting Guides

Linking Multiple Rust Servers to MySQL via Pterodactyl

9 min readDebian 12PterodactylUnity
Once your server is online, jump to the Rust command and config reference.

Once a Rust community grows past a single map, players start demanding shared state across servers: a global chat that bridges every map, a unified economy, cross server bans, even shared clan rosters. The Oxide ecosystem has plugins for all of this, and almost every one expects a MySQL backend. Running that MySQL by hand on the host is needless overhead. Pterodactyl already ships a first class database feature that provisions per server credentials against a managed MySQL host, with cleanly scoped users and an audit trail in the panel.

This guide configures the panel side database host, attaches a database to two Rust servers, and walks through wiring a cross server chat plugin so both maps share a unified channel. Everything traverses Docker's internal network, so MySQL never needs to be exposed publicly.

Prerequisites

  • Debian 12 with Pterodactyl Panel and at least one Wings node already operational.
  • An external or co located MySQL 8 instance reachable from the panel host. MariaDB 10.11 also works.
  • Two existing Rust Oxide servers (the Pterodactyl Rust egg with the Oxide variant selected).
  • uMod's cross server plugin of choice, for example BetterChat plus Cross Server Chat.

Step 1: Configure the Database Host in Pterodactyl

Inside the panel admin area, navigate to Databases and add the MySQL host. The panel needs an account with CREATE USER, CREATE DATABASE, and GRANT privileges so it can provision new credentials on demand.

MySQL preparation, run as root on the database host
CREATE USER 'pterodactyluser'@'%' IDENTIFIED BY 'REPLACE_WITH_LONG_PASSWORD';
GRANT ALL PRIVILEGES ON *.* TO 'pterodactyluser'@'%' WITH GRANT OPTION;
FLUSH PRIVILEGES;
Pterodactyl admin, Database Hosts, Create
Name: rust-cluster-db
Host: 10.0.0.20
Port: 3306
Username: pterodactyluser
Password: REPLACE_WITH_LONG_PASSWORD
Linked Node: rust-node-01

The Linked Node field controls which node's network the database is reachable from. Pick the node your Rust servers live on, and Pterodactyl will resolve the host name on the internal Docker network instead of routing back over the public IP.

Step 2: Provision Databases on Both Rust Servers

Open the first Rust server in the panel, switch to the Databases tab, and click New Database. Pterodactyl creates a database named like s1_rust and a per server user with full rights inside that schema only.

Pterodactyl server, Databases tab
Database Name: rust
Connections From: %
# Panel returns:
Database: s1_rust
Username: u1_RandomString
Password: AutoGeneratedLongString
Host: 10.0.0.20:3306

Repeat the process on the second Rust server. Both servers will now have their own dedicated MySQL accounts, but they point at the same MySQL host. We will reuse the first server's database from the second server, so copy the s1_rust credentials somewhere safe.

Step 3: Install Oxide Plugins

Drop the cross server chat plugin into oxide/plugins/ on both servers via SFTP. The plugin reads its database credentials from oxide/config/CrossServerChat.json, which is generated on first load.

oxide/config/CrossServerChat.json on server 1
{
"MySQL Settings": {
"Host": "10.0.0.20",
"Port": 3306,
"Database": "s1_rust",
"Username": "u1_RandomString",
"Password": "AutoGeneratedLongString"
},
"Server Identity": {
"ServerTag": "MAIN",
"PollIntervalSeconds": 2
}
}
oxide/config/CrossServerChat.json on server 2
{
"MySQL Settings": {
"Host": "10.0.0.20",
"Port": 3306,
"Database": "s1_rust",
"Username": "u1_RandomString",
"Password": "AutoGeneratedLongString"
},
"Server Identity": {
"ServerTag": "EVENT",
"PollIntervalSeconds": 2
}
}

Both servers now read and write into the same s1_rust schema, but each tags its outbound messages with a different identifier so players can see which map a chat line originated on. The plugin auto creates its tables on first boot, so no SQL needs to be applied by hand.

Step 4: Verify the Network Path

Wings runs every game server inside a Docker network. The cleanest verification is to exec into the running container and confirm MySQL is reachable on the internal address, which catches firewall mistakes before they cost you a wipe night.

root@rust-node-01
docker exec -it <container_id> bash
apt-get update && apt-get install -y mariadb-client
mariadb -h 10.0.0.20 -P 3306 -u u1_RandomString -p s1_rust -e "SHOW TABLES;"

A successful response (even an empty table list) confirms the credentials work and the network path is open. If the connection times out, the database host's bind address is restricted to localhost. Edit /etc/mysql/mariadb.conf.d/50-server.cnf and set bind-address = 0.0.0.0, then restart MySQL.

Performance and Tuning

  • Co locate MySQL on the same node as the Rust servers. Cross node MySQL adds 1 to 3 ms per query, which is noticeable for chat polling at 2 Hz.
  • Set innodb_buffer_pool_size to 25 percent of host RAM. The default 128 MB will thrash even for two server clusters.
  • Index every plugin generated table on server_tag if your plugins do not do it automatically. Cross server reads degrade quickly past 100k rows without it.
  • Schedule nightly logical dumps with mysqldump and ship them offsite. Plugin schemas are easy to recreate, but historical chat and economy data is not.

Conclusion

Pterodactyl's database feature collapses what used to be a manual MySQL provisioning chore into a single panel click, and pointing multiple Rust servers at the same schema unlocks the entire cross server plugin ecosystem (chat, economy, bans, clan rosters, leaderboards). Lean on the internal Docker network for everything, keep MySQL off the public internet, and your cluster scales horizontally by adding new Rust eggs that point at the same backend.