From ccdc21da53058a9cf225695908d448dd7ac1bb31 Mon Sep 17 00:00:00 2001 From: Naterfute Date: Sun, 8 Mar 2026 01:39:41 -0800 Subject: [PATCH 01/10] just working --- justfile | 128 +++++++++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 128 insertions(+) create mode 100644 justfile diff --git a/justfile b/justfile new file mode 100644 index 00000000..7b430884 --- /dev/null +++ b/justfile @@ -0,0 +1,128 @@ +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" + +default: setup_dev + +setup_dev: check-deps + #!/usr/bin/env bash + set -euo pipefail + + if [ ! -d {{ pterodactyl_dir }} ]; then + git clone https://github.com/pterodactyl/panel.git {{ pterodactyl_dir }} + fi + git -C {{ pterodactyl_dir }} pull || true + + cd {{ pterodactyl_dir }} + + cp -n .env.example .env + + composer update + composer i + php artisan key:generate --force + + 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 start_db + php artisan migrate --force + + 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 + docker exec blueprint-dev-db mysql -uroot -proot -e "USE panel; UPDATE users SET root_admin = 1 WHERE email = 'dev@dev.com';" + + just dev + +apply-core: + rsync -av --delete \ + --exclude='.git' --exclude='node_modules' --exclude='pterodactyl' --exclude='justfile' \ + {{ blueprint_root }}app/ {{ pterodactyl_dir }}/app/ + rsync -av --delete {{ blueprint_root }}blueprint/ {{ pterodactyl_dir }}/blueprint/ + rsync -av --delete {{ blueprint_root }}resources/ {{ pterodactyl_dir }}/resources/ + rsync -av --delete {{ blueprint_root }}routes/ {{ pterodactyl_dir }}/routes/ + rsync -av --delete {{ blueprint_root }}public/ {{ pterodactyl_dir }}/public/ + + cp {{ blueprint_root }}blueprint.sh {{ pterodactyl_dir }}/blueprint.sh + chmod +x {{ pterodactyl_dir }}/blueprint.sh + + rsync -av {{ blueprint_root }}scripts/ {{ pterodactyl_dir }} + +reinstall-blueprint: apply-core + cd {{ pterodactyl_dir }} + bash blueprint.sh + php artisan optimize:clear + php artisan view:clear + php artisan config:clear + php artisan route:clear + +core-dev: apply-core reinstall-blueprint start_db dev + +quick-apply: apply-core + cd {{ pterodactyl_dir }} + php artisan optimize:clear # minimal cache clear + blueprint -build # if already installed, to re-apply extension logic if relevant + +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: start_db + # php artisan serve --port=5000 + # yarn watch + tmux new-session -s dev \; \ + send-keys 'cd {{ pterodactyl_dir }} && php artisan serve --port=5000' C-m \; \ + split-window -h \; \ + send-keys 'cd {{ pterodactyl_dir }} && yarn watch' 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; } + +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 From 72d22ff6672cbfd596dd7adcfc37d1856420bfec Mon Sep 17 00:00:00 2001 From: Naterfute Date: Tue, 10 Mar 2026 16:24:11 -0700 Subject: [PATCH 02/10] feat: fully working dev environment setup --- justfile | 105 +++++++++++++++++++++++++++++++++++++++---------------- 1 file changed, 75 insertions(+), 30 deletions(-) diff --git a/justfile b/justfile index 7b430884..5ae4470f 100644 --- a/justfile +++ b/justfile @@ -1,15 +1,27 @@ blueprint_root := "./" -pterodactyl_dir := "./pterodactyl" +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: setup_dev +default: setup_dev install_blueprint dev -setup_dev: check-deps +blueprintrc: + #!/usr/bin/env bash + export user=$(whoami) + + cat > .blueprintrc << EOF + WEBUSER="$user" + OWNERSHIP="$user:$user" + USERSHELL="{{ USERSHELL }}" + SHORTCUT_DIR="" + EOF + +setup_dev: check-deps blueprintrc #!/usr/bin/env bash set -euo pipefail @@ -24,7 +36,7 @@ setup_dev: check-deps composer update composer i - php artisan key:generate --force + php artisan key:generate --force -n yarn install just env_replace {{ pterodactyl_dir }}/.env DB_CONNECTION {{ db_connection }} @@ -35,43 +47,71 @@ setup_dev: check-deps 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 --force + php artisan migrate --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 docker exec blueprint-dev-db mysql -uroot -proot -e "USE panel; UPDATE users SET root_admin = 1 WHERE email = 'dev@dev.com';" - just dev +install_blueprint: + #!/usr/bin/env bash + set -euo pipefail -apply-core: - rsync -av --delete \ - --exclude='.git' --exclude='node_modules' --exclude='pterodactyl' --exclude='justfile' \ - {{ blueprint_root }}app/ {{ pterodactyl_dir }}/app/ - rsync -av --delete {{ blueprint_root }}blueprint/ {{ pterodactyl_dir }}/blueprint/ - rsync -av --delete {{ blueprint_root }}resources/ {{ pterodactyl_dir }}/resources/ - rsync -av --delete {{ blueprint_root }}routes/ {{ pterodactyl_dir }}/routes/ - rsync -av --delete {{ blueprint_root }}public/ {{ pterodactyl_dir }}/public/ + 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 }}/ \ - cp {{ blueprint_root }}blueprint.sh {{ pterodactyl_dir }}/blueprint.sh chmod +x {{ pterodactyl_dir }}/blueprint.sh - rsync -av {{ blueprint_root }}scripts/ {{ pterodactyl_dir }} - -reinstall-blueprint: apply-core cd {{ pterodactyl_dir }} - bash blueprint.sh - php artisan optimize:clear - php artisan view:clear - php artisan config:clear - php artisan route:clear + rm -f .blueprint/data/internal/db/installed -core-dev: apply-core reinstall-blueprint start_db dev + bash blueprint.sh -bash -rerun-install -quick-apply: apply-core - cd {{ pterodactyl_dir }} - php artisan optimize:clear # minimal cache clear - blueprint -build # if already installed, to re-apply extension logic if relevant +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 @@ -100,13 +140,15 @@ stop_db: docker stop blueprint-dev-db docker rm blueprint-dev-db -dev: start_db +dev: blueprintrc start_db # php artisan serve --port=5000 # yarn watch tmux new-session -s dev \; \ send-keys 'cd {{ pterodactyl_dir }} && php artisan serve --port=5000' C-m \; \ split-window -h \; \ - send-keys 'cd {{ pterodactyl_dir }} && yarn watch' C-m + 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; } @@ -116,6 +158,9 @@ check-deps: @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 From c68cbe02281fd4a23196132c90628288ddaa4195 Mon Sep 17 00:00:00 2001 From: Emma Date: Sun, 8 Mar 2026 23:04:00 +0100 Subject: [PATCH 03/10] feat: allow for custom shortcut paths and dont place shortcut if path is empty untested lets hope this works --- blueprint.sh | 33 +++++++++++++++++++-------------- 1 file changed, 19 insertions(+), 14 deletions(-) diff --git a/blueprint.sh b/blueprint.sh index 09ad296b..f40ae91a 100644 --- a/blueprint.sh +++ b/blueprint.sh @@ -17,6 +17,7 @@ FOLDER=$(realpath "$(dirname "$0" 2> /dev/null)" 2> /dev/null) || FOLDER="$BLUEP OWNERSHIP="www-data:www-data" #; WEBUSER="www-data" #; USERSHELL="/bin/bash" #; +SHORTCUT_PATH="/usr/local/bin" # Check if the script is being sourced - and if so - load bash autocompletion. if [[ "${BASH_SOURCE[0]}" != "${0}" ]]; then @@ -209,20 +210,24 @@ assignflags() { # Adds the "blueprint" command to the /usr/local/bin directory and configures the correct permissions for it. placeshortcut() { - PRINT INFO "Placing Blueprint command shortcut.." - - rm -f scripts/helpers/blueprint.bak - cp "scripts/helpers/blueprint" "scripts/helpers/blueprint.bak" - sed -i "s~BLUEPRINT_FOLDER_HERE~$FOLDER~g" "scripts/helpers/blueprint.bak" - - rm -f /usr/local/bin/blueprint - mv scripts/helpers/blueprint.bak /usr/local/bin/blueprint - - { - chmod 755 \ - "$FOLDER/blueprint.sh" \ - /usr/local/bin/blueprint - } >> "$BLUEPRINT__DEBUG" + if [[ $SHORTCUT_PATH != "" ]]; then + PRINT INFO "Placing Blueprint command shortcut.." + + rm -f scripts/helpers/blueprint.bak + cp "scripts/helpers/blueprint" "scripts/helpers/blueprint.bak" + sed -i "s~BLUEPRINT_FOLDER_HERE~$FOLDER~g" "scripts/helpers/blueprint.bak" + + rm -f "$SHORTCUT_PATH/blueprint" + mv scripts/helpers/blueprint.bak "$SHORTCUT_PATH/blueprint" + + { + chmod 755 \ + "$FOLDER/blueprint.sh" \ + "$SHORTCUT_PATH/blueprint" + } >> "$BLUEPRINT__DEBUG" + else + PRINT DEBUG "Shortcut not placed as \$SHORTCUT_PATH is empty" + fi } if ! [ -x "$(command -v blueprint)" ]; then placeshortcut; fi From 9a5d8e5d97b269475f3ecf0d8dd9204de6f39757 Mon Sep 17 00:00:00 2001 From: Emma Date: Sun, 8 Mar 2026 23:05:43 +0100 Subject: [PATCH 04/10] feat: update terminology --- blueprint.sh | 14 +++++++------- 1 file changed, 7 insertions(+), 7 deletions(-) diff --git a/blueprint.sh b/blueprint.sh index f40ae91a..5b20bb36 100644 --- a/blueprint.sh +++ b/blueprint.sh @@ -17,7 +17,7 @@ FOLDER=$(realpath "$(dirname "$0" 2> /dev/null)" 2> /dev/null) || FOLDER="$BLUEP OWNERSHIP="www-data:www-data" #; WEBUSER="www-data" #; USERSHELL="/bin/bash" #; -SHORTCUT_PATH="/usr/local/bin" +SHORTCUT_DIR="/usr/local/bin" # Check if the script is being sourced - and if so - load bash autocompletion. if [[ "${BASH_SOURCE[0]}" != "${0}" ]]; then @@ -208,25 +208,25 @@ assignflags() { fi } -# Adds the "blueprint" command to the /usr/local/bin directory and configures the correct permissions for it. +# Adds the "blueprint" command to the $SHORTCUT_DIR and configures the correct permissions for it. placeshortcut() { - if [[ $SHORTCUT_PATH != "" ]]; then + if [[ $SHORTCUT_DIR != "" ]]; then PRINT INFO "Placing Blueprint command shortcut.." rm -f scripts/helpers/blueprint.bak cp "scripts/helpers/blueprint" "scripts/helpers/blueprint.bak" sed -i "s~BLUEPRINT_FOLDER_HERE~$FOLDER~g" "scripts/helpers/blueprint.bak" - rm -f "$SHORTCUT_PATH/blueprint" - mv scripts/helpers/blueprint.bak "$SHORTCUT_PATH/blueprint" + rm -f "$SHORTCUT_DIR/blueprint" + mv scripts/helpers/blueprint.bak "$SHORTCUT_DIR/blueprint" { chmod 755 \ "$FOLDER/blueprint.sh" \ - "$SHORTCUT_PATH/blueprint" + "$SHORTCUT_DIR/blueprint" } >> "$BLUEPRINT__DEBUG" else - PRINT DEBUG "Shortcut not placed as \$SHORTCUT_PATH is empty" + PRINT DEBUG "Shortcut not placed as \$SHORTCUT_DIR is empty" fi } if ! [ -x "$(command -v blueprint)" ]; then placeshortcut; fi From e28383285724dd8a361487a5e13d8fd0ce086adf Mon Sep 17 00:00:00 2001 From: Naterfute Date: Tue, 10 Mar 2026 19:53:01 -0700 Subject: [PATCH 05/10] add pterodactyl dir to gitignore for local development --- .gitignore | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/.gitignore b/.gitignore index 675f1d1f..f256e37e 100644 --- a/.gitignore +++ b/.gitignore @@ -18,6 +18,10 @@ _ide_helper_models.php .yarn public/assets/manifest.json + +# For local development with Just +pterodactyl/ + # For local development with docker # Remove if we ever put the Dockerfile in the repo .dockerignore From 773558890c1642bd0fb911899cb1be5558b6b636 Mon Sep 17 00:00:00 2001 From: Naterfute Date: Tue, 21 Apr 2026 22:02:33 -0700 Subject: [PATCH 06/10] feat(dev): auto setup wings node on first boot --- .gitignore | 1 + justfile | 54 +++++++++++++++++++++++++++++++++++++++++++----------- 2 files changed, 44 insertions(+), 11 deletions(-) diff --git a/.gitignore b/.gitignore index f256e37e..38302da7 100644 --- a/.gitignore +++ b/.gitignore @@ -21,6 +21,7 @@ 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 diff --git a/justfile b/justfile index 5ae4470f..28d28a96 100644 --- a/justfile +++ b/justfile @@ -8,7 +8,7 @@ app_url := "http://localhost:3000" app_debug := "true" USERSHELL := "/bin/bash" -default: setup_dev install_blueprint dev +default: stop_db stop_wings setup_dev install_blueprint setup_wings dev blueprintrc: #!/usr/bin/env bash @@ -32,11 +32,15 @@ setup_dev: check-deps blueprintrc cd {{ pterodactyl_dir }} - cp -n .env.example .env + if [ ! -f ".env" ]; then + cp -n .env.example .env + fi composer update composer i - php artisan key:generate --force -n + 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 }} @@ -53,7 +57,11 @@ setup_dev: check-deps blueprintrc php artisan migrate --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 - docker exec blueprint-dev-db mysql -uroot -proot -e "USE panel; UPDATE users SET root_admin = 1 WHERE email = 'dev@dev.com';" + 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 install_blueprint: #!/usr/bin/env bash @@ -83,6 +91,32 @@ install_blueprint: 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 @@ -113,7 +147,7 @@ watch_sync: fi done -start_db: +start_db: #!/usr/bin/env bash if [ "$(docker ps -aq -f name=blueprint-dev-db)" ]; then docker start blueprint-dev-db @@ -137,14 +171,12 @@ start_db: 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 + -@docker stop blueprint-dev-db + -@docker rm blueprint-dev-db -dev: blueprintrc start_db - # php artisan serve --port=5000 - # yarn watch +dev: blueprintrc start_db tmux new-session -s dev \; \ - send-keys 'cd {{ pterodactyl_dir }} && php artisan serve --port=5000' C-m \; \ + send-keys 'cd {{ pterodactyl_dir }} && php artisan serve --port=3000' C-m \; \ split-window -h \; \ send-keys 'cd {{ pterodactyl_dir }} && yarn watch' C-m \; \ split-window -v \; \ From 5205ba97e6d3babbb904922170ef06ecb1a1e83c Mon Sep 17 00:00:00 2001 From: Naterfute Date: Fri, 24 Apr 2026 15:16:15 -0700 Subject: [PATCH 07/10] fix: running the setup no longer breaks an existing install --- justfile | 21 ++++++++++++++------- 1 file changed, 14 insertions(+), 7 deletions(-) diff --git a/justfile b/justfile index 28d28a96..2500af75 100644 --- a/justfile +++ b/justfile @@ -1,3 +1,4 @@ + blueprint_root := "./" pterodactyl_dir := "pterodactyl" db_connection := "mysql" @@ -8,7 +9,9 @@ app_url := "http://localhost:3000" app_debug := "true" USERSHELL := "/bin/bash" -default: stop_db stop_wings setup_dev install_blueprint setup_wings dev +default: dev + +setup: check_dev stop_db stop_wings setup_dev install_blueprint setup_wings dev blueprintrc: #!/usr/bin/env bash @@ -21,13 +24,17 @@ blueprintrc: 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 - - if [ ! -d {{ pterodactyl_dir }} ]; then - git clone https://github.com/pterodactyl/panel.git {{ pterodactyl_dir }} - fi + git clone https://github.com/pterodactyl/panel.git {{ pterodactyl_dir }} git -C {{ pterodactyl_dir }} pull || true cd {{ pterodactyl_dir }} @@ -54,7 +61,7 @@ setup_dev: check-deps blueprintrc just env_replace {{ pterodactyl_dir }}/.env RECAPTCHA_ENABLED false just start_db - php artisan migrate --force -n + 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 @@ -176,7 +183,7 @@ stop_db: dev: blueprintrc start_db tmux new-session -s dev \; \ - send-keys 'cd {{ pterodactyl_dir }} && php artisan serve --port=3000' C-m \; \ + 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 \; \ From 1c924cac3d3d362d88ae6d4c650b15b7f7f11c2e Mon Sep 17 00:00:00 2001 From: Naterfute Date: Fri, 24 Apr 2026 15:50:07 -0700 Subject: [PATCH 08/10] auto create allocations on the wings node --- justfile | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) diff --git a/justfile b/justfile index 2500af75..7de1a3af 100644 --- a/justfile +++ b/justfile @@ -1,4 +1,3 @@ - blueprint_root := "./" pterodactyl_dir := "pterodactyl" db_connection := "mysql" @@ -68,7 +67,11 @@ setup_dev: check-deps blueprintrc 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 @@ -94,7 +97,6 @@ install_blueprint: chmod +x {{ pterodactyl_dir }}/blueprint.sh cd {{ pterodactyl_dir }} - rm -f .blueprint/data/internal/db/installed bash blueprint.sh -bash -rerun-install From cd0305144dc0d65a27b654999d1cc6fa3c73c9b9 Mon Sep 17 00:00:00 2001 From: Naterfute Date: Wed, 29 Apr 2026 15:09:01 -0700 Subject: [PATCH 09/10] fix: now using nginx on port 80 to fix server creation --- justfile | 77 ++++++++++++++++++++++++++++++++++++++++++++++++-------- 1 file changed, 67 insertions(+), 10 deletions(-) diff --git a/justfile b/justfile index 7de1a3af..53fe743e 100644 --- a/justfile +++ b/justfile @@ -4,7 +4,7 @@ db_connection := "mysql" db_username := "pterodactyl" db_password := "pterodactyl" db_port := "3006" -app_url := "http://localhost:3000" +app_url := "http://localhost" app_debug := "true" USERSHELL := "/bin/bash" @@ -23,10 +23,10 @@ blueprintrc: SHORTCUT_DIR="" EOF -check_dev: +check_dev: #!/usr/bin/env bash if [ -d {{ pterodactyl_dir }} ]; then - echo "${RED}Pterodactyl Dir exists, delete it to rerun setup${NC}" + echo "Pterodactyl Dir exists, delete it to rerun setup" exit 1 fi @@ -73,6 +73,9 @@ setup_dev: check-deps blueprintrc 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 + # Fix ownership for current user (relative paths since we're in pterodactyl_dir) + sudo chown -R $(id -u):$(id -g) storage bootstrap/cache + install_blueprint: #!/usr/bin/env bash set -euo pipefail @@ -105,7 +108,7 @@ setup_wings: check-deps stop_wings 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 + -php ./{{ pterodactyl_dir }}/artisan p:node:configuration 1 > {{ pterodactyl_dir }}/srv/etc/config.yml docker run \ -d \ @@ -119,10 +122,8 @@ setup_wings: check-deps stop_wings -v "./{{ pterodactyl_dir }}/srv/var/lib/pterodactyl:/var/lib/pterodactyl" \ -v "./{{ pterodactyl_dir }}/srv/etc:/etc/pterodactyl/" \ ghcr.io/pterodactyl/wings:latest - - -stop_wings: +stop_wings: -@docker stop blueprint-dev-wings -@docker rm blueprint-dev-wings @@ -156,7 +157,36 @@ watch_sync: fi done -start_db: +php-image: + #!/usr/bin/env bash + set -euo pipefail + if ! docker image inspect php:8.3-fpm-pdo >/dev/null 2>&1; then + echo "Building PHP 8.3 FPM image with pdo_mysql..." + echo 'RlJPTSBwaHA6OC4zLWZwbQpSVU4gZG9ja2VyLXBocC1leHQtaW5zdGFsbCBwZG9fbXlzcWwKUlVOIGFwdC1nZXQgdXBkYXRlICYmIGFwdC1nZXQgaW5zdGFsbCAteSBzdWRvClJVTiB1c2VybW9kIC11IDEwMDAgd3d3LWRhdGEgMj4vZGV2L251bGwgfHwgdHJ1ZQpSVU4gZ3JvdXBtb2QgLWcgMTAwMCB3d3ctZGF0YSAyPi9kZXYvbnVsbCB8fCB0cnVlCg==' | base64 -d | docker build -t php:8.3-fpm-pdo - + else + echo "PHP image with pdo_mysql already exists." + fi + +nginx-image: + #!/usr/bin/env bash + set -euo pipefail + if ! docker image inspect nginx:latest-user >/dev/null 2>&1; then + echo "Building Nginx image with user permissions..." + echo 'RlJPTSBuZ2lueDpsYXRlc3QKUlVOIG1rZGlyIC1wIC92YXIvY2FjaGUvbmdpbngvY2xpZW50X3RlbXAgL3Zhci9ydW4vbmdpbnggJiYgXAogICAgY2hvd24gLVIgMTAwMDoxMDAwIC92YXIvY2FjaGUvbmdpbnggL3Zhci9ydW4vbmdpbnggL3Zhci9sb2cvbmdpbnggL2V0Yy9uZ2lueC9jb25mLmQgJiYgXAogICAgc2VkIC1pICdzL3VzZXIgbmdpbng7L3VzZXIgMTAwMDoxMDAwOy8nIC9ldGMvbmdpbngvbmdpbnguY29uZgo=' | base64 -d | docker build -t nginx:latest-user - + else + echo "Nginx image with user permissions already exists." + fi + +start_panel: php-image + docker run --rm \ + --name blueprint-dev-php \ + --network host \ + -u $(id -u):$(id -g) \ + -v "$(pwd)/{{ pterodactyl_dir }}:/var/www/html" \ + -w /var/www/html \ + php:8.3-fpm-pdo + +start_db: #!/usr/bin/env bash if [ "$(docker ps -aq -f name=blueprint-dev-db)" ]; then docker start blueprint-dev-db @@ -183,14 +213,41 @@ stop_db: -@docker stop blueprint-dev-db -@docker rm blueprint-dev-db -dev: blueprintrc start_db +dev: blueprintrc start_db php-image nginx-image + # Clean up existing containers and tmux session + -@tmux kill-session -t dev 2>/dev/null || true + -@docker stop blueprint-dev-php blueprint-dev-nginx 2>/dev/null || true + -@docker rm blueprint-dev-php blueprint-dev-nginx 2>/dev/null || true + # Generate nginx config if missing + -@test -f {{ pterodactyl_dir }}/nginx.conf || just nginx-config + # Start development environment in tmux 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 \; \ + send-keys 'docker run --rm --name blueprint-dev-php --network host -u $(id -u):$(id -g) -v "$(pwd)/{{ pterodactyl_dir }}:/var/www/html" -w /var/www/html php:8.3-fpm-pdo' C-m \; \ split-window -h \; \ + send-keys 'docker run --rm --name blueprint-dev-nginx --network host -v "$(pwd)/{{ pterodactyl_dir }}/public:/var/www/html/public" -v "$(pwd)/{{ pterodactyl_dir }}/nginx.conf:/etc/nginx/conf.d/default.conf" nginx:latest-user nginx -g "daemon off;"' C-m \; \ + split-window -v \; \ send-keys 'cd {{ pterodactyl_dir }} && yarn watch' C-m \; \ split-window -v \; \ send-keys 'just watch_sync' C-m +nginx-config: + #!/usr/bin/env bash + set -euo pipefail + + CONFIG_FILE="{{ pterodactyl_dir }}/nginx.conf" + + echo "Creating Nginx config at ${CONFIG_FILE}..." + + base64 -d <<< 'c2VydmVyIHsKICAgIGxpc3RlbiA4MCBkZWZhdWx0X3NlcnZlcjsKICAgIHNlcnZlcl9uYW1lIF87CgogICAgcm9vdCAvdmFyL3d3dy9odG1sL3B1YmxpYzsKICAgIGluZGV4IGluZGV4LnBocDsKCiAgICBjbGllbnRfbWF4X2JvZHlfc2l6ZSAxMDBtOwogICAgY2xpZW50X2JvZHlfdGltZW91dCAxMjBzOwoKICAgIGFjY2Vzc19sb2cgL3Zhci9sb2cvbmdpbngvcHRlcm9kYWN0eWwuYWNjZXNzLmxvZzsKICAgIGVycm9yX2xvZyAvdmFyL2xvZy9uZ2lueC9wdGVyb2RhY3R5bC5lcnJvci5sb2cgd2FybjsKCiAgICBsb2NhdGlvbiAvIHsKICAgICAgICB0cnlfZmlsZXMgJHVyaSAkdXJpLyAvaW5kZXgucGhwPyRxdWVyeV9zdHJpbmc7CiAgICB9CgogICAgbG9jYXRpb24gfiBcLnBocCQgewogICAgICAgIGZhc3RjZ2lfcGFzcyAxMjcuMC4wLjE6OTAwMDsKICAgICAgICBmYXN0Y2dpX2luZGV4IGluZGV4LnBocDsKICAgICAgICBmYXN0Y2dpX3BhcmFtIFNDUklQVF9GSUxFTkFNRSAkZG9jdW1lbnRfcm9vdCRmYXN0Y2dpX3NjcmlwdF9uYW1lOwogICAgICAgIGluY2x1ZGUgZmFzdGNnaV9wYXJhbXM7CiAgICAgICAgZmFzdGNnaV9wYXJhbSBQSFBfVkFMVUUgInVwbG9hZF9tYXhfZmlsZXNpemU9MTAwbVxucG9zdF9tYXhfc2l6ZT0xMDBtIjsKICAgIH0KCiAgICBsb2NhdGlvbiB+KiBcLihqcGd8anBlZ3xnaWZ8cG5nfGljb3xjc3N8anN8c3ZnfHdvZmZ8dHRmfGVvdCkkIHsKICAgICAgICBleHBpcmVzIDMwZDsKICAgICAgICBhY2Nlc3NfbG9nIG9mZjsKICAgICAgICBhZGRfaGVhZGVyIENhY2hlLUNvbnRyb2wgInB1YmxpYyI7CiAgICB9CgogICAgbG9jYXRpb24gPSAvZmF2aWNvbi5pY28geyBhY2Nlc3NfbG9nIG9mZjsgbG9nX25vdF9mb3VuZCBvZmY7IH0KICAgIGxvY2F0aW9uID0gL3JvYm90cy50eHQgIHsgYWNjZXNzX2xvZyBvZmY7IGxvZ19ub3RfZm91bmQgb2ZmOyB9CgogICAgbG9jYXRpb24gfiAvXC5lbnZ8L1wuZ2l0fC9cLmJsdWVwcmludCB7CiAgICAgICAgZGVueSBhbGw7CiAgICAgICAgcmV0dXJuIDQwNDsKICAgIH0KfQo=' > "${CONFIG_FILE}" + + if [ $? -eq 0 ]; then + echo "Nginx config written to ${CONFIG_FILE}" + ls -l "${CONFIG_FILE}" + else + echo "Failed to create nginx config" + exit 1 + fi + 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; } From 44b2d63e190801cad63b9994296aa197005858a4 Mon Sep 17 00:00:00 2001 From: Naterfute Date: Wed, 29 Apr 2026 15:17:48 -0700 Subject: [PATCH 10/10] fix: forgot to proxy images --- justfile | 18 ++++++++++++------ 1 file changed, 12 insertions(+), 6 deletions(-) diff --git a/justfile b/justfile index 53fe743e..e0a7e286 100644 --- a/justfile +++ b/justfile @@ -74,7 +74,12 @@ setup_dev: check-deps blueprintrc 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 # Fix ownership for current user (relative paths since we're in pterodactyl_dir) - sudo chown -R $(id -u):$(id -g) storage bootstrap/cache + cd .. + sudo chown -R $(id -u):$(id -g) {{ pterodactyl_dir }} + + # Create storage symlink for user-uploaded content + cd {{ pterodactyl_dir }} + php artisan storage:link 2>/dev/null || true install_blueprint: #!/usr/bin/env bash @@ -220,11 +225,13 @@ dev: blueprintrc start_db php-image nginx-image -@docker rm blueprint-dev-php blueprint-dev-nginx 2>/dev/null || true # Generate nginx config if missing -@test -f {{ pterodactyl_dir }}/nginx.conf || just nginx-config + # Create storage symlink if missing + -@cd {{ pterodactyl_dir }} && test -L public/storage || php artisan storage:link 2>/dev/null || true # Start development environment in tmux tmux new-session -s dev \; \ send-keys 'docker run --rm --name blueprint-dev-php --network host -u $(id -u):$(id -g) -v "$(pwd)/{{ pterodactyl_dir }}:/var/www/html" -w /var/www/html php:8.3-fpm-pdo' C-m \; \ split-window -h \; \ - send-keys 'docker run --rm --name blueprint-dev-nginx --network host -v "$(pwd)/{{ pterodactyl_dir }}/public:/var/www/html/public" -v "$(pwd)/{{ pterodactyl_dir }}/nginx.conf:/etc/nginx/conf.d/default.conf" nginx:latest-user nginx -g "daemon off;"' C-m \; \ + send-keys 'docker run --rm --name blueprint-dev-nginx --network host -v "$(pwd)/{{ pterodactyl_dir }}:/var/www/html" -v "$(pwd)/{{ pterodactyl_dir }}/nginx.conf:/etc/nginx/conf.d/default.conf" nginx:latest-user nginx -g "daemon off;"' C-m \; \ split-window -v \; \ send-keys 'cd {{ pterodactyl_dir }} && yarn watch' C-m \; \ split-window -v \; \ @@ -238,13 +245,12 @@ nginx-config: echo "Creating Nginx config at ${CONFIG_FILE}..." - base64 -d <<< 'c2VydmVyIHsKICAgIGxpc3RlbiA4MCBkZWZhdWx0X3NlcnZlcjsKICAgIHNlcnZlcl9uYW1lIF87CgogICAgcm9vdCAvdmFyL3d3dy9odG1sL3B1YmxpYzsKICAgIGluZGV4IGluZGV4LnBocDsKCiAgICBjbGllbnRfbWF4X2JvZHlfc2l6ZSAxMDBtOwogICAgY2xpZW50X2JvZHlfdGltZW91dCAxMjBzOwoKICAgIGFjY2Vzc19sb2cgL3Zhci9sb2cvbmdpbngvcHRlcm9kYWN0eWwuYWNjZXNzLmxvZzsKICAgIGVycm9yX2xvZyAvdmFyL2xvZy9uZ2lueC9wdGVyb2RhY3R5bC5lcnJvci5sb2cgd2FybjsKCiAgICBsb2NhdGlvbiAvIHsKICAgICAgICB0cnlfZmlsZXMgJHVyaSAkdXJpLyAvaW5kZXgucGhwPyRxdWVyeV9zdHJpbmc7CiAgICB9CgogICAgbG9jYXRpb24gfiBcLnBocCQgewogICAgICAgIGZhc3RjZ2lfcGFzcyAxMjcuMC4wLjE6OTAwMDsKICAgICAgICBmYXN0Y2dpX2luZGV4IGluZGV4LnBocDsKICAgICAgICBmYXN0Y2dpX3BhcmFtIFNDUklQVF9GSUxFTkFNRSAkZG9jdW1lbnRfcm9vdCRmYXN0Y2dpX3NjcmlwdF9uYW1lOwogICAgICAgIGluY2x1ZGUgZmFzdGNnaV9wYXJhbXM7CiAgICAgICAgZmFzdGNnaV9wYXJhbSBQSFBfVkFMVUUgInVwbG9hZF9tYXhfZmlsZXNpemU9MTAwbVxucG9zdF9tYXhfc2l6ZT0xMDBtIjsKICAgIH0KCiAgICBsb2NhdGlvbiB+KiBcLihqcGd8anBlZ3xnaWZ8cG5nfGljb3xjc3N8anN8c3ZnfHdvZmZ8dHRmfGVvdCkkIHsKICAgICAgICBleHBpcmVzIDMwZDsKICAgICAgICBhY2Nlc3NfbG9nIG9mZjsKICAgICAgICBhZGRfaGVhZGVyIENhY2hlLUNvbnRyb2wgInB1YmxpYyI7CiAgICB9CgogICAgbG9jYXRpb24gPSAvZmF2aWNvbi5pY28geyBhY2Nlc3NfbG9nIG9mZjsgbG9nX25vdF9mb3VuZCBvZmY7IH0KICAgIGxvY2F0aW9uID0gL3JvYm90cy50eHQgIHsgYWNjZXNzX2xvZyBvZmY7IGxvZ19ub3RfZm91bmQgb2ZmOyB9CgogICAgbG9jYXRpb24gfiAvXC5lbnZ8L1wuZ2l0fC9cLmJsdWVwcmludCB7CiAgICAgICAgZGVueSBhbGw7CiAgICAgICAgcmV0dXJuIDQwNDsKICAgIH0KfQo=' > "${CONFIG_FILE}" - - if [ $? -eq 0 ]; then + if [ -f "nginx.conf.template" ]; then + cp nginx.conf.template "${CONFIG_FILE}" echo "Nginx config written to ${CONFIG_FILE}" ls -l "${CONFIG_FILE}" else - echo "Failed to create nginx config" + echo "Error: nginx.conf.template not found" exit 1 fi