# pterodactyl/wings: the control plane behind a game server panel

> Wings is the Go daemon that actually runs and manages game server instances for the Pterodactyl panel. It exposes an HTTP API for the lifecycle, the logs and the backups, and it ships a built-in SFTP server so that users can reach their files with the credentials they already have. The same daemon will run the upcoming Panel v2.

**pterodactyl/wings** — The server control plane for Pterodactyl Panel. Written from the ground-up with security, speed, and stability in mind.

- Repository: https://github.com/pterodactyl/wings
- Website: https://pterodactyl.io
- Stars: 1,068 · Forks: 506
- Language: Go
- License: MIT
- Published: 2026-10-19 · Updated: 2026-10-19 · Language: en
- Canonical page: https://hysenlabs.com/projects/pterodactyl-wings

## What the daemon actually does

Wings is Pterodactyl's server control plane, built for the rapidly changing gaming industry and designed to be highly performant and secure. The description of the interface is concrete. Wings provides an HTTP API allowing you to interface directly with running server instances, fetch server logs, generate backups, and control all aspects of the server lifecycle.

The division of labour is what makes Pterodactyl work. The panel is the web interface that users and administrators interact with, and it is written in PHP and does not run the game servers itself. Wings is the privileged process on each node that does, and the panel drives it over the API.

That means Wings holds the credentials to the game server processes, the files of every tenant, and the ability to start and stop them. The security posture of the whole system is the security posture of this daemon, which is why the project describes itself as written from the ground up with security, speed and stability in mind.

The second feature is the built-in SFTP server, and the reason for it is stated: it allows the system to remain free of Pterodactyl specific dependencies, and it allows users to authenticate with the same credentials they would normally use to access the Panel. A user uploads a mod or downloads a save over SFTP with the account they already have, and the host does not need an SSH daemon of its own with its own user database.

The project is MIT licensed, written in Go, and the site is pterodactyl.io. The default branch is develop, and the last push was on 2026-10-14.

## The same daemon will run Panel v2

There is a short section in the README about the future, and it matters for anyone planning a deployment.

Pterodactyl v2 is coming soon, and the note says that Wings is stable and remains the daemon for Pterodactyl, with the same Wings used with the upcoming Panel v2. There is a video linked, Introducing Pterodactyl v2.

The practical significance is that a v2 upgrade is a panel upgrade rather than a node rebuild. Whatever you deploy today, the node-side component stays the same binary with the same API, which is an unusual and welcome property for a project of this size.

It also means the compatibility surface you depend on is the HTTP API between the panel and the daemon, and that surface is documented separately from the panel documentation. The README points at the Panel Documentation, the Wings Documentation, the Community Guides with a Debian installation walkthrough, and Discord for help.

One more thing about support: the reporting section says to use the pterodactyl/panel repository to report any issues or make feature requests for Wings, and states that the security policy listed within that repository also applies to Wings. So the panel repository is the issue tracker for both halves of the project, and the security policy covers the daemon as well.

## The repository layout is the daemon's anatomy

The top-level directories describe the parts of a node-side control plane, and reading them tells you what the daemon is responsible for.

There is wings.go at the root, which is the entry point the build compiles, and a cmd/ directory for the command line. The config/ directory holds the configuration, and environment/ holds the environment handling, which in a panel-driven system is how the panel passes settings to the node. The server/ directory is the server instance management, the part that starts, stops and supervises the game processes, and sftp/ is the built-in file server.

The supporting directories are the interesting ones. The router/ directory holds the HTTP API surface, remote/ is the client for talking to the panel and to the nodes, events/ is the event system that pushes state changes to the panel, parser/ handles the parsing of configuration files, loggers/ the log handling, system/ the system-level operations, and internal/ the shared internals.

Around them are the files a Go project of this size carries: a Dockerfile, a Makefile, the .golangci.yml for the linter, a flake.nix for Nix, a .envrc for direnv, a docker-compose.example.yml, a CHANGELOG.md and the LICENSE file.

The dependency list confirms the architecture. The docker/docker client at v28.5.2 and the containerd error definitions are there because the daemon manages containerised game servers. The events/ and remote/ directories correspond to the gocron scheduler, the gorilla websocket, and the gbrlsnchs jwt library for tokens. The SQLite driver glebarez/sqlite and the go-cache package are the local state, and the New York Times logrotate package is the log rotation, which matters for a long-running daemon on a node that hosts many tenants.

## The dependency list is the feature list

A few dependencies in the go.mod are worth calling out, because each one corresponds to a capability a game server host actually needs.

The HTTP stack is gin, and the API is a normal REST surface rather than something exotic. The scheduler is go-co-op/gocron, which is what makes a scheduled task, a backup or a scheduled restart possible without an external cron. The concurrency helper is gammazero/workerpool, so the work of fanning out to many servers is bounded. The rate limiter is juju/ratelimit, which protects the daemon from its own clients.

Compression and archiving are the pair that decides whether backups are practical. klauspost/compress and klauspost/pgzip handle compression, and mholt/archives handles archive formats, so a backup can be a tarball of the server directory rather than a raw copy. NYTimes/logrotate takes care of the log files that would otherwise fill a node's disk.

The file transfer path is pkg/sftp, which is the implementation behind the built-in SFTP server, and the detection of the platform is acobaugh/osrelease, which is how a single binary knows what it is running on. The interactive configuration uses AlecAivazis/survey, so a first run can ask questions rather than demand a hand-written file.

The module targets Go 1.26.0 with the toolchain pinned to go1.26.9, and the library set is otherwise conventional, with cobra for the command line, gorilla/websocket for the live event stream, the gbrlsnchs jwt library for token handling, and testify for the tests.

## The container image is distroless

The Dockerfile builds a static binary and ships it in a distroless image, and the details are worth reading because they are the standard hardening for a privileged daemon.

The build stage is golang:1.27.2-alpine, with git, make and mailcap installed, the module manifests copied first so the dependency download is cached separately from the source, and the build run with CGO_ENABLED=0 and three flags: the linker flags strip the binary and stamp the version into the system package, the build is verbose, and -trimpath removes local paths from the binary.

The final stage is gcr.io/distroless/static:latest, which contains no shell and no package manager. Two files are copied in from the builder deliberately: the os-release file, which the build overwrites with a minimal description, and the mime.types file, which the SFTP server needs in order to serve content types correctly. The binary goes to /usr/bin/, the entrypoint is /usr/bin/wings, and the default command is --config /etc/pterodactyl/config.yml.

The exposed ports tell you the shape of the service. Port 8080 is the HTTP API and port 2022 is the SFTP server, and the fact that the SFTP port is on the same container is the reason a user can reach their files without an SSH daemon on the host.

For a component that runs game servers for other people, an image with no shell in it is a meaningful reduction in what an attacker can reach if they get code execution on the node.

## Building it, and the debug targets

The Makefile is small and the debug targets are the interesting part.

The build target cross-compiles for two architectures, linux amd64 and linux arm64, with the -s -w linker flags and a gcflags setting that trims the build path out of the binary. A compress target sits alongside it, and there is also a cross-build target that chains clean, build and compress.

The debug target is the one a contributor will actually use, and it shows the flags that matter in development:

```bash
sudo ./wings --debug --ignore-certificate-errors --config config.yml --pprof --pprof-block-rate 1
```

The pprof flags expose a profiling endpoint, and the block rate of 1 turns on goroutine blocking profiling, which is how you find a deadlock in a daemon that manages many concurrent servers. The ignore-certificate-errors flag is there because a development node often has a self-signed panel certificate.

There is a second, more elaborate target for a remotely debuggable session, which builds with the race detector and the compiler's debug flags, then runs the binary under the Delve debugger in headless mode listening on port 2345, with the API version set and multiple clients accepted, so an IDE can attach and hit breakpoints.

The lint target has a detail that is easy to miss in the comment above it. Wings only targets Linux, so the linter runs with GOOS=linux to cover the linux and unix specific files.

The project also ships a flake.nix, so a Nix user can build the same binary from the same source.

## Sponsors, and where the project stands

The sponsors section is a table of seven companies, and reading it tells you who depends on this daemon.

Buildurly is a hardware procurement company, Hosturly an enterprise hosting provider, indifferent broccoli a game server hosting and rental company, Infraly an infrastructure company, MineStrator a game server hosting provider with a Minecraft focus, Physgun a game server hosting provider that describes itself as engineering the performance rather than renting rack space and rebranding a panel, and WISP a SaaS platform for game server management aimed at hosting companies and enthusiasts.

The list is a list of hosting companies, and that is the point: Wings is the node-side component that every one of them runs, so its stability is a business dependency for them. That is a different kind of pressure from a hobby project, and it is visible in the release cadence.

The releases are regular. v1.13.2 was tagged on 2026-08-03, v1.13.3 on 2026-08-14 and v1.13.4 on 2026-10-14, with the last push to the repository on 2026-10-14. The 1.13 line is a mature, stable series, and the version numbers have been incrementing for long enough that the current major line tells you how settled the API is.

The one caveat about the future is the Panel v2 timeline, which the README describes as coming soon without a date. The daemon stays the same, but a panel major version is still a migration for the operators running it, and the project is young enough that the v2 work is still in flight.

## Conclusion

Adopt Wings if you are running Pterodactyl, because it is the daemon the panel talks to and there is no alternative that keeps the panel working. Do not adopt it as a standalone game server manager, because it is designed around the panel's model, and do not skip the security policy, which is maintained in the panel repository and applies to Wings as well. Before you start, read the Wings documentation rather than the panel documentation, and if you build it yourself, use the Makefile targets as they are, because the debug and remote debug targets assume a specific configuration and the race detector is enabled in the remote debugging build.

## FAQ

### What is Pterodactyl Wings?

It is Pterodactyl's server control plane, the Go daemon that runs and manages the game server instances on a node. It provides an HTTP API for interfacing with running instances, fetching server logs, generating backups and controlling the server lifecycle, and it ships a built-in SFTP server so users can use their Panel credentials for file access.

### Will I need to change Wings when Pterodactyl v2 arrives?

No. The README says Wings is stable and remains the daemon for Pterodactyl, and that the same Wings is used with the upcoming Panel v2, so a v2 upgrade is a panel change rather than a node rebuild. Issues for Wings are reported in the pterodactyl/panel repository, and the security policy there applies to Wings as well.

### What does the Wings container image look like?

It is a two-stage build that produces a static binary in a golang:1.27.2-alpine builder and ships it in gcr.io/distroless/static, so the runtime has no shell or package manager. The os-release and mime.types files are copied in from the builder, the entrypoint is /usr/bin/wings, the default config path is /etc/pterodactyl/config.yml, and ports 8080 and 2022 are exposed.

### How do I build and debug Wings locally?

The Makefile cross-builds for linux amd64 and arm64, and its debug target runs the binary with --debug, --ignore-certificate-errors and the pprof flags with a block rate of 1. A second target builds with the race detector and runs under the Delve debugger headless on port 2345 so an IDE can attach, and the lint target runs with GOOS=linux.

### How actively is Wings maintained?

The repository is not archived, the last push was on 2026-10-14, and the recent releases are v1.13.2 from 2026-08-03, v1.13.3 from 2026-08-14 and v1.13.4 from 2026-10-14. The sponsor list is a list of hosting companies, so the daemon's stability is a dependency for a number of businesses.

## Sources

- [License: MIT](https://github.com/pterodactyl/wings/blob/develop/LICENSE)
- [Project website](https://pterodactyl.io)
- [pterodactyl/wings on GitHub](https://github.com/pterodactyl/wings)
- [README](https://github.com/pterodactyl/wings/blob/develop/README.md)
- [Releases](https://github.com/pterodactyl/wings/releases)

---

Hysen Labs editorial analysis, written from the project's own repository and release notes. Cite the canonical page: https://hysenlabs.com/projects/pterodactyl-wings
