Creating a new Panel
Time Required
30 Minutes
Difficulty
Moderate
Installing the Panel
Setting up the Portainer stack
Create your Portainer stack using the below compose and .env file
I would recommend deploying GitOps (have a look at the this guide) as this will shift your compose file off of your server and into GitHub.
version: '3.8'
services:
database:
image: mariadb:10.11
restart: unless-stopped
command: --default-authentication-plugin=mysql_native_password
volumes:
- db:/var/lib/mysql
- dbetc:/etc/mysql
networks:
- panel
environment:
MYSQL_PASSWORD: $MYSQL_PASS
MYSQL_ROOT_PASSWORD: $MYSQL_PASS_ROOT
MYSQL_DATABASE: "panel"
MYSQL_USER: "pterodactyl"
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"
cache:
image: redis:alpine3.18
networks:
- panel
restart: unless-stopped
volumes:
- cache:/data
healthcheck:
test: ["CMD", "redis-cli", "ping"]
interval: 10s
timeout: 5s
retries: 5
labels:
- "autoheal=true"
logging:
driver: "json-file"
options:
max-size: "10m"
max-file: "3"
panel:
image: ghcr.io/pterodactyl/panel:v1.11.11
restart: unless-stopped
networks:
- panel
ports:
- ${PORT_HTTP:-80}:80
#dns:
# - 1.1.1.1
links:
- database
- cache
volumes:
- env:/app/var
environment:
MAIL_FROM: $MAIL_FROM
MAIL_DRIVER: "smtp"
MAIL_HOST: ${MAIL_SERVER:-smtp.gmail.com}
MAIL_PORT: ${MAIL_PORT:-587}
MAIL_USERNAME: $MAIL_USERNAME
MAIL_PASSWORD: $MAIL_PASS
MAIL_ENCRYPTION: "true"
APP_URL: $PTERO_PANEL_URL
APP_TIMEZONE: $TZ
APP_SERVICE_AUTHOR: $MAIL_FROM
TRUSTED_PROXIES: "*"
DB_PASSWORD: $MYSQL_PASS
APP_ENV: "production"
APP_ENVIRONMENT_ONLY: "false"
CACHE_DRIVER: "redis"
SESSION_DRIVER: "redis"
QUEUE_DRIVER: "redis"
REDIS_HOST: "cache"
DB_HOST: "database"
DB_PORT: "3306"
HASHIDS_SALT: $HASHIDS_SALT #Refer to https://github.com/pterodactyl/panel/issues/5012#issuecomment-1960789655
HASHIDS_LENGTH: 8
healthcheck:
test: curl --connect-timeout 15 --silent --show-error --fail localhost:80
interval: 1m
timeout: 30s
retries: 3
start_period: 30s
labels:
- "autoheal=true"
- cloudflare.tunnel.enable=true
- cloudflare.tunnel.hostname=${SUBDOMAIN}${DOMAIN}
- cloudflare.tunnel.service=http://${HOSTNAME}:${PORT_HTTP:-80}
- cloudflare.tunnel.access.policy=${CFPOLICY:-default_tld}
- cloudflare.tunnel.zonename=${DOMAIN}
- cloudflare.tunnel.path=${URLPATH:-}
logging:
driver: "json-file"
options:
max-size: "10m"
max-file: "3"
networks:
panel:
volumes:
cache:
db:
env:
dbetc:
MYSQL_PASS_ROOT=
PORT_HTTP=
MAIL_FROM=
MAIL_SERVER=smtp.gmail.com
MAIL_PORT=587
[email protected]
MAIL_PASS=
PTERO_PANEL_URL=https://panel.example.com #your cloudflare subdomain
TZ=
HASHIDS_SALT= #This MUST be a 20 character string, per https://github.com/pterodactyl/panel/issues/5012#issuecomment-1960789655
Confirm the Panel is running
Check the Portainer logs for the panel container, you should see something similar to below
external vars exist.
Checking if https is required.
Checking if letsencrypt email is set.
No letsencrypt email is set using http config.
Removing the default nginx config
Checking database status.
Waiting for database connection...
database (172.28.0.3:3306) open
Migrating and Seeding D.B
INFO Nothing to migrate.
INFO Seeding database.
Database\Seeders\NestSeeder ........................................ RUNNING
Database\Seeders\NestSeeder ................................... 2.34 ms DONE
Database\Seeders\EggSeeder ......................................... RUNNING
*********************************************
* Updating Eggs for Nest: Minecraft *
*********************************************
Updated Paper
Updated Bungeecord
Updated Vanilla Minecraft
Updated Sponge (SpongeVanilla)
Updated Forge Minecraft
*************************************************
* Updating Eggs for Nest: Source Engine *
*************************************************
Updated Counter-Strike: Global Offensive
Updated Garrys Mod
Updated Team Fortress 2
Updated Ark: Survival Evolved
Updated Insurgency
Updated Custom Source Engine Game
*************************************************
* Updating Eggs for Nest: Voice Servers *
*************************************************
Updated Teamspeak3 Server
Updated Mumble Server
****************************************
* Updating Eggs for Nest: Rust *
****************************************
Updated Rust
Database\Seeders\EggSeeder .................................. 175.67 ms DONE
Starting cron jobs.
Starting supervisord.
2023-06-13 13:41:50,854 CRIT Server 'unix_http_server' running without any HTTP authentication checking
Confirm the Login page loads
Browse to http://yourserver:port and confirm you see the below

Create your Admin user
Open up Portainer and navigate to the Panel container
Click on Console and change the command to '/bin/sh'
Hit Connect
Input the below command and next through the prompts (set account as administrator)
php artisan p:user:make
Log into Pterodactyl with your newly created administrator account
Configure the Panel
Enforce 2FA
Click on the Settings cog in the top right hand corner
Click on Settings
Set 'Require 2FA authentication' to 'All Users' and hit Save
Click on 'Enable 2FA' and follow the steps
Save your backup codes somewhere
Create Node Locations
Click on Locations, then 'create new'
Create 2 locations,
a location for 'On Prem' nodes
a location for 'Off Prem' nodes
Set up your Proxy
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

navigate to your proxy url and confirm you see the login page
Last updated
Was this helpful?