Skip to content

Instantly share code, notes, and snippets.

@Scarsz
Last active March 6, 2024 06:00
Show Gist options
  • Save Scarsz/d0f299470ef9654f76f6e430d4b2f1f9 to your computer and use it in GitHub Desktop.
Save Scarsz/d0f299470ef9654f76f6e430d4b2f1f9 to your computer and use it in GitHub Desktop.
Pterodactyl running in docker-compose stacks with Caddy reverse proxying + SSL behind CloudFlare

Setup

This setup assumes you're a normal user, one such as minecraft, with sudo and docker privileges/groups. Docker is assumed to be installed and functional. I deployed this on clean Debian 12, your mileage may vary with other distributions/versions.

Files

Retrieve the linked docker-compose.yml files and make changes detailed in the corresponding Gist files. Ensure you rename the example compose files to the same names in this Gist for the automatically generated scripts to work.

Caddy

Retrieve Caddy from https://caddyserver.com, being sure to include the CloudFlare TLS package. I like installing Caddy to the system binaries folder, though you don't have to.

Download Caddy with Httpie: sudo http -d https://caddyserver.com/api/download?os=linux&arch=amd64&p=github.com%2Fcaddy-dns%2Fcloudflare -o /usr/sbin/caddy && sudo chmod +x /usr/sbin/caddy

I suggest creating a www user with no password (meaning direct password login disabled) whose home folder contains your Caddyfile. Switch to that user with sudo su - www, save the Caddyfile from this Gist, modify the example domain names, modify the CloudFlare token placeholder from the below step, then start Caddy with sudo caddy start.

CloudFlare

Creating API token for automatic TLS with Caddy

Create an API token at https://dash.cloudflare.com/profile/api-tokens. It should have Zone: Read and DNS: Edit permissions for the proper zone. Replace INSERT_CLOUDFLARE_TOKEN in Caddyfile with your token.

DNS records

Create two A (or CNAME -> A) records for your panel and your daemon. Both should be proxied (orange cloud) and pointing to your server's IP.

Panel -> node communication through reverse proxy

We will be telling the panel to communicate through HTTPS to our node, which in reality will be CloudFlare. CloudFlare will then proxy the request to Caddy, which will then communicate over HTTP with our daemon at our local port. This allows us to not expose our daemon IP through our DNS record. Do note that the SFTP connection can't be proxied unless you have a TCP proxying service such as with CloudFlare's enterprise plan.

See also: https://pterodactyl.io/wings/1.0/configuration.html#enabling-cloudflare-proxy, https://developers.cloudflare.com/fundamentals/get-started/reference/network-ports/

Adding your node to the panel

  • Fully Qualified Domain Name should match your configured DNS record, i.e. node.yourdomain.com
  • Set Communicate Over SSL to Use SSL Connection to enable the panel to communicate with Wings through HTTPS
  • Tick Behind Proxy as Caddy will be taking care of SSL for us automatically
  • Set Daemon Port to 443 to tell Pterodactyl to communicate via HTTPS

Run setup.sh with bash <(curl -s https://scarsz.me/pterodactyl). Once you get to Press any key to open daemon config, press a key which will open daemon-config.yml in nano. Copy + paste the generated YAML config from your newly created node's Configuration tab, write changes, and close the file. The daemon will be automatically started.

Verify your node has a green heart in the node list and that the node's information shows up on its status page.

Scripts

Daemons

  • ./daemon - shortcut for docker compose -f docker-compose.daemon.yml ...
  • ./panel - shortcut for docker compose -f docker-compose.panel.yml ...

You can use these as you would a normal docker compose stack. i.e.:

  • Restart daemon: ./daemon restart
  • Update panel: ./panel pull && ./panel up -d

add-user

This will run the Laravel user creation wizard in Pterodactyl's panel container. The setup script does this once to add the initial administrator user. Subsequent users can be added in the panel by an admin.

(ssl) {
tls {
dns cloudflare INSERT_CLOUDFLARE_TOKEN
}
}
(log) {
log {
output stdout
}
}
panel.yourdomain.com {
import ssl
import log
reverse_proxy 127.0.0.1:47310
request_body {
max_size 100m
}
}
node.yourdomain.com {
import ssl
import log
reverse_proxy 127.0.0.1:47312
}
# based on https://github.com/pterodactyl/wings/blob/develop/docker-compose.example.yml
# contents of this file are what needs to be changed
services:
wings:
ports:
- "127.0.0.1:47312:443" # Caddy exposes our Daemon for us, listen on a random loopback port
- "2022:2022" # sftp port, change if you'd like, otherwise leave as default 2022
# based on https://github.com/pterodactyl/panel/blob/develop/docker-compose.example.yml
# contents of this file are what needs to be changed
# change to randomly generated passwords
x-common:
database:
MYSQL_PASSWORD: &db-password "CHANGE_ME"
MYSQL_ROOT_PASSWORD: "CHANGE_ME_TOO"
# be sure to set the proper app url for links on the panel to work properly
x-common:
panel:
APP_URL: "https://panel.yourdomain.com"
# Caddy will be exposing :80 and :443 and proxying requests internally,
# so we'll set our panel to only listen on loopback ports
services:
panel:
ports:
- "127.0.0.1:47310:80"
- "127.0.0.1:47311:443"
#!/bin/bash
set -x
echo './panel run panel php artisan p:user:make' > add-user
echo 'docker compose -f docker-compose.daemon.yml "$@"' > daemon
echo 'docker compose -f docker-compose.panel.yml "$@"' > panel
chmod +x add-user daemon panel
./daemon create
./panel create
sudo mkdir /etc/pterodactyl
sudo touch /etc/pterodactyl/config.yml
ln -s /etc/pterodactyl/config.yml daemon-config.yml
echo Time to create your administrator user!
sleep 3
./add-user
./panel up -d
# fix log directory permissions
./panel exec panel chown -R nginx: /app/storage/logs/
echo 'Go to the panel and create your node. Follow the instructions in the README!'
echo 'Press any key to open daemon config (copy + paste generated data in node Configration tab)'
read -r -n1
sudo nano daemon-config.yml
./daemon up -d
set +x
echo Setup finished. Panel and daemon have been started.
@Simsz
Copy link

Simsz commented Dec 6, 2023

What does your caddy.service file look like? I think that is where I am running into errors with caddy not being able to get SSL certs for the domains. I am on identical hardware more or less and have the domain pointed to the server already

I ended up getting it figured out, didn't whitelist the IPv6 address like I should've and just the IPv4 address. I guess additionally, steps to follow after Caddy is set up would be nice. It took a bit but I figured out what I needed to do to run docker, etc. and get things working.

Oh also lastly, the linked bash command doesn't work because this URL (https://scarsz.me/pterodactyl) 404's and from my own experience the SFTP doesn't work either as is. I set up another record on cloudflare for sftp.node.DOMAIN.COM and set it to not proxy that traffic and it's working now. Just a detail that could be added to help anyone else trying to use this :)

Nice gist, very helpful overall :)

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment