Creating a new Wings node
Time Required
30 Minutes
Difficulty
Moderate
I am installing Wings on my test VM, 'Basil', for writing this documentation. Any references to Basil will need to be changed to your server. Once this documentation has been finalized, Wings will be deleted from Basil.
Installing Wings and set up Reverse Proxy
Configure the 'Pterodactyl Wings' Portainer stack
Refer to the Portainer and GitOps documentation for configuring a new Portainer stack using the AGG Pterodactyl Wings Docker Compose file
Name the stack something simple, like 'wings'
Ensure you fill all the variables from the ENV file
version: '3.8'
services:
wings:
image: ghcr.io/pterodactyl/wings:v1.11.13@sha256:98a5b9622cd152c43f1795fbc443934a25828cb1b3f7b5979cd5efb58175e869
restart: always
logging:
driver: "json-file"
options:
max-size: "10m"
max-file: "3"
networks:
- wings
ports:
- ${PORT_SFTP:-2022}:2022
- ${PORT:-443}:443 #Web address port
#- $PORT_UNKNOWN:8080
tty: true
environment:
TZ: $TZ
WINGS_UID: 988
WINGS_GID: 988
WINGS_USERNAME: pterodactyl
volumes:
- /var/run/docker.sock:/var/run/docker.sock
- /var/lib/docker/containers/:/var/lib/docker/containers/
- config:/etc/pterodactyl/ #config file from Panel
- /var/lib/pterodactyl/:/var/lib/pterodactyl/ #game server files
- /var/log/pterodactyl/:/var/log/pterodactyl/ #Allows Crowdsec to read logs
- /tmp/pterodactyl/:/tmp/pterodactyl/
- /srv/daemon-data/:/srv/daemon-data/
- logs:/app/storage/logs/ #Laravel log files
# healthcheck:
# test: [ "CMD", "/usr/bin/wget", "--no-verbose", "--tries=1", "--spider", "http://localhost/health" ]
# interval: 15s
# timeout: 3s
# retries: 5
# start_period: 30s
labels:
# - autoheal=true
- cloudflare.tunnel.enable=true
- cloudflare.tunnel.hostname=${CFSUBDOMAIN}${CFDOMAIN}
- cloudflare.tunnel.service=http://${HOSTNAME:-localhost}:${PORT:-443}
- cloudflare.tunnel.access.policy=${CFPOLICY:-default_tld}
- cloudflare.tunnel.zonename=${CFDOMAIN}
- cloudflare.tunnel.path=${CFURLPATH:-}
db:
image: mariadb:12.0
restart: always
command: --default-authentication-plugin=mysql_native_password
ports:
- ${PORT_DB:-3306}:3306
networks:
- wings
volumes:
- db:/var/lib/mysql
environment:
- MYSQL_DATABASE="servers"
- MYSQL_USER="pterodactyl"
- MYSQL_PASSWORD=$SQL_PASS
- MYSQL_ROOT_PASSWORD=$SQL_PASS_ROOT
healthcheck:
test: ["CMD", "mariadb-admin", "ping", "-proot", "--password=$MYSQL_PASS_ROOT"]
interval: 30s
timeout: 10s
retries: 5
labels:
- "autoheal=true"
logging:
driver: "json-file"
options:
max-size: "10m"
max-file: "3"
networks:
wings:
name: wings
driver: bridge
driver_opts:
com.docker.network.bridge.name: wings
pterodactyl_nw:
driver: bridge
volumes:
config:
lib:
daemon:
db:
logs:
PORT_SFTP=2022 # unfortunately SFTP doesn't seem to work with CF tunnels
TZ=
SQL_PASS=
SQL_PASS_ROOT=
PORT_DB=3306 #Port for the database on the on the node. This is an advanced function and probably not needed
PORT=8443 #It is recommended to NOT use 443 for this
CFSUBDOMAIN= # the subdomain to access your node with the . eg node1.
CFDOMAIN= # your domain, eg example.comAllow Ports through the Firewall
SSH into your server
Allow SSH and enable the firewall with the below commands
ufw allow ssh ufw enableThis is to increase security on this hardware as a port forward is required
Run the command
ufw allow PORT, replacing PORT with what you set for PORT and PORT_SFTP above, eg;ufw allow 2022
Configure the Reverse Proxy
This step can be skipped thanks to the labels in the compose file, if you are using DockFlare
Refer to the Cloudflare Proxy and Authentication guides
Your subdomain and domain needs to match the PTERO_PANEL_URL variable set above
Type is HTTP, pointing at yourserver:port (my example is basil.agg.local:8443)

