Skip to content

Commit d79c07e

Browse files
committed
Update: Add Node.js 25 and smarter startup
Added Node.js 25 support, package manager auto-detection (npm/pnpm/yarn), and improved startup/install logic. Updated README with setup notes and troubleshooting.
1 parent 7236b01 commit d79c07e

2 files changed

Lines changed: 45 additions & 10 deletions

File tree

README.md

Lines changed: 28 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -9,13 +9,20 @@ By default, Next.js applications often bind to `localhost` (127.0.0.1). Inside a
99

1010
**This Egg fixes that** by automatically forcing the start command to listen on all interfaces (`0.0.0.0`), ensuring your site is immediately accessible after deployment.
1111

12+
It also improves startup reliability by using smarter dependency install behavior with package manager detection:
13+
14+
* `auto` mode detects lockfiles and picks `pnpm`, `yarn`, or `npm` automatically.
15+
* In `start` mode, it installs production dependencies and builds before launch.
16+
* In `dev` mode, it installs full dependencies so local development tools still work.
17+
1218
---
1319

1420
## 🧩 Supported Versions
1521

1622
This Egg comes pre-configured with **all modern Node.js versions**, selectable during installation:
1723

18-
* **Node.js 24** (Latest)
24+
* **Node.js 25** (Latest)
25+
* **Node.js 24** (LTS)
1926
* **Node.js 23**
2027
* **Node.js 22** (LTS)
2128
* **Node.js 21**
@@ -31,19 +38,36 @@ This Egg comes pre-configured with **all modern Node.js versions**, selectable d
3138

3239
* **🔌 Instant Connectivity:** Pre-configured to listen on `0.0.0.0`, solving connection timeouts.
3340
* **📦 Auto-Install:** Automatically runs `npm install` on startup if packages are missing.
34-
* **⚙️ Auto-Build:** Runs `npm run build` to ensure your production build is fresh.
41+
* **⚙️ Smart Build:** Runs `npm run build` automatically in production mode (`NODE_RUN_ENV=start`).
42+
* **🧠 Package Manager Auto-Detect:** Supports `npm`, `pnpm`, and `yarn` with optional manual override.
3543
* **🔒 Secure:** Based on the official Pterodactyl Docker images (Parkervcp/Yolks).
44+
* **✅ Better Validation:** Restricts runtime mode to `start` or `dev` to prevent invalid command values.
45+
46+
## 🔧 Recommended Variables
47+
48+
* `NODE_RUN_ENV`: `start` for production, `dev` for development.
49+
* `PACKAGE_MANAGER`: `auto` (default), `npm`, `pnpm`, or `yarn`.
3650

3751
## 📥 Installation Guide
3852

39-
1. **Download:** Get the `egg-nextjs.json` file from this repository (or copy the RAW link).
53+
1. **Download:** Get the `nextjs-egg.json` file from this repository (or copy the RAW link).
4054
2. **Import:** Go to your **Pterodactyl Admin Panel** -> **Nests** -> **Import Egg**.
4155
3. **Select Nest:** Choose the appropriate Nest (usually "NodeJS" or "Generic").
42-
4. **Upload:** Upload the JSON file.
56+
4. **Upload:** Upload `nextjs-egg.json` and complete the import wizard.
4357
5. **Deploy:** You can now create new servers using this Egg!
4458

4559
---
4660

61+
## 🛠️ Troubleshooting
62+
63+
* **Install fails with package manager errors:** Set `PACKAGE_MANAGER` manually to `npm`, `pnpm`, or `yarn` instead of `auto`.
64+
* **`pnpm` or `yarn` command not found:** Keep `PACKAGE_MANAGER=npm` or ensure Corepack is available in your selected Node image.
65+
* **Unexpected dependency behavior:** Verify lockfiles in your project root (`package-lock.json`, `pnpm-lock.yaml`, or `yarn.lock`).
66+
* **Server builds on every boot in production:** This is expected when `NODE_RUN_ENV=start`; use `dev` while iterating quickly.
67+
* **Server not reachable from outside:** Confirm your panel allocation/port is correct; this Egg already binds Next.js to `0.0.0.0`.
68+
69+
---
70+
4771
## ☕ Support My Work
4872

