Linking Multiple Rust Servers to MySQL via Pterodactyl
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.
CREATE USER 'pterodactyluser'@'%' IDENTIFIED BY 'REPLACE_WITH_LONG_PASSWORD';GRANT ALL PRIVILEGES ON *.* TO 'pterodactyluser'@'%' WITH GRANT OPTION;FLUSH PRIVILEGES;Name: rust-cluster-dbHost: 10.0.0.20Port: 3306Username: pterodactyluserPassword: REPLACE_WITH_LONG_PASSWORDLinked Node: rust-node-01The 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.
Database Name: rustConnections From: %# Panel returns:Database: s1_rustUsername: u1_RandomStringPassword: AutoGeneratedLongStringHost: 10.0.0.20:3306Repeat 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.
{ "MySQL Settings": { "Host": "10.0.0.20", "Port": 3306, "Database": "s1_rust", "Username": "u1_RandomString", "Password": "AutoGeneratedLongString" }, "Server Identity": { "ServerTag": "MAIN", "PollIntervalSeconds": 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.
docker exec -it <container_id> bashapt-get update && apt-get install -y mariadb-clientmariadb -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_sizeto 25 percent of host RAM. The default 128 MB will thrash even for two server clusters. - Index every plugin generated table on
server_tagif your plugins do not do it automatically. Cross server reads degrade quickly past 100k rows without it. - Schedule nightly logical dumps with
mysqldumpand 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.