Author: Smithesis

  • Building a Real Backup System for My Gaming Server

    Building a Real Backup System for My Gaming Server

    Running your own server is fun right up until you start thinking about everything that could disappear if something goes wrong.

    My DigitalOcean VPS now hosts several services that I’ve put a fair amount of time into: Minecraft, Valheim, Core Keeper, Foundry VTT, the Smithesis Gaming Hub WordPress site, and the Pterodactyl game-server management system itself.

    DigitalOcean’s automated backups gave me some protection, but as the server became more important, I wanted something I had more control over—and something I could actually test.

    So I built my own automated backup system using Restic and Backblaze B2.

    What I Wanted From the Backup System

    My goals were fairly simple.

    I wanted backups to happen automatically every night, without requiring me to remember to do anything. I wanted those backups stored somewhere other than the VPS itself. I wanted multiple recovery points without storing a complete duplicate of the server every night.

    Most importantly, I wanted to know that I could actually restore something.

    A backup that has never been tested is really just a theory.

    Why Restic and Backblaze B2?

    I settled on Restic as the backup software and Backblaze B2 as the off-site storage.

    Restic handles encryption, compression, deduplication, snapshots, and retention. B2 provides inexpensive object storage somewhere completely separate from my DigitalOcean server.

    That separation is important. If the VPS disappears entirely, the backups don’t disappear with it.

    Restic’s deduplication was another major attraction. My first backup processed roughly 5.25 GiB of data, but only about 2.23 GiB needed to be stored after compression and deduplication.

    The following night’s backup created another complete snapshot—but the repository grew by only about 25 MiB.

    Instead of uploading another copy of everything, Restic reused the data it already had and uploaded only the new or changed pieces.

    Deciding What Actually Needed Backing Up

    I didn’t simply point Restic at / and call it a day.

    A lot of what’s on the VPS can be recreated. Docker images can be downloaded again. Game-server binaries can be reinstalled. Ubuntu itself can be rebuilt.

    The important pieces are the things that are mine.

    That includes my Minecraft worlds and configuration, the Valheim world, Core Keeper saves, Foundry VTT data, WordPress site and database, Pterodactyl database and configuration, Caddy configuration, and important systemd service definitions.

    That makes the backups smaller while concentrating on the data that would actually hurt to lose.

    Backing Up Live Game Servers

    Game servers presented an interesting problem.

    Copying a save file while the game is actively writing to it isn’t ideal. I wanted the backups to capture a clean, consistent state.

    So the backup script does more than just run Restic.

    Before the backup begins, it checks the state of the game servers through Pterodactyl. It then gracefully stops Minecraft, Valheim, and Core Keeper. Foundry VTT is stopped as well.

    Database dumps are created for services such as WordPress and Pterodactyl, and the relevant files are staged for backup.

    Restic then creates the snapshot and sends the new data to Backblaze B2.

    When that’s finished, the script brings everything back online and verifies that the services are running again.

    The whole process happens automatically in the middle of the night.

    Letting systemd Handle the Schedule

    Rather than adding another application just to schedule the backups, I used systemd timers.

    Every night at 4:00 AM, systemd launches the backup service.

    I also configured a separate maintenance job for Sunday at 6:00 AM. That job performs Restic repository maintenance and runs an integrity check against the backups.

    The retention policy currently keeps:

    • 7 daily snapshots
    • 4 weekly snapshots
    • 6 monthly snapshots

    That gives me useful historical recovery points without allowing storage usage to grow indefinitely.

    Then I Tried to Break It

    Configuring backups wasn’t enough.

    I wanted proof that I could get the data back.

    After the first backup completed, I deliberately restored my Caddy configuration from Backblaze B2 to a temporary location. I then compared the restored file against the live copy.

    They were identical.

    That small test was probably the most important part of the entire project.

    It proved the chain actually worked:

    VPS → Restic → Backblaze B2 → Restic restore → usable file

    The First Unattended Backup

    The next test was doing absolutely nothing.

    I left the server alone overnight and checked it the following morning.

    At 4:00 AM, systemd triggered the backup automatically. The backup completed successfully, and Foundry VTT, Core Keeper, Valheim, and Minecraft were all restored to their running state.

    A new Restic snapshot appeared in B2.

    Then at 6:00 AM, the weekly maintenance task ran automatically. Restic pruned the repository and checked both existing snapshots.

    The result:

    No errors were found.

    At that point, I was comfortable calling the new backup system operational.

    An Unexpected Bonus: It Costs Less

    There was also a financial benefit.

    DigitalOcean’s automatic backup service was contributing substantially to my monthly infrastructure costs. After validating the new system, I created one final DigitalOcean snapshot and disabled the recurring backup service.

    I’ll continue keeping at least one DigitalOcean snapshot because it’s useful as a complete machine-level recovery point. I’ll also create additional snapshots manually before major server changes.

    But my everyday backups are now handled by Restic and B2.

    That change dropped my backup-related costs from roughly $17 per month to less than $5 per month.

    More importantly, I now have considerably more control over what gets backed up, how long it’s retained, and whether it can actually be restored.

    Backups vs. Snapshots

    I’ve ended up with two complementary layers of protection.

    Restic + Backblaze B2 handles the routine stuff. It’s automated, off-site, encrypted, deduplicated, versioned, and regularly checked.

    DigitalOcean snapshots are occasional whole-server checkpoints. I’ll create one before particularly significant infrastructure changes or upgrades.

    If I accidentally delete a Minecraft world, I don’t need to restore an entire VPS.

    If I completely destroy the server while experimenting with something, the DigitalOcean snapshot gives me another option.

    What I Learned

    The biggest lesson wasn’t really about Restic or Backblaze.

    It was that creating a backup isn’t the same thing as having a backup strategy.

    A useful backup system needs to answer several questions:

    What am I protecting?

    Where is it stored?

    How often is it backed up?

    How many versions do I keep?

    What happens if a backup fails?

    And, most importantly:

    Can I actually restore it?

    For the Smithesis Gaming Server, I can finally answer that last question with a tested yes.

  • Building the Smithesis Gaming Server

    Building the Smithesis Gaming Server

    Disclosure: Much of this work has been supported by ChatGPT (including this blog post). I can say I am seriously impressed at how well it works, especially how well it collaborates with me to accomplish the tasks that I want to achieve.

    When I first spun up this server, the idea was pretty simple: I wanted somewhere I could host game servers for myself and friends.

    It didn’t take very long for that idea to grow.

    Over the past several days, I’ve been turning a DigitalOcean VPS into the foundation for what I’m calling the Smithesis Gaming Hub—a place where I can host different games, experiment with self-hosting, and learn a lot more about Linux, Docker, networking, and server administration along the way.

    The basic infrastructure is finally in place, so this seems like a good time to document where things stand.

    The Hardware

    Everything currently runs on a DigitalOcean VPS with:

    • 4 AMD vCPUs
    • 8 GB of RAM
    • 160 GB of NVMe storage
    • Ubuntu Server 24.04 LTS

    Eight gigabytes of memory obviously puts a limit on how many large game servers I can run simultaneously, but it’s surprisingly capable for what I’m doing right now.

    If the project continues to grow, moving to 16 GB is an easy upgrade—and would give me considerably more room to experiment.

    Bringing Everything Under Pterodactyl

    One of the biggest improvements I’ve made is installing Pterodactyl to manage the game servers.

    Before that, the servers were a mixture of native Linux services, LinuxGSM installations, and command-line management. It worked, but every game was effectively its own little administration project.

    Pterodactyl gives me one web interface where I can manage all of them.

    Behind the scenes, Pterodactyl Wings manages Docker containers for each game server. That gives me a much cleaner architecture:

    Pterodactyl → Wings → Docker → Game Servers

    Each game gets its own isolated environment while still sharing the resources of the VPS.

    More importantly, I now have one place to start and stop servers, watch their consoles, manage files, adjust resource limits, and deploy new games.

    Minecraft Bedrock

    The first server migrated into Pterodactyl was Minecraft Bedrock.

    Minecraft was already running on the VPS, so this wasn’t a fresh installation. I backed up the existing server and world, created a new Bedrock instance through Pterodactyl, moved the existing data into it, and verified that everything survived the migration.

    Once I could connect and confirm that the world was intact, the old native service was disabled.

    Minecraft currently has 2 GB of RAM available to it, which should be plenty for the relatively small server I’m planning to run.

    Valheim

    Next came Valheim.

    Our Valheim world is called Caledonia, and it also survived the move into Pterodactyl.

    The server uses Valheim’s crossplay support and currently has 3 GB of RAM allocated to it. Like Minecraft, the original installation has been retained as a rollback copy but is no longer running.

    Keeping those old installations around temporarily has been part of my approach to the migration: don’t destroy the known-good version until I’m confident the replacement works.

    Core Keeper—and Fewer Open Ports

    Core Keeper ended up being one of the more interesting migrations.

    Our world is called Degobah, and I’ve allocated 2 GB of RAM to the server.

    But the interesting part isn’t really the memory allocation—it’s how players connect.

    Core Keeper supports Steam Datagram Relay, or SDR. Instead of requiring players to connect directly to an exposed game port on my VPS, the server can establish itself through Steam’s relay infrastructure and players connect using a permanent Game ID.

    After configuring and testing that setup—including making sure the world persisted properly across server restarts—I removed Core Keeper’s inbound game ports from the DigitalOcean firewall entirely.

    Players can still connect, but those ports no longer need to be exposed to the public Internet.

    That’s a philosophy I’d like to follow throughout this project:

    If a service doesn’t need to be exposed to the Internet, don’t expose it.

    It’s More Than a Game Server Now

    The VPS has also gradually accumulated some other responsibilities.

    I run Foundry Virtual Tabletop on it for tabletop RPG games. Foundry currently lives outside Pterodactyl and runs under its own Linux account with PM2 managing the process.

    Then there’s the website you’re reading right now.

    Smithesis Gaming Hub runs on WordPress in Docker, with its own MariaDB database.

    Caddy acts as the reverse proxy in front of the web services and handles HTTPS, allowing several different applications to coexist on the same machine under their own domains and subdomains.

    So what started as a machine for running a game server is now hosting the game servers, their management infrastructure, a virtual tabletop, and the website documenting the whole project.

    I’m okay with where this is going.

    Connecting the Website to the Game Servers

    This is probably my favorite addition so far.

    I wanted Smithesis Gaming Hub to be more than a blog about the servers. I wanted the website to actually know what was happening on them.

    So I created a small custom WordPress plugin that connects to the Pterodactyl API.

    The new Server Status page displays Minecraft Bedrock, Valheim, and Core Keeper and shows whether each server is currently online.

    And these aren’t just decorative green dots.

    When I stop a server in Pterodactyl, the website detects the actual change in server state and changes its status to Offline. Start it again, and the website returns it to Online.

    I tested the entire process in both directions.

    The integration is also entirely server-side. The API credentials aren’t sent to visitors’ browsers, and the results are briefly cached so that every page view doesn’t generate a pile of unnecessary API requests.

    An API failure is treated separately as Unknown, rather than incorrectly telling visitors that a game server is offline.

    It even works with Core Keeper despite the fact that its game ports aren’t publicly accessible, because WordPress is asking Pterodactyl for the server’s actual state rather than trying to probe an Internet-facing port.

    It’s a fairly small feature, but it represents where I’d like to take the site.

    Smithesis Gaming Hub isn’t just documenting the gaming server. It’s becoming the public-facing side of it.

    Where Things Stand

    At this point, three game servers have been migrated successfully:

    Minecraft Bedrock is running.

    Valheim is running.

    Core Keeper is running.

    They’re centrally managed through Pterodactyl, isolated in Docker containers, and operating behind a firewall that I’m trying to keep as restrictive as practical.

    The old installations have been retained for now as rollback copies rather than immediately deleting them.

    And Smithesis Gaming Hub can now communicate with the infrastructure and report the actual status of the servers.

    That’s a pretty solid foundation.

    What’s Next?

    There’s still plenty I want to do.

    The Server Status page is only at version one. I’d eventually like to explore displaying things like player counts, uptime, server information, and connection instructions, depending on what each game makes available.

    I’m also looking at better monitoring for the VPS itself and want to do a complete audit of every listening service against the DigitalOcean firewall.

    Then, of course, there are more games.

    One of the advantages of having Pterodactyl in place is that experimenting with another dedicated server no longer means building an entirely new management setup from scratch.

    And if 8 GB of RAM eventually becomes the limiting factor, there’s always that tempting 16 GB upgrade button waiting for me.

    For now, though, the foundation of the Smithesis Gaming Hub is officially up and running.

    And I suspect I’m just getting started.

  • Test Post

    This is just a test post. 🙂