Skip to content
Draft
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
5 changes: 5 additions & 0 deletions .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -18,6 +18,11 @@ _ide_helper_models.php
.yarn
public/assets/manifest.json


# For local development with Just
pterodactyl/
.blueprintrc

# For local development with docker
# Remove if we ever put the Dockerfile in the repo
.dockerignore
Expand Down
214 changes: 214 additions & 0 deletions justfile
Original file line number Diff line number Diff line change
@@ -0,0 +1,214 @@
blueprint_root := "./"
pterodactyl_dir := "pterodactyl"
db_connection := "mysql"
db_username := "pterodactyl"
db_password := "pterodactyl"
db_port := "3006"
app_url := "http://localhost:3000"
app_debug := "true"
USERSHELL := "/bin/bash"

default: dev

setup: check_dev stop_db stop_wings setup_dev install_blueprint setup_wings dev

blueprintrc:
#!/usr/bin/env bash
export user=$(whoami)

cat > .blueprintrc << EOF
WEBUSER="$user"
OWNERSHIP="$user:$user"
USERSHELL="{{ USERSHELL }}"
SHORTCUT_DIR=""
EOF

check_dev:
#!/usr/bin/env bash
if [ -d {{ pterodactyl_dir }} ]; then
echo "${RED}Pterodactyl Dir exists, delete it to rerun setup${NC}"
exit 1
fi

setup_dev: check-deps blueprintrc
#!/usr/bin/env bash
set -euo pipefail
git clone https://github.com/pterodactyl/panel.git {{ pterodactyl_dir }}
git -C {{ pterodactyl_dir }} pull || true

cd {{ pterodactyl_dir }}

if [ ! -f ".env" ]; then
cp -n .env.example .env
fi

composer update
composer i
if ! grep -q "^APP_KEY=base64:" .env; then
php artisan key:generate -n
fi

yarn install
just env_replace {{ pterodactyl_dir }}/.env DB_CONNECTION {{ db_connection }}
just env_replace {{ pterodactyl_dir }}/.env DB_USERNAME {{ db_username }}
just env_replace {{ pterodactyl_dir }}/.env DB_PASSWORD {{ db_password }}
just env_replace {{ pterodactyl_dir }}/.env DB_PORT {{ db_port }}

just env_replace {{ pterodactyl_dir }}/.env APP_URL {{ app_url }}
just env_replace {{ pterodactyl_dir }}/.env APP_DEBUG {{ app_debug }}
just env_replace {{ pterodactyl_dir }}/.env APP_ENVIRONMENT_ONLY false
just env_replace {{ pterodactyl_dir }}/.env RECAPTCHA_ENABLED false

just start_db
php artisan migrate --seed --force -n

php artisan p:user:make --email=dev@dev.com --username=dev --name-first=dev --name-last=dev --password=dev --admin=yes 2>/dev/null || true
if [ ! -f "{{ pterodactyl_dir }}/srv/etc/config.yml" ]; then
php artisan p:location:make --short=dev --long=dev -qn 2>/dev/null || true
php artisan p:node:make --fqdn=127.0.0.1 --name=dev-node --description=dev-node --locationId=1 --public=1 --scheme=http --proxy=0 --maxMemory=10240 --overallocateMemory=0 --maxDisk=10240 --overallocateDisk=0 --uploadSize=1024 --daemonListeningPort=8080 --daemonSFTPPort=2022 --maintenance=0 -n 2>/dev/null || true
fi

docker exec blueprint-dev-db mysql -uroot -proot -e "USE panel; UPDATE users SET root_admin = 1 WHERE email = 'dev@dev.com';" 2>/dev/null || true
docker exec blueprint-dev-db mysql -uroot -proot -e "USE panel; INSERT INTO allocations (id, node_id, ip, ip_alias, port, server_id, notes, created_at, updated_at) VALUES (1, 1, '0.0.0.0', NULL, 25565, NULL, NULL, NOW(), NOW());" 2>/dev/null || true
docker exec blueprint-dev-db mysql -uroot -proot -e "USE panel; INSERT INTO allocations (id, node_id, ip, ip_alias, port, server_id, notes, created_at, updated_at) VALUES (2, 1, '0.0.0.0', NULL, 25566, NULL, NULL, NOW(), NOW());" 2>/dev/null || true
docker exec blueprint-dev-db mysql -uroot -proot -e "USE panel; INSERT INTO allocations (id, node_id, ip, ip_alias, port, server_id, notes, created_at, updated_at) VALUES (3, 1, '0.0.0.0', NULL, 25567, NULL, NULL, NOW(), NOW());" 2>/dev/null || true

install_blueprint:
#!/usr/bin/env bash
set -euo pipefail

export BLUEPRINT_ENVIRONMENT="ci"
export SHORTCUT_DIR=""
echo "Syncing Blueprint files to Pterodactyl..."

rsync -av \
--exclude='{{ pterodactyl_dir }}' \
--exclude='.git' \
--exclude='node_modules' \
--exclude='vendor' \
--exclude='.env' \
--exclude='justfile' \
--exclude='LICENSE.md' \
--exclude='README.md' \
--exclude='CODE_OF_CONDUCT.md' \
--exclude='SECURITY.md' \
{{ blueprint_root }} {{ pterodactyl_dir }}/ \

