5 Commits
Author SHA1 Message Date
NixReaper 3902935f60 fix(install): read from /dev/tty so curl | bash confirmation prompt works, bump v0.5.2
set -euo pipefail causes the script to exit when read gets EOF from
the curl pipe instead of an interactive terminal. Fix by appending
'< /dev/tty || CONFIRM=Y' so the prompt reads from the actual terminal
regardless of how the script was invoked.
2026-04-12 04:39:14 -05:00
NixReaper da55367039 fix(install): remove --silent from build steps, clean node_modules before install, bump v0.5.1 2026-04-11 16:15:53 -05:00
NixReaper 55786bfa0e fix: never commit package-lock.json, clean install in update.sh, bump v0.5.0
package-lock.json generated on Windows includes win32 rollup binary but
not linux-x64-gnu, breaking the frontend build on the server.

- Add package-lock.json to .gitignore and remove it from git tracking
- update.sh: rm -rf node_modules + package-lock.json before npm install
  so the server always generates a platform-correct lock file from scratch
- update.sh: remove --silent from build steps so errors are visible
- .gitignore: fix stale whm/cpanel dist paths → nixserver/nixclient
2026-04-11 15:32:29 -05:00
NixReaper 70908745bd fix(update): discard local package-lock.json before git pull, bump v0.4.9
npm install modifies package-lock.json on the server, causing
'git pull --ff-only' to abort with 'your local changes would be
overwritten'. Add 'git checkout -- package-lock.json' before the pull
so the generated lock file never blocks updates.
2026-04-11 15:03:46 -05:00
NixReaper 0362810681 fix(login): fetch version from /api/health instead of hardcoding, bump v0.4.8
Login page had 'NixServer v0.3.2 · Port 2087' hardcoded and subtitle
said 'Web Host Manager'. Now fetches version from GET /api/health on
mount (no auth needed) and shows it dynamically. Changed subtitle to
'Admin Panel'.
2026-04-11 15:02:18 -05:00
8 changed files with 80 additions and 4040 deletions
+9 -4
View File
@@ -6,15 +6,20 @@ dist/
.DS_Store .DS_Store
Thumbs.db Thumbs.db
# package-lock.json is platform-specific (rollup native binaries differ between
# Windows dev machines and Linux servers). Never commit it — the server generates
# its own on each install.
package-lock.json
# Prisma # Prisma
server/prisma/dev.db server/prisma/dev.db
server/prisma/dev.db-journal server/prisma/dev.db-journal
# Build outputs # Build outputs
server/dist/ server/dist/
whm/dist/ nixserver/dist/
cpanel/dist/ nixclient/dist/
# Vite # Vite
whm/.vite/ nixserver/.vite/
cpanel/.vite/ nixclient/.vite/
+39
View File
@@ -6,6 +6,45 @@ Pre-1.0 versions treat MINOR as feature releases and PATCH as bug fixes.
--- ---
## [0.5.2] — 2026-04-11
### Bug Fixes
- **`curl | bash` aborts immediately at confirmation prompt** — `set -euo pipefail` caused the script to exit when `read` received EOF from the pipe instead of a terminal. Fixed by reading from `/dev/tty` directly so the prompt works correctly whether the script is piped or run from a file.
---
## [0.5.1] — 2026-04-11
### Bug Fixes
- **`install.sh` build steps used `--silent`** — errors during `npm install` and frontend/server builds were suppressed, making failures invisible. Removed `--silent` from all build commands. Also added `rm -rf node_modules package-lock.json` before `npm install` to ensure a clean platform-correct install, consistent with `update.sh`.
---
## [0.5.0] — 2026-04-11
### Bug Fixes
- **Rollup native binary missing on Linux** — `package-lock.json` was generated on Windows and committed to git. It included the Windows rollup binary (`@rollup/rollup-win32-x64-msvc`) but not the Linux one (`@rollup/rollup-linux-x64-gnu`), causing the frontend build to fail on the server with `Cannot find module @rollup/rollup-linux-x64-gnu`.
- **`package-lock.json` added to `.gitignore`** — lock files are platform-specific and must never be committed. The server now generates its own fresh lock file on every update.
- **`update.sh` now does a clean install** — deletes `node_modules/` and `package-lock.json` before `npm install` on every update run to guarantee platform-correct native binaries. Also drops `--silent` from build commands so errors are visible.
- **`.gitignore` corrected** — removed stale `whm/` and `cpanel/` dist paths, added correct `nixserver/` and `nixclient/` paths.
---
## [0.4.9] — 2026-04-11
### Bug Fixes
- **`update.sh` fails when `package-lock.json` has local changes** — `git pull --ff-only` aborted with "Your local changes would be overwritten by merge" whenever npm had modified the lock file on the server. Fixed by running `git checkout -- package-lock.json` before the pull to discard local changes to the generated lock file.
---
## [0.4.8] — 2026-04-11
### Bug Fixes
- **Login page showing stale hardcoded version** — "NixServer v0.3.2 · Port 2087" was hardcoded. Now fetches version live from `GET /api/health` (no auth required) on mount.
- **Login page subtitle** — "Web Host Manager" replaced with "Admin Panel" to remove any WHM trademark association.
---
## [0.4.7] — 2026-04-11 ## [0.4.7] — 2026-04-11
### Bug Fixes ### Bug Fixes
+11 -3
View File
@@ -1,7 +1,8 @@
import React, { useState } from 'react' import React, { useState, useEffect } from 'react'
import { useNavigate } from 'react-router-dom' import { useNavigate } from 'react-router-dom'
import { useAuth } from '../contexts/AuthContext' import { useAuth } from '../contexts/AuthContext'
import { Shield } from 'lucide-react' import { Shield } from 'lucide-react'
import axios from 'axios'
export default function Login() { export default function Login() {
const { login } = useAuth() const { login } = useAuth()
@@ -10,6 +11,13 @@ export default function Login() {
const [password, setPassword] = useState('') const [password, setPassword] = useState('')
const [error, setError] = useState('') const [error, setError] = useState('')
const [loading, setLoading] = useState(false) const [loading, setLoading] = useState(false)
const [version, setVersion] = useState<string | null>(null)
useEffect(() => {
axios.get('/api/health', { timeout: 5_000 })
.then(r => setVersion(r.data.version ?? null))
.catch(() => {})
}, [])
const handleSubmit = async (e: React.FormEvent) => { const handleSubmit = async (e: React.FormEvent) => {
e.preventDefault() e.preventDefault()
@@ -35,7 +43,7 @@ export default function Login() {
<Shield size={24} className="text-white" /> <Shield size={24} className="text-white" />
</div> </div>
<h1 className="text-white text-xl font-bold">NixServer</h1> <h1 className="text-white text-xl font-bold">NixServer</h1>
<p className="text-[#64748b] text-sm mt-1">Web Host Manager</p> <p className="text-[#64748b] text-sm mt-1">Admin Panel</p>
</div> </div>
{/* Form */} {/* Form */}
@@ -81,7 +89,7 @@ export default function Login() {
</form> </form>
<p className="text-center text-[#64748b] text-xs mt-4"> <p className="text-center text-[#64748b] text-xs mt-4">
NixServer v0.3.2 · Port 2087 NixServer{version ? ` v${version}` : ''} · Port 2087
</p> </p>
</div> </div>
</div> </div>
-4022
View File
File diff suppressed because it is too large Load Diff
+1 -1
View File
@@ -1,6 +1,6 @@
{ {
"name": "nixpanel-server", "name": "nixpanel-server",
"version": "0.4.7", "version": "0.5.2",
"private": true, "private": true,
"workspaces": [ "workspaces": [
"server", "server",
+8 -5
View File
@@ -82,6 +82,8 @@ if [[ -z "$ADMIN_EMAIL" ]]; then
ADMIN_EMAIL="admin@$(hostname -f 2>/dev/null || echo localhost)" ADMIN_EMAIL="admin@$(hostname -f 2>/dev/null || echo localhost)"
fi fi
# Redirect all interactive reads to /dev/tty so curl | bash works correctly
MARIADB_ROOT_PASS=$(openssl rand -base64 24 | tr -dc 'a-zA-Z0-9' | head -c 24) MARIADB_ROOT_PASS=$(openssl rand -base64 24 | tr -dc 'a-zA-Z0-9' | head -c 24)
JWT_SECRET=$(gen_secret) JWT_SECRET=$(gen_secret)
JWT_REFRESH_SECRET=$(gen_secret) JWT_REFRESH_SECRET=$(gen_secret)
@@ -93,7 +95,7 @@ echo " Admin username : $ADMIN_USER"
echo " Admin email : $ADMIN_EMAIL" echo " Admin email : $ADMIN_EMAIL"
echo " Admin password : $([ "$GENERATED_PASS" = "true" ] && echo "<auto-generated>" || echo "$ADMIN_PASS")" echo " Admin password : $([ "$GENERATED_PASS" = "true" ] && echo "<auto-generated>" || echo "$ADMIN_PASS")"
echo "" echo ""
read -r -p "Continue? [Y/n] " CONFIRM read -r -p "Continue? [Y/n] " CONFIRM < /dev/tty || CONFIRM="Y"
CONFIRM="${CONFIRM:-Y}" CONFIRM="${CONFIRM:-Y}"
[[ "$CONFIRM" =~ ^[Yy]$ ]] || { echo "Aborted."; exit 0; } [[ "$CONFIRM" =~ ^[Yy]$ ]] || { echo "Aborted."; exit 0; }
@@ -547,7 +549,8 @@ success ".env written"
# ── npm install ─────────────────────────────────────────────────────────────── # ── npm install ───────────────────────────────────────────────────────────────
step "Installing Node.js dependencies" step "Installing Node.js dependencies"
cd "$INSTALL_DIR" cd "$INSTALL_DIR"
npm install --silent rm -rf node_modules package-lock.json
npm install
success "npm dependencies installed" success "npm dependencies installed"
# ── Prisma generate + db push ───────────────────────────────────────────────── # ── Prisma generate + db push ─────────────────────────────────────────────────
@@ -571,10 +574,10 @@ success "Admin account and default packages seeded"
# ── Build ───────────────────────────────────────────────────────────────────── # ── Build ─────────────────────────────────────────────────────────────────────
step "Building frontends and server" step "Building frontends and server"
cd "$INSTALL_DIR" cd "$INSTALL_DIR"
npm run build --workspace=nixserver --silent npm run build --workspace=nixserver
npm run build --workspace=nixclient --silent npm run build --workspace=nixclient
cd "$INSTALL_DIR/server" cd "$INSTALL_DIR/server"
npm run build --silent npm run build
success "Build complete" success "Build complete"
# ── Set web-readable permissions on frontend assets ─────────────────────────── # ── Set web-readable permissions on frontend assets ───────────────────────────
+11 -4
View File
@@ -14,12 +14,19 @@ INSTALL_DIR="${1:-/opt/nixpanel}"
[[ -d "$INSTALL_DIR/.git" ]] || error "NixPanel not found at $INSTALL_DIR" [[ -d "$INSTALL_DIR/.git" ]] || error "NixPanel not found at $INSTALL_DIR"
step "Pulling latest code" step "Pulling latest code"
# package-lock.json is not tracked (platform-specific), but discard any other
# locally modified tracked files that could block a fast-forward pull
git -C "$INSTALL_DIR" checkout -- . 2>/dev/null || true
git -C "$INSTALL_DIR" pull --ff-only git -C "$INSTALL_DIR" pull --ff-only
success "Code updated" success "Code updated"
step "Installing dependencies" step "Installing dependencies"
cd "$INSTALL_DIR" cd "$INSTALL_DIR"
npm install --workspaces --include-workspace-root --silent # Delete node_modules and any stale lock file so npm regenerates them fresh
# for this platform (avoids the rollup native binary mismatch between
# Windows dev machines and Linux servers)
rm -rf node_modules package-lock.json
npm install --workspaces --include-workspace-root
success "Dependencies ready" success "Dependencies ready"
step "Running migrations" step "Running migrations"
@@ -30,8 +37,8 @@ success "Migrations applied"
step "Rebuilding frontends" step "Rebuilding frontends"
cd "$INSTALL_DIR" cd "$INSTALL_DIR"
npm run build --workspace=nixserver --silent npm run build --workspace=nixserver
npm run build --workspace=nixclient --silent npm run build --workspace=nixclient
# Ensure Apache (www-data) can read the rebuilt assets # Ensure Apache (www-data) can read the rebuilt assets
chmod 755 "$INSTALL_DIR/nixserver" "$INSTALL_DIR/nixclient" chmod 755 "$INSTALL_DIR/nixserver" "$INSTALL_DIR/nixclient"
find "$INSTALL_DIR/nixserver/dist" -type d -exec chmod 755 {} \; find "$INSTALL_DIR/nixserver/dist" -type d -exec chmod 755 {} \;
@@ -42,7 +49,7 @@ success "Frontends rebuilt"
step "Rebuilding server" step "Rebuilding server"
cd "$INSTALL_DIR/server" cd "$INSTALL_DIR/server"
npm run build --silent 2>/dev/null || npx tsc 2>/dev/null || true npm run build 2>/dev/null || npx tsc 2>/dev/null || true
success "Server rebuilt" success "Server rebuilt"
step "Restarting service" step "Restarting service"
+1 -1
View File
@@ -73,7 +73,7 @@ export async function buildApp() {
fastify.get('/api/health', async () => ({ fastify.get('/api/health', async () => ({
status: 'ok', status: 'ok',
version: '0.4.7', version: '0.5.2',
timestamp: new Date().toISOString(), timestamp: new Date().toISOString(),
})) }))