4973
If this Egg saved you time or fixed your server headaches, consider supporting my work! It helps me keep creating tools and fixes.

nextjs-egg.json

Lines changed: 17 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -7,9 +7,10 @@
77
"exported_at": "2025-12-17T14:00:00+01:00",
88
"name": "Next JS",
99
"author": "info@joopdev.com",
10-
"description": "Host a Next JS application. Sets type: module for ESM support. Fixed bind address.",
10+
"description": "Host a Next.js application with reliable 0.0.0.0 binding and auto package manager detection.",
1111
"features": null,
1212
"docker_images": {
13+
"Nodejs 25": "ghcr.io/parkervcp/yolks:nodejs_25",
1314
"Nodejs 24": "ghcr.io/parkervcp/yolks:nodejs_24",
1415
"Nodejs 23": "ghcr.io/parkervcp/yolks:nodejs_23",
1516
"Nodejs 22": "ghcr.io/parkervcp/yolks:nodejs_22",
@@ -19,16 +20,16 @@
1920
"Nodejs 18": "ghcr.io/parkervcp/yolks:nodejs_18"
2021
},
2122
"file_denylist": [],
22-
"startup": "if [ ! -d /home/container/node_modules ]; then mkdir -p /home/container/node_modules; fi; if [ ! \"$(ls -A /home/container)\" ]; then echo -e \"/home/container is empty.\"; if [ -n \"${GIT_URL}\" ]; then echo -e \"Git URL found, cloning...\"; if [ -z ${GIT_BRANCH} ]; then git clone ${GIT_URL} /home/container; else git clone --single-branch --branch ${GIT_BRANCH} ${GIT_URL} /home/container; fi; fi; fi; if [ ! -f /home/container/package.json ]; then echo -e \"No package.json found. Generating safely using npm init...\"; npm init -y; npm pkg set type=\"module\"; npm pkg set scripts.dev=\"next dev\"; npm pkg set scripts.build=\"next build\"; npm pkg set scripts.start=\"next start\"; echo -e \"Installing Next.js {{NEXT_VERSION}}...\"; npm install next@{{NEXT_VERSION}} react@latest react-dom@latest; else echo -e \"package.json found, skipping creation.\"; fi; if [ -d .git ] && [ \"{{AUTO_UPDATE}}\" == \"1\" ]; then git pull; fi; echo -e \"Running npm install...\"; npm install; echo -e \"Building project...\"; npm run build; echo -e \"Starting server...\"; /usr/local/bin/npx next ${NODE_RUN_ENV} -H 0.0.0.0 -p {{SERVER_PORT}}",
23+
"startup": "cd /home/container; if [ ! \"$(ls -A /home/container 2>/dev/null)\" ]; then echo -e \"/home/container is empty.\"; if [ -n \"${GIT_URL}\" ]; then echo -e \"Git URL found, cloning...\"; if [ -z \"${GIT_BRANCH}\" ]; then git clone \"${GIT_URL}\" /home/container; else git clone --single-branch --branch \"${GIT_BRANCH}\" \"${GIT_URL}\" /home/container; fi; fi; fi; if [ ! -f package.json ]; then echo -e \"No package.json found. Creating a minimal Next.js project...\"; npm init -y; npm pkg set type=\"module\"; npm pkg set scripts.dev=\"next dev\"; npm pkg set scripts.build=\"next build\"; npm pkg set scripts.start=\"next start\"; echo -e \"Installing Next.js {{NEXT_VERSION}}...\"; npm install next@{{NEXT_VERSION}} react@latest react-dom@latest; else echo -e \"package.json found, skipping creation.\"; fi; if [ -d .git ] && [ \"{{AUTO_UPDATE}}\" = \"1\" ]; then echo -e \"Auto update enabled, pulling latest changes...\"; git pull; fi; corepack enable >/dev/null 2>&1 || true; PM_CHOICE=\"${PACKAGE_MANAGER:-auto}\"; if [ \"${PM_CHOICE}\" = \"auto\" ]; then if [ -f pnpm-lock.yaml ]; then PM_CHOICE=\"pnpm\"; elif [ -f yarn.lock ]; then PM_CHOICE=\"yarn\"; else PM_CHOICE=\"npm\"; fi; fi; echo -e \"Using package manager: ${PM_CHOICE}\"; if [ \"${NODE_RUN_ENV}\" = \"dev\" ]; then if [ \"${PM_CHOICE}\" = \"pnpm\" ]; then pnpm install; elif [ \"${PM_CHOICE}\" = \"yarn\" ]; then yarn install; else npm install; fi; else if [ \"${PM_CHOICE}\" = \"pnpm\" ]; then if [ -f pnpm-lock.yaml ]; then pnpm install --prod --frozen-lockfile; else pnpm install --prod; fi; elif [ \"${PM_CHOICE}\" = \"yarn\" ]; then yarn install --production=true; else if [ -f package-lock.json ] || [ -f npm-shrinkwrap.json ]; then npm ci --omit=dev; else npm install --omit=dev; fi; fi; fi; if [ \"${NODE_RUN_ENV}\" = \"start\" ]; then echo -e \"Building project for production...\"; if [ \"${PM_CHOICE}\" = \"pnpm\" ]; then pnpm run build; elif [ \"${PM_CHOICE}\" = \"yarn\" ]; then yarn build; else npm run build; fi; fi; echo -e \"Starting Next.js with mode: ${NODE_RUN_ENV}\"; /usr/local/bin/npx next ${NODE_RUN_ENV} -H 0.0.0.0 -p {{SERVER_PORT}}",
2324
"config": {
2425
"files": "{}",
25-
"startup": "{\r\n \"done\": \"Ready on\"\r\n}",
26+
"startup": "{\r\n \"done\": \"Ready in\"\r\n}",
2627
"logs": "{}",
2728
"stop": "^^C"
2829
},
2930
"scripts": {
3031
"installation": {
31-
"script": "#!/bin/bash\r\n# NodeJS App Installation Script\r\napt update\r\napt install -y git curl jq file unzip make gcc g++ python python-dev libtool\r\n\r\nmkdir -p /mnt/server\r\ncd /mnt/server\r\n\r\nif [ -n \"${GIT_URL}\" ]; then\r\n if [[ ${GIT_URL} != *.git ]]; then\r\n GIT_URL=${GIT_URL%/} \r\n GIT_URL=${GIT_URL}.git\r\n fi\r\n\r\n if [ -z \"${USERNAME}\" ] && [ -z \"${ACCESS_TOKEN}\" ]; then\r\n echo -e \"using anon api call\"\r\n else\r\n GIT_URL=\"https://${USERNAME}:${ACCESS_TOKEN}@$(echo -e ${GIT_URL} | cut -d/ -f3-)\"\r\n fi\r\n\r\n if [ ! \"$(ls -A /mnt/server)\" ]; then\r\n echo -e \"cloning files into repo\"\r\n if [ -z ${GIT_BRANCH} ]; then\r\n git clone ${GIT_URL} .\r\n else\r\n git clone --single-branch --branch ${GIT_BRANCH} ${GIT_URL} .\r\n fi\r\n fi\r\nfi\r\n\r\nif [ -f /mnt/server/package.json ]; then\r\n /usr/local/bin/npm install --production\r\nfi\r\n\r\necho -e \"install complete\"\r\nexit 0",
32+
"script": "#!/bin/bash\r\n# NodeJS App Installation Script\r\napt update\r\napt install -y git curl jq file unzip make gcc g++ python3 libtool\r\n\r\nmkdir -p /mnt/server\r\ncd /mnt/server\r\n\r\nif [ -n \"${GIT_URL}\" ]; then\r\n if [[ ${GIT_URL} != *.git ]]; then\r\n GIT_URL=${GIT_URL%/} \r\n GIT_URL=${GIT_URL}.git\r\n fi\r\n\r\n if [ -z \"${USERNAME}\" ] && [ -z \"${ACCESS_TOKEN}\" ]; then\r\n echo -e \"using anon api call\"\r\n else\r\n GIT_URL=\"https://${USERNAME}:${ACCESS_TOKEN}@$(echo -e ${GIT_URL} | cut -d/ -f3-)\"\r\n fi\r\n\r\n if [ ! \"$(ls -A /mnt/server)\" ]; then\r\n echo -e \"cloning files into repo\"\r\n if [ -z \"${GIT_BRANCH}\" ]; then\r\n git clone \"${GIT_URL}\" .\r\n else\r\n git clone --single-branch --branch \"${GIT_BRANCH}\" \"${GIT_URL}\" .\r\n fi\r\n fi\r\nfi\r\n\r\nif [ -f /mnt/server/package.json ]; then\r\n corepack enable >/dev/null 2>&1 || true\r\n PM_CHOICE=${PACKAGE_MANAGER:-auto}\r\n\r\n if [ \"${PM_CHOICE}\" = \"auto\" ]; then\r\n if [ -f /mnt/server/pnpm-lock.yaml ]; then\r\n PM_CHOICE=pnpm\r\n elif [ -f /mnt/server/yarn.lock ]; then\r\n PM_CHOICE=yarn\r\n else\r\n PM_CHOICE=npm\r\n fi\r\n fi\r\n\r\n echo -e \"using package manager: ${PM_CHOICE}\"\r\n\r\n if [ \"${PM_CHOICE}\" = \"pnpm\" ]; then\r\n if [ -f /mnt/server/pnpm-lock.yaml ]; then\r\n pnpm install --prod --frozen-lockfile\r\n else\r\n pnpm install --prod\r\n fi\r\n elif [ \"${PM_CHOICE}\" = \"yarn\" ]; then\r\n yarn install --production=true\r\n else\r\n if [ -f /mnt/server/package-lock.json ] || [ -f /mnt/server/npm-shrinkwrap.json ]; then\r\n /usr/local/bin/npm ci --omit=dev\r\n else\r\n /usr/local/bin/npm install --omit=dev\r\n fi\r\n fi\r\nfi\r\n\r\necho -e \"install complete\"\r\nexit 0",
3233
"container": "node:20-bullseye-slim",
3334
"entrypoint": "bash"
3435
}
@@ -46,12 +47,22 @@
4647
},
4748
{
4849
"name": "Node ENV",
49-
"description": "NodeJS env (production or dev) used in start command.",
50+
"description": "Runtime mode for Next.js command: use 'start' for production or 'dev' for development.",
5051
"env_variable": "NODE_RUN_ENV",
5152
"default_value": "start",
5253
"user_viewable": true,
5354
"user_editable": true,
54-
"rules": "required|string|max:20",
55+
"rules": "required|string|in:start,dev",
56+
"field_type": "text"
57+
},
58+
{
59+
"name": "Package Manager",
60+
"description": "Choose package manager: auto (detect by lockfile), npm, pnpm, or yarn.",
61+
"env_variable": "PACKAGE_MANAGER",
62+
"default_value": "auto",
63+
"user_viewable": true,
64+
"user_editable": true,
65+
"rules": "required|string|in:auto,npm,pnpm,yarn",
5566
"field_type": "text"
5667
},
5768
{

0 commit comments

Comments
 (0)