TPTito Pinardo Gutiérrez
← Back to the rack
Español
1U · GAMESAMP · Velocity · mirrored ZFS In production

Slot 11 of 25 in the rack · In production

1U unit · Community

AMP · game servers

Writes ×8.8 without buying hardware

Modded Minecraft, other Minecraft worlds behind a proxy and Steam games for friends, managed from a panel. What's open to the internet depends on what's running: starting a server creates its router rule and its name on Cloudflare, and 3 minutes after it stops they're gone.

Why so much care
It's the only part of the homelab with game ports open to the internet. The fewer and the shorter, the better.
How Minecraft players get in
All through one port, that of a proxy that picks the world based on the name you join with.
Performance
The disks shipped with write cache off, the CPU was split across two processors and Java was badly tuned. All fixed without spending.
  • 108 → 946writes per second with fsync
  • 1 minfor router and DNS to open on start
  • 3 minstopped before they close
  • 17 daysof empty backups nobody had noticed

Its code, in the open Public version of the repo: no IPs or secrets.

Inside the game servers

Starting a server in the panel opens the router and DNS on its own; stopping it closes them. Pick a flow.

Hermesvisiting the unit

Click a part or pick a flow. If you came from a skill, the parts where I use it are already lit.

      I start a server
      1. AMP panel — I start a server from the panel.
      2. Instance manager — The manager starts its container.
      3. Modded Minecraft — The server loads the world.
      4. Automatic publisher — A minute later, the publisher sees it's running.
      5. Router — It creates its rule on the router, with only the game ports: no console or admin.
      6. Automatic publisher — And its name…
      7. Cloudflare DNS — …on Cloudflare.
      8. Friends — A friend types that name in the game.
      9. Router — They come in through the router.
      10. Minecraft proxy — The proxy looks at the name and sends them to their world.
      11. Modded Minecraft — They're in.
      I stop it
      1. AMP panel — I stop the server in the panel.
      2. Instance manager — The manager stops its container.
      3. Automatic publisher — The publisher waits 3 minutes, in case it's a restart.
      4. Router — It removes the router rule.
      5. Cloudflare DNS — And the Cloudflare name. Nothing is left open.
      A game session
      1. Friends — A player connects.
      2. Router — They come in through the router.
      3. Container firewall — They pass the container firewall, which only allows declared ports.
      4. Minecraft proxy — The proxy sends them to their world.
      5. Modded Minecraft — The server saves the world every so often.
      6. Four mirrored disks — Writes go to the disk mirror, now with cache: 8.8 times faster.
      7. ZFS cache in RAM — Reads almost always come from the RAM cache.
      8. Modded Minecraft — The server answers.
      9. Minecraft proxy — Through the proxy, which compresses just once.
      10. Friends — And to the player.
      Friends check Discord to see what's up
      1. AMP panel — The panel knows which servers are running and how many people are on each.
      2. Status bot — The bot asks it every so often, with a read-only user over the internal network.
      3. Discord — In the Discord channel each server has its own message: on or off, who's in, the address and its cover art. The bot edits it when something changes, without flooding the channel.
      4. Friends — A friend sees people playing and fancies joining.
      5. Discord — The message title links to the server's page to connect directly or copy the address; if that page won't work, to the website.
      6. Router — They come in through the router, which has that port open because the server is running.
      7. Minecraft proxy — And the proxy takes them to their world.
      A new server shows up on the site and on Discord
      1. AMP panel — In the AMP panel I give a server its public address.
      2. Status bot — The bot sees it on its next check: address, game, cover art and the Steam button come from what AMP already knows.
      3. Public servers site — The server appears on its own on the public site, in its section (Minecraft, games with several servers, Steam or others). No Discord message yet.
      4. Bot admin panel — In the bot's panel, only from home or the VPN with two-factor, it shows up under «Published from AMP» with an «Add to bot» button.
      5. Status bot — Adding it registers it in the bot: if I set my own address or cover art, they override AMP's.
      6. Discord — And it starts posting its status message in the Discord channel.
      7. Public servers site — On the site the server now has its full card: «Copy» the address and «Connect with Steam».
      8. Friends — Friends find it on the site or on Discord, without me having to tell anyone.
      A power cut
      1. Hypervisor — The power goes and the server switches off abruptly.
      2. Users file — AMP was writing its users file: it's left empty.
      3. Backup every 30 minutes — But it was copied every 30 minutes from outside the container.
      4. Check the backup — The last valid copy (not empty, real JSON) is found automatically.
      5. Users file — It's restored with the panel stopped.
      6. AMP panel — And the panel comes back with every account.
      1. Friends

        From their homes, using the server's name.

      2. Router

        Only has the ports of running servers open, with rules created by the automation.

        • MikroTik
      3. Cloudflare DNS

        One name per server, which only exists while it's running. No proxy: games don't speak HTTP.

      4. Automatic publisher

        Every minute it asks the panel what's running and adjusts router and DNS. On the router it can only touch its own rules.

        • Python
        • MikroTik
      5. Discord

        A channel where each server has its status message: on or off, who's in, the address and the link to join.

      6. Public servers site

        A single page with the servers live, grouped by game, with «Copy» and «Connect with Steam», who's on Discord and the rules. It doesn't link to the AMP panel.

        • JavaScript / TypeScript
      7. Bot admin panel

        Only from home or the VPN, behind the internal door with two-factor. This is where servers AMP already publishes get registered and how they show up gets edited.

        • Linux / SSH hardening
      8. Hypervisor

        Power cuts included: with no UPS, the server switches off abruptly.

        • Proxmox VE
        • ZFS
      9. Minecraft proxy

        One port for every Minecraft world: depending on the name you join with, it sends you to one world or another.

      10. Container firewall

        Inbound blocked except declared ports. The panel syncs them every five minutes; the panel and SSH, only from home.

        • Linux / SSH hardening
      11. AMP panel

        Where servers are started, stopped and configured. No longer published on the internet.

        • Docker
      12. Status bot

        Reads the panel with an unprivileged user and keeps the Discord messages and the public site up to date.

        • JavaScript / TypeScript
        • Docker
      13. Modded Minecraft

        The main server, with almost ninety mods, several of them for performance.

        • Docker
      14. Other Minecraft worlds

        Smaller worlds, behind the same proxy.

        • Docker
      15. Steam games

        Dedicated servers that start when someone wants to play.

        • Docker
      16. Instance manager

        Each server is its own Docker container. The manager starts, stops and updates them.

        • Linux (Debian, Alpine, Arch)
      17. Four mirrored disks

        They came with write cache off. Turned on and saved on the disk itself: fsync writes, from 108 to 946 per second.

        • ZFS
        • Linux (Debian, Alpine, Arch)
      18. CPU on a single processor

        The hypervisor gave threads from both processors: Java had its memory on one and its work on the other. Now the container uses six cores of a single one.

        • Proxmox VE
        • LXC
      19. Tuned Java

        Memory reserved from start-up, huge pages and no forced clean-ups every 5 seconds. Compression only once: at the proxy.

      20. ZFS cache in RAM

        It already served over 98 % of reads: no need to touch it.

        • ZFS
      21. Users file

        Where AMP keeps accounts and permissions. With a power cut mid-write, it ends up empty.

      22. Backup every 30 minutes

        From the hypervisor, outside the container, the last 100 versions.

        • Linux (Debian, Alpine, Arch)
      23. Check the backup

        An empty or «{}» copy doesn't count as a backup: the script rejects it and warns.

        • Linux (Debian, Alpine, Arch)
      24. Monitoring

        Watches the container and the servers' processes.

        • Zabbix

      What I use from my skill tree

      Pick a skill: the parts where I use it light up on the map and I tell you what for.

      Terraform
      Creates the AMP container; CPU pinning is noted because Terraform can't see it.
      Proxmox VE
      CPU pinned to one processor, more memory live, and backups of the users file from the hypervisor.
      LXC
      AMP runs in its own container, with game data mounted from the ZFS pool.
      ZFS
      A four-disk mirror for the worlds, compression and RAM cache with over 98 % hits.
      Docker
      Each game server and the panel in its own container, plus the status bot.
      Linux (Debian, Alpine, Arch)
      Disk write cache, I/O scheduler, cron with the right PATH and verified backups.
      MikroTik
      Inbound rules created and deleted by the automation based on what's running.
      Zabbix
      Watches the container and its processes.
      Linux / SSH hardening
      Firewall blocking inbound, panel and SSH only from home, no UPnP and ports open only while needed.
      Python
      The publisher that syncs panel, router and DNS every minute.
      JavaScript / TypeScript
      The bot that posts the servers' status, in Node.js.

      Incident log

      Real failures. Read the symptom, pick the cause you think it was and see how it was fixed.

      1. #1

        «No such user» after a power cut

        16-07-2026 · panel

        After a power cut I couldn't log into the panel: «No such user». Neither could the status bot, which retried thousands of times a day.

        What do you think was going on?

        Show the fix
        Cause
        AMP doesn't write its users file atomically. A shutdown halfway leaves it as «{}», and its own rotating copy fell in the same window. It's a known AMP bug.
        Fix
        Recreate the accounts, plus a backup every 30 minutes from the hypervisor, outside the container, keeping the last 100 versions.
        Lesson
        Without a UPS, anything that writes carelessly is a risk. The backup has to live outside what breaks.
      2. #2

        A backup that had never backed up

        02-08-2026 · backups

        Another cut and the file was empty again. I went to restore the backup… and 17 days of backups were all 0 bytes.

        What do you think was going on?

        Show the fix
        Cause
        The script used a Proxmox command living in a folder that cron's minimal PATH doesn't include. It failed on every run since day one, silently, and the script accepted any output as good.
        Fix
        Absolute paths, a test with cron's real PATH and a check that each copy is real JSON: if it's empty or «{}», it's discarded and a warning is raised.
        Lesson
        An untested backup isn't a backup. Test it the way the system will run it, not the way I run it.
      3. #3

        Slow disks for no obvious reason

        06-10-2026 · performance

        Saving the world was slow and fsync writes topped out at 108 per second on a four-disk mirror.

        What do you think was going on?

        Show the fix
        Cause
        These SAS disks come with write cache disabled. Every write waited for the platter.
        Fix
        Turn it on and save it on the disk itself, with the «none» scheduler since ZFS already orders I/O. Safe with power cuts: ZFS flushes the cache on every transaction. From 108 to 946 fsync writes per second.
        Lesson
        Measure before buying. And note that a replacement disk will come with the cache off again.
      4. #4

        No network on every boot, and the backup didn't fix it

        17-10-2026 · AMP

        After a restart, the games container came up with no network. Restoring last night's backup changed nothing: it booted without network again.

        What do you think was going on?

        Show the fix
        Cause
        At boot, the internal firewall found leftovers from a previous run, only emptied them, half-failed and left all incoming traffic on «deny». It happened on every boot, which is why the backup didn't help.
        Fix
        Before starting, the firewall is wiped clean and retries if it fails. Tested with a real restart.
        Lesson
        If restoring doesn't fix something, the fault isn't in the data but in how it starts.
      5. #5

        A deployment took away a third of its memory

        18-10-2026 · Terraform

        Right after a deployment, the game panel died from lack of memory.

        What do you think was going on?

        Show the fix
        Cause
        I'd raised the container's memory by hand, live, without changing the code. The next deployment saw the difference, undid it and restarted the container, and the panel didn't fit in what was left.
        Fix
        Memory is taken out of Terraform for every container: it's changed live and the code stays as a record. Growing a disk with Terraform was already live.
        Lesson
        What you change by hand without the code knowing, the code undoes. Either everything in code, or out of code on purpose.

      Told in full in an article:

      How it was built

      1. Summer 2026

        The first servers

        • AMP with one Docker instance per game and a proxy for every Minecraft world.
        • Backups of the users file after the first cut, and their fix when they turned out empty.
      2. September 2026

        Firewall and migration

        • Container firewall blocking inbound, with ports synced by the panel.
        • A new container managed with Terraform.
      3. October 2026

        Performance and automatic opening

        • Write cache, CPU on one processor, Java and compression tuned.
        • Router and DNS that open and close by themselves based on what's running.
        • Panel and the bot's admin off the internet.
      4. 17 and 18-10-2026

        More isolated, more robust

        • In the DMZ, apart from the home network.
        • An internal firewall that always starts from scratch.
        • Custom plugins for the server network, with their own CI testing them against real servers. In development: not in production yet.

      Decisions (and why)

      • What gets opened

        Only what's running, and only its game ports

        An open port for a stopped server adds nothing and is surface. Console and admin are never opened.

      • How to improve without buying

        Measure first

        The CPU is what it is and a Minecraft server depends on a single thread. But the disks, the split across processors and Java had room, measured before and after with fio.

      • What the automation touches on the router

        Only its own rules

        The router user the publisher uses can only create and delete rules with its prefix. If it failed, it couldn't break the rest of the firewall.

      What I learned

      • Test backups by restoring them, and with cron's real environment.
      • Open ports based on what's running, not just in case.
      • Measure before thinking about buying.

      What's next

      • A UPS: the only thing that truly prevents shutdowns mid-write.
      • An SSD for the main world and pre-generating the map.

      Shall we talk?

      I can walk through any of these decisions in detail in an interview.

      Download CV Get in touch ← Back to the rack

      Rebuilt from my documentation: no domains, server names, ports or addresses.