Test the reverse proxy works
Navigate to the URL of your reverse proxy. If you see the below text, it is working
{"error":"The required authorization heads were not present in the request."}Configure Panel & Wings
Set up a Node on the Panel
Log into Pterodactyl with an administrator account
Click on the Settings cog in the top right
Click on Nodes
Click on Create New in the top right and
Name your Node (I normally give them the same name as the server, or node1)
Provide the FQDN of your Node (this is the externally available reverse proxy address configured here Configure the Reverse Proxy)
Tick 'Use SSL Connection'
Tick 'Behind Proxy'
Provide RAM & RAM over allocation of the machine or VM
Provide the disk space & over allocation of the machine or VM
Set your Daemon port to 443 (As Cloudflare uses 443 for its proxy)
Click on 'Create Node'

Upload Configuration file to Wings
In Pterodactyl, click on 'Nodes' on the left
You should see your new Node, with a red heart

Click on your new node, then the Configuration tab and confirm that the highlighted lines are the same as mine

I would also recommend changing the upload_limit to '1024' If the highlighted settings are NOT the same, you made a mistake in step Set up a Node on the Panel. Delete the node and start back there
Copy the contents of the file and save it as 'config.yml'
Log into Portainer and click on the Wings host
Click on 'Stacks' and select the 'wings' stack
Click on 'Stop stack'
Click on 'Volumes'
Locate the Wings 'config' volume - it will be named after your stack (eg wings_config) and click on Browse
Click on the Upload button, then select your config.yml file
SSH onto your Wings Node
Run the command
docker volume listand locate the Wings Config volumeRun the command docker
volume inspect <VolumeNameHere>to get the mountpath of the volumeCD to the mountpath
run command
nano config.ymland paste in the contents of the config filePress
CTRL + O, thenEnterto save the config file
Restart the container to load the config file
Click on Stacks and open your Wings stack
Restart the stack and wait 30 seconds
Refresh the Pterodactyl Nodes page and it should now be connected

Assigning Ports to the Node
Click on your new node and click the 'Allocations' tab
On the right hand panel, input
IP address: 0.0.0.0
IP Alias: Your domain or subdomain that points to your servers public IP
Ports: The port range you will forward to this VM (I've chosen ports 500-600)\

Run the
ufw allowcommand to allow these ports through the firewall. You can use a : to allow a range, such as 500:600
Port Forward
You will now need to port forward the chosen ports to your server.
Firstly, have a look at your modem / router. You will need to take note of
Brand
Model number or part number
Port forwarding is particularly tricky for beginners, mostly because every device is slightly different.
You'll need to do some Googling and / or Youtube'ing on how to port forward with your model router / modem.
Why do I do it this way?
My assumption here is that the Pterodactyl dev's want us to set up and use SSL certs on the Wings host and make it publicly available without a proxy. I can't be bothered generating certs and managing their expirations in my Homelab. My configuration offloads the certificate management to Cloudflare (or any other reverse proxy - I used to use NGINX Proxy Manager for this) which means that I don't need to worry about cycling certificates.
Offloading this task to the Cloudflare tunnel does create a couple of potential issues,
If the tunnel is down / crashes, the Panel can't talk Wings
If your hosting the Panel and Wings in your _home_lab, the connection is reliant on the internet being up
Cloudflare outages may break the Panel / Wings communication
Pterodactyl Discord does not provide support for proxied panel/wings connections
Please note that I don't have SFTP working with this set up, though I imagine changing the SFTP port and forwarding that port to the host would function fine.
Last updated
Was this helpful?