I ran Pterodactyl for two years on a customer box at the day job. Two physical machines, around forty game servers, mostly Minecraft and a long tail of "can you spin me up a Valheim real quick" requests. It worked. It was also clearly slowing down — issues piling up, releases getting rarer, and at some point last year it became official: Pterodactyl Panel 1.x stays in maintenance mode, no 2.x is coming.

Around the same time the core developers forked it and started over as Pelican Panel. Same MIT license, same general shape (Panel + Wings daemon + Docker eggs), but a much cleaner stack underneath. I migrated my home box first, then the customer node a few weeks later. No regrets.

This is the ten-minute version, before I forget it.

TL;DR

# On a fresh Ubuntu 24.04 box, with Docker already installed:
mkdir -p /opt/pelican && cd /opt/pelican
curl -fsSL https://github.com/pelican-dev/panel/releases/latest/download/docker-compose.yml -o docker-compose.yml
docker compose up -d
# Then open http://your-server/installer and walk through it.

That's the whole panel. Wings (the daemon that actually runs game containers) gets installed separately on whatever boxes you want to host servers on — covered below. Numbers and exact URL: check the current Pelican docs, the release artifact name has shifted once already.

Pelican vs Pterodactyl in 30 seconds

  • Same architecture: Panel (web UI + API) on one box, Wings (daemon) on each game host. Eggs are still JSON, mostly drop-in compatible.
  • Different stack under the panel: Pelican uses Filament on top of Laravel 11, which means the admin UI is generated and consistent instead of the bespoke Vue thing Pterodactyl shipped. It feels modern.
  • Simpler install: Pelican ships an installer wizard at /installer and a single-binary-ish Docker image. Pterodactyl wanted you to hand-edit .env, run php artisan migrations, set up queues, redis, supervisor, the works. Pelican does all that for you on first boot.
  • SQLite is a real option for small deployments. Pterodactyl basically required MariaDB + Redis. Pelican will happily run on SQLite for a homelab; switch to MariaDB when you actually need it.
  • Wings is still Wings. They kept the daemon name and the egg format on purpose so migrating doesn't mean throwing out years of community eggs.
  • Active. That's the real one. Issues get answered. Releases ship.

Install Pelican Panel on Ubuntu 24.04 (Docker)

I'm picking the Docker compose path because it's what I run in production now and it's genuinely less painful than the native PHP install. The native path (PHP 8.3, nginx, php-fpm, redis, mariadb, queue worker, scheduler cron) still works if you're allergic to Docker, and the docs cover it — but I've stopped doing it that way.

Prereqs:

sudo mkdir -p /opt/pelican
cd /opt/pelican
sudo curl -fsSL \
  https://github.com/pelican-dev/panel/releases/latest/download/docker-compose.yml \
  -o docker-compose.yml

Open the compose file. You'll want to set a volume for /pelican-data (so SQLite + uploads + config survive container restarts) and pin a port. Defaults bind to :80 on the host, which is fine if the box does nothing else, otherwise change it to :8080 and put nginx in front.

sudo docker compose up -d
sudo docker compose logs -f app

When the container is healthy, hit http://your-server/installer in a browser. The wizard asks you for:

  • DB driver (SQLite for a homelab, MariaDB for "real")
  • Cache/queue driver (file is fine for small, redis for larger)
  • Admin user
  • App URL — set this to the final https://panel.example.com, not the IP, otherwise you'll be regenerating later

For TLS, terminate with nginx + Let's Encrypt in front of the panel container. The reverse-proxy walkthrough is in /nginx-reverse-proxy-setup/; the Pelican-specific bit is just "proxy_pass to whatever port you bound the panel container to, set X-Forwarded-Proto https."

Install Wings (the daemon)

Wings runs on every host that should actually run game servers. Can be the same box as the Panel; can be ten boxes spread across racks. Pelican still ships it as a single Go binary.

# On the Wings host:
sudo mkdir -p /etc/pelican /var/lib/pelican /var/log/pelican
sudo curl -L -o /usr/local/bin/wings \
  "https://github.com/pelican-dev/wings/releases/latest/download/wings_linux_amd64"
sudo chmod +x /usr/local/bin/wings

Docker has to be installed and running on the Wings host — that's how game servers actually get sandboxed. If you don't have it yet, install it the normal way (get.docker.com script or distro packages). Wings talks to the Docker socket.

In the Panel UI: Admin → Nodes → Create Node. Fill in FQDN, ports (default daemon port 8080, SFTP 2022), allocate disk and memory. Once saved, click Configuration on the node and copy the generated YAML to the Wings host:

sudo nano /etc/pelican/config.yml
# paste, save

Run it:

sudo wings --debug

If the panel goes green and SFTP comes up on :2022, kill the foreground process and create a systemd unit (the docs ship one, drop it in /etc/systemd/system/wings.service):

sudo systemctl enable --now wings
sudo systemctl status wings

First node, first server

The eggs are the part that hasn't really changed. From the admin panel: Eggs → Import and grab a Paper egg from the community repo (the pelican-eggs org on GitHub mirrors most of what parkervcp/eggs had for Pterodactyl, and a lot of the old eggs still import cleanly).

Then Servers → Create:

  • Owner: yourself
  • Node: the one you just registered
  • Allocation: pick a free ip:port (e.g. 0.0.0.0:25565)
  • Egg: Paper
  • Memory/CPU/Disk: 4 GB / 200% / 10 GB is a sensible Paper baseline
  • Startup: leave defaults, set MC version to 1.21.4 or whatever you actually want

Hit create. Wings pulls the Java image, downloads the Paper jar, accepts the EULA when you toggle the variable, and you've got a running server in about 90 seconds.

If you want to compare what the panel is doing under the hood against the manual approach, my manual Minecraft Java server on Linux post walks through the same end state without any panel — useful for understanding what Wings is actually doing and what to look at when something breaks.

Migration thoughts if you're on Pterodactyl

I did one in-place migration and one rebuild-from-scratch.

Rebuild-from-scratch is faster. Stand up Pelican on a fresh box, import your eggs, recreate servers, rsync the world files / save directories from the old Wings host into the new server's volume on the new Wings host, fix permissions, done. For forty servers it took me an afternoon.

In-place migration (Pelican now has a migration tool that reads a Pterodactyl database and ports users, nodes, servers, allocations) works but you need to be on a recent Pterodactyl 1.x and you need MariaDB on both sides. I'd only do it if you have hundreds of servers or sensitive user accounts you can't recreate. Otherwise, fresh box.

Either way: read the current Pelican migration docs before starting. The tool has changed twice since release.

Gotchas

Stuff that actually bit me:

  • Egg compatibility is "mostly". Old parkervcp eggs that shell out to weird scripts sometimes assume Pterodactyl-specific env vars. Re-import from pelican-eggs instead of the old repo when there's a Pelican-side fork available. Modded Minecraft (Forge/NeoForge) eggs in particular got cleaned up.
  • Port conflicts on multi-server boxes. Wings allocations are per-IP, and if you've got the panel on :80 and Wings's SFTP on :2022 and twenty Minecraft servers between 2556525585, sooner or later you'll allocate 8080 to a server and Wings will silently refuse to start it. Reserve a clean range in UFW and stick to it.
  • Docker permissions. Wings has to be able to talk to /var/run/docker.sock. If you run Wings as a non-root user, it has to be in the docker group. Symptom: server creates fine, install fails with permission denied while trying to connect to the Docker daemon socket.
  • Reverse-proxy and websockets. The console in the panel uses websockets to Wings on the daemon port. If you're proxying both panel and daemon through nginx, make sure the daemon vhost has proxy_http_version 1.1, Upgrade/Connection headers, and a long proxy_read_timeout (I use 7200s). Without it the console just shows nothing and you'll think Wings is broken. It isn't.
  • Let's Encrypt on the daemon. Wings wants a real cert for the SFTP/daemon endpoint, not just the panel. Easiest path: a separate node1.example.com DNS record, certbot for both, point Wings at the cert files in config.yml.
  • SQLite isn't free. It's fine for a personal box. The moment you have multiple admins clicking around or you cross ~30 servers, switch to MariaDB. The php artisan db:migrate-to-mysql-style tooling exists in the panel, check the docs for the current command name.

Why I switched

Honestly, because Pterodactyl stopped feeling alive and Pelican does. The Filament admin is nicer to look at. The installer wizard means I can stand a panel up in fifteen minutes instead of an hour. SQLite mode means my homelab Pelican isn't running a whole MariaDB just to track three Minecraft servers. And the eggs I care about — Paper, Velocity, Forge, Valheim, Satisfactory — all work.

The day-job side matters too. I don't want to be the guy still running an unmaintained panel in front of customer game servers in 2027. Pelican is the path forward that doesn't involve me writing my own panel, and that's the one I'm picking.

If you're on Pterodactyl right now and it's working fine: no rush. 1.x will keep going for a while. But the next time you spin up a new node, do it on Pelican. You'll save yourself the migration later.


Related posts