chmod +x {{ pterodactyl_dir }}/blueprint.sh

cd {{ pterodactyl_dir }}

bash blueprint.sh -bash -rerun-install

setup_wings: check-deps stop_wings
mkdir -p "./{{ pterodactyl_dir }}/srv/tmp/pterodactyl"
mkdir -p "./{{ pterodactyl_dir }}/srv/var/lib/pterodactyl"
mkdir -p "./{{ pterodactyl_dir }}/srv/var/lib/pterodactyl/volumes"
mkdir -p "./{{ pterodactyl_dir }}/srv/etc"
-php ./{{ pterodactyl_dir }}/artisan p:node:configuration 1 > {{pterodactyl_dir }}/srv/etc/config.yml

docker run \
-d \
--privileged \
--name blueprint-dev-wings \
--restart unless-stopped \
--network host \
-v "/var/run/docker.sock:/var/run/docker.sock" \
-v "/var/lib/docker/:/var/lib/docker" \
-v "./{{ pterodactyl_dir }}/srv/tmp/pterodactyl:/tmp/pterodactyl" \
-v "./{{ pterodactyl_dir }}/srv/var/lib/pterodactyl:/var/lib/pterodactyl" \
-v "./{{ pterodactyl_dir }}/srv/etc:/etc/pterodactyl/" \
ghcr.io/pterodactyl/wings:latest



stop_wings:
-@docker stop blueprint-dev-wings
-@docker rm blueprint-dev-wings

watch_sync:
#!/usr/bin/env bash
set -euo pipefail

echo "Watching Blueprint framework for changes..."
echo "📂 Syncing to: {{ pterodactyl_dir }}"

inotifywait -m -r \
-e modify,create,move \
--exclude '({{ pterodactyl_dir }}|\.git|node_modules|vendor|\.env|justfile)' \
--format '%w%f' \
. | while read -r filepath; do

[[ -f "$filepath" ]] || continue

relpath="${filepath#./}"

# Remap blueprint/ to .blueprint/
if [[ "$relpath" == blueprint/* ]]; then
relpath=".blueprint/${relpath#blueprint/}"
fi

destpath="{{ pterodactyl_dir }}/$relpath"
mkdir -p "$(dirname "$destpath")"

if cp "$filepath" "$destpath" 2>/dev/null; then
echo "[$(date +%H:%M:%S)] ✓ $relpath"
fi
done

start_db:
#!/usr/bin/env bash
if [ "$(docker ps -aq -f name=blueprint-dev-db)" ]; then
docker start blueprint-dev-db
else
docker run -d \
--name blueprint-dev-db \
-e MYSQL_ROOT_PASSWORD=root \
-e MYSQL_DATABASE=panel \
-e MYSQL_USER={{ db_username }} \
-e MYSQL_PASSWORD={{ db_password }} \
-p {{ db_port }}:3306 \
mysql:9
fi
until docker exec blueprint-dev-db sh -c "mysql -uroot -proot -e 'SELECT 1;'"; do
echo "Waiting for database..."
sleep 2
done

docker exec blueprint-dev-db mysql -uroot -proot -e "SET GLOBAL sql_mode='';"
docker exec blueprint-dev-db mysql -uroot -proot -e "CREATE DATABASE IF NOT EXISTS panel;"
docker exec blueprint-dev-db mysql -uroot -proot -e "GRANT ALL PRIVILEGES ON *.* TO '{{ db_username }}'@'%'; FLUSH PRIVILEGES;"

stop_db:
-@docker stop blueprint-dev-db
-@docker rm blueprint-dev-db

dev: blueprintrc start_db
tmux new-session -s dev \; \
send-keys 'cd {{ pterodactyl_dir }} && php -d memory_limit=1024M artisan serve --host=0.0.0.0 --port=3000' C-m \; \
split-window -h \; \
send-keys 'cd {{ pterodactyl_dir }} && yarn watch' C-m \; \
split-window -v \; \
send-keys 'just watch_sync' C-m

check-deps:
@command -v git >/dev/null 2>&1 || { echo "git is required but not installed"; exit 1; }
@command -v docker >/dev/null 2>&1 || { echo "docker is required but not installed"; exit 1; }
@command -v php >/dev/null 2>&1 || { echo "php is required but not installed"; exit 1; }
@command -v composer >/dev/null 2>&1 || { echo "composer is required but not installed"; exit 1; }
@command -v node >/dev/null 2>&1 || { echo "node is required but not installed"; exit 1; }
@command -v yarn >/dev/null 2>&1 || { echo "yarn is required but not installed"; exit 1; }
@command -v mariadb >/dev/null 2>&1 || { echo "mariadb-clients is required but not installed"; exit 1; }
@command -v inotifywait >/dev/null 2>&1 || { echo "inotify-tools is required but not installed"; exit 1; }
@command -v tmux >/dev/null 2>&1 || { echo "tmux is required but not installed"; exit 1; }
@command -v rsync >/dev/null 2>&1 || { echo "rsync is required but not installed"; exit 1; }

env_replace file key value:
#!/usr/bin/env bash
set -euo pipefail

if grep -q "^{{ key }}=" "{{ file }}"; then
sed -i "s|^{{ key }}=.*|{{ key }}={{ value }}|" "{{ file }}"
else
echo "{{ key }}={{ value }}" >> "{{ file }}"
fi
Loading