Self-hosted service
pelican/panel avatar
pelican/panel

Pelican Panel's production image builds from a base image at localhost:5000

Free, open source game server management panel built on Laravel and Docker.

2,431 stars324 forksPHPAGPL-3.0

At a glance

What is it?
A game server control panel that positions itself as a modern alternative in the Pterodactyl ecosystem, running each server in its own container through a separate daemon. The packaging tells you what to expect: three compose files, three Dockerfiles, a browser installer, and a build that needs a base image you cannot pull.
Who is it for?
Pelican Panel fits a community, a host or a self hoster who wants Pterodactyl shaped tooling without Pterodactyl, and who is comfortable running a panel that holds a daemon with root level access to game servers. Four things to check before you deploy one.
Can I use it commercially?
Yes, with strict conditions. AGPL-3.0 is a network copyleft licence: if people use a modified version over a network, for example as a hosted service, you must offer them its source code under the same licence.
Is it still maintained?
Yes. The repository received new commits within the last day.
What is it written in?
Mainly PHP, according to GitHub's language statistics.

Answers come from the project's GitHub data, last synced on November 14, 2026, and from our analysis. They are not legal advice.

From daily snapshots

Star history

  • pelican/panel2,431 ★ · +121
Star history
Repository2026-09-112026-11-14
pelican/panel2.3k2.4k

121 Stars in the last 64 days, measured from the daily GitHub snapshot. Compare with other projects

Editorial analysis

The egg catalogue includes Elasticsearch, Grafana and S3

The list of supported software is the first thing to read, because it is longer than the list of games and describes a different product than the name suggests.

There is a Minecraft category with the usual server software and two proxies. There is a SteamCMD category with a dozen titles. There is a standalone games category, a Discord bot category with three bots, and a voice server category with three servers.

Then there are four categories that are not games at all. Software: Elasticsearch, Gitea, Grafana and RabbitMQ. Programming: Node.js, Python, Java and C#. Databases: Redis, MariaDB, PostgreSQL and MongoDB. Storage: S3 and an SFTP share. Monitoring: Prometheus and Loki.

So the panel provisions Elasticsearch and Grafana and PostgreSQL and S3 through exactly the interface it uses for a Minecraft server, using the same template concept, called an egg, with its own repository per category. That is either a strength or a hazard depending on what you are installing.

As a strength, it means one panel can run a game's server, the database behind a community's website, and the monitoring stack around both, with one interface and one set of backups.

As a hazard, it means the panel is a general purpose container orchestration tool with root level control, presented through vocabulary that suggests game servers. The permission model, the resource limits, the network isolation and the update behaviour are all container level concerns, and a database with your community's data behind them deserves the same scrutiny as the game server would get, plus more.

The category list is also the best available map of what the project actually supports, and it is maintained separately as several repositories rather than in this one.

The production image pulls its base from a registry on localhost

The production Dockerfile cannot be built from a public registry, and the file says so without quite saying it.

Every stage inherits from a base image addressed as a path on a local registry, with the architecture appended. The composer stage, the composer build stage and the final application stage all reference it that way.

That is a private base image, held somewhere this repository does not describe. Anyone who clones the project and runs the documented build will fail at the first FROM line, because that name resolves to the machine they are standing on.

The comment at the top of the file answers the question before you ask it: if you want to build this locally you want to build from the development Dockerfile instead. So there is a supported local path and an unsupported production path in the same file, distinguished by which file you pass on the command line.

This matters for the compose file too, because the service definition carries both an image reference to the published container and a build context pointing at this directory. A person who edits the compose file to build from source, or who runs a compose command that triggers the build, hits the missing base image immediately. The published image is the intended route; the build is for the people who have the base image.

Two other details in that file are worth naming. The syntax directive asks for a labelled Dockerfile version that supports the copy exclusions used later in the file, so the build needs a recent and somewhat experimental builder. And the frontend stage runs an install with a frozen lockfile and a five minute network timeout raised, which is the project telling you that its JavaScript dependency tree is slow to fetch.

Ports 80 and 443 by default, with the proxy options commented out

The compose file publishes the web interface on the standard ports and leaves every alternative commented, so the default is a panel that terminates TLS itself.

Two port lines are active, one for HTTP and one for HTTPS. A third, mapping a different host port to the same container port, carries a comment explaining it is for running behind a proxy instead, and a fourth carries a comment about reaching the PHP process manager directly when not using the bundled web server. Both are inactive.

The bundled web server is the piece that makes those ports work without your help. There is a commented setting for skipping it entirely, which confirms that something else is present by default, and a certificate email variable whose comment says it is used for certificate issuance. The value shipped in the file is a placeholder in all caps telling you to put your own address there, and it is exactly the kind of default that causes a problem at three in the morning when the certificate cannot be issued and the error message names an address nobody owns.

Two more defaults to know. Mail is configured to log rather than send, so password reset and notification mail will land in the container log until you set it up. And there is a commented pair of settings for running behind a proxy, with a list of trusted proxy addresses whose defaults are the local bridge networks, which is a reminder that trusting proxy headers is a configuration decision.

One line is worth reading as design rather than configuration: a host gateway entry for reaching the host machine's services from inside the panel's network, commented as showing the panel on the internal network too. A panel that can reach the host is a panel whose compromise is a host compromise, and that capability is in the shipped default rather than behind a flag.

Configuration happens in the browser, not in the environment file

The example environment file has six keys, and that is the whole of it.

There is the environment name, the debug flag set to false, an application key left empty, a URL pointing at a test host, an installed flag set to false, and a locale.

So the panel is configured after it starts, through an installer in the browser. The installed flag is what tells it whether to serve the installer or the panel, and the empty application key is the marker that no one has been through it yet.

That design has one clear advantage and one cost. The advantage is that you do not have to learn a configuration file before you can look at the thing, and the same image works for a first install and for a production deployment. The cost is that the configuration is not in version control in any form you control, it is in the database, which means an upgrade that requires a new setting has no migration you can review in a diff.

The tree shows where the user facing content lives: a language directory for translations, a Crowdin configuration file for how those translations are managed, and separate markdown documents for the contributing guide, the code of conduct, the code standards, a contributor licence agreement, a security policy and a file of bounties.

The bounties file is unusual enough to be worth noting. In a volunteer maintained project, a list of paid tasks is a statement about which work is actually stuck, and it is more useful to a prospective contributor than an issue tracker sorted by label, because it says what somebody has already decided is worth doing.

The API has a versioning policy and two formatters for two languages

Three documents in the repository root describe how the project expects to be worked on, and they are worth reading before contributing.

The API versioning document is the most consequential of the three for anyone integrating against the panel, because a panel is a control plane other software talks to, and an unversioned API is an integration that breaks on upgrade. Having a written policy in the repository, rather than a promise in a chat channel, is the difference between an API and an implementation detail.

The code standards document and the contributing guide cover the human process, and the contributor licence agreement covers the legal side, which for an AGPL licensed project is not a formality.

Then the tooling, which is unusually well specified for a PHP and JavaScript project. Static analysis for PHP is configured in its own file. PHP code formatting is configured separately, and JavaScript and TypeScript formatting is configured in yet another file, so the two languages have independent formatters and neither has to compromise with the other. Tests are configured in their own file as well, and the frontend is built by a bundler with its own configuration file.

There are three Dockerfiles and three compose files, named for the base image, the development image, the bind mount variant and the full stack variant, so the container recipes are separated by purpose rather than accumulated in one file.

Two entries at the root deserve a note. The licence file is named without an extension while most of the documentation is markdown, and a plugins directory sits beside the application code, which is consistent with the volume mount in the compose file pointing a subdirectory of the data volume at that path.

Passkeys for the panel and a terminal emulator with a WebGL renderer

The frontend dependency list is short and two entries in it are load bearing.

The first is a passkey library from the Laravel ecosystem, as a runtime dependency rather than a development one. That means the panel's own administrative login supports passkeys rather than only passwords, which is the right call for a control plane that can start and stop containers across a host.

The second is a terminal emulator and its addons. There are four addons: one to fit the viewport to the window, one to search the scrollback, one to turn URLs in the output into links, and one that renders with WebGL rather than the DOM. There is also a separate search bar addon for the console itself.

A WebGL renderer for a server console is not a cosmetic choice. Console output for a game server is a lot of text appending quickly, and the DOM renderer falls over on volume; the accelerated renderer is what makes a live console usable. The search addon and the fit addon together are the difference between watching a console and finding something in it.

Everything else is styling and build tooling: three Tailwind plugins including the forms and typography sets, autoprefixer, a concurrency runner for parallel tasks, the Vite plugin for the Laravel side, Prettier, and the bundler itself.

The two version numbers worth noticing are the styling framework and the bundler, both of which are at a fourth and an eighth major respectively. A frontend that new, on a project whose last three releases are all pre one point zero betas, means the asset pipeline is one of the things most likely to need attention when either moves.

A section called Repository Activity that contains a copyright line

The readme ends with a heading and almost nothing under it.

The final heading is Repository Activity, and the only line beneath it is a copyright notice with a registered trademark symbol and a year range. Whatever activity summary that heading was meant to carry is not there, which is a small thing and a useful one: it tells you the page is maintained by hand rather than generated, and that a section can be left as a heading with nothing under it for a long time without anyone noticing.

There is a second small artefact at the very top. After the tagline there are two identical lines of forum style colour markup that never rendered, both carrying the same red value. It is a leftover from a platform that supported inline colour and a copy that did not, and it is duplicated, which suggests a paste rather than a deliberate repeat.

The release cadence tells the real story. The three most recent tags are all the same major and zero with an incrementing beta number: 36 in early August 2026, 37 three days later, 38 three days after that. Then nothing for about seven weeks, while the last commit on the default branch is dated 3 October 2026.

So this is a project in pre one point zero, shipping betas roughly every few days during a burst and then going quiet, with the branch still receiving commits. Thirty eight betas is a long time to be in beta, and for an AGPL licensed panel competing with an established alternative it says the API and the data model are still moving.

The project describes itself as built and maintained by volunteers, links a sponsorship page, and lists four ways to help including answering questions in the project's Discord. That is a coherent and honest picture of a project with a small team, a busy commit history, and no stable release.

Editorial conclusion

Pelican Panel fits a community, a host or a self hoster who wants Pterodactyl shaped tooling without Pterodactyl, and who is comfortable running a panel that holds a daemon with root level access to game servers. Four things to check before you deploy one. Whether you can build the image, because the production Dockerfile pulls its base from a private registry path on localhost and the file itself tells you to use the development Dockerfile locally instead, so a plain build from the repository will fail. Which ports you are publishing, since the compose file publishes 80 and 443 by default with the proxy alternatives left commented, and a reverse proxy set up on top of that will surprise you. Which email address is configured for certificate issuance, because the placeholder in the compose file is the kind of default that works until it does not. And whether you need anything beyond games, since the egg catalogue includes databases, object storage, monitoring and a search engine, which means the thing you are installing is a general container panel wearing a games vocabulary.

Frequently asked questions

What is Pelican Panel?

It is a free, open source game server control panel built on Laravel and Docker, positioned as a modern alternative in the Pterodactyl ecosystem. It gives a web interface for creating and managing servers, each of which runs in an isolated Docker container through a separate daemon called Wings.

Which games and services can Pelican Panel run?

Its templates, called eggs, are organised by category: Minecraft servers and proxies, SteamCMD titles, standalone games, Discord bots, voice servers, and four non game categories covering software such as Elasticsearch, Gitea, Grafana and RabbitMQ, programming runtimes, databases including Redis, MariaDB, PostgreSQL and MongoDB, S3 and SFTP storage, and Prometheus and Loki monitoring.

How is Pelican Panel configured after installation?

Through a browser installer. The example environment file has only six keys: the environment name, a debug flag, an empty application key, a URL, an installed flag set to false, and a locale. Mail defaults to logging rather than sending, and the certificate email in the compose file ships as a placeholder you are expected to replace.

What licence is Pelican Panel under?

AGPL-3.0, and the tree also carries a contributor licence agreement alongside the licence file, plus a code of conduct and a security policy document. The API is covered by a written versioning policy in the repository, which matters for a control plane that other software integrates against.

Official sources

  1. License: AGPL-3.0
  2. pelican/panel on GitHub
  3. Project website
  4. README
  5. Releases
Add this badge to your README

If you maintain this project, the badge below links readers to this analysis and shows its maintenance status from the daily GitHub snapshot. Paste the markdown into your README; add ?metric=license or ?metric=stars to the image URL for a different field.

Add this badge to your README

markdown
[![Hysen Labs](https://hysenlabs.com/badge/pelican-panel.svg)](https://hysenlabs.com/projects/pelican-panel)

Star history chart for your README

markdown
[![Star history](https://hysenlabs.com/chart/pelican-panel.svg)](https://hysenlabs.com/projects/pelican-panel)

Was this useful?