chore: polish repo — README badges, CHANGELOG, LICENSE, install.sh cleanup

- README: add shields.io badges, fix stack (Rust, not Node.js),
  add licensing plan table, improve structure throughout
- CHANGELOG: proper Keep a Changelog format, document v0.1.0-alpha
- LICENSE: expand source-available terms with clearer restrictions
- install.sh: strip licensing/website-api build steps (those run on
  nixpanel.io/license.nixpanel.io, not on customer servers); add
  license key prompt + activation against license.nixpanel.io; keep
  only the panel DB; fix Apache to only expose ports 2083/2087
This commit is contained in:
NixReaper
2026-04-25 05:05:04 -05:00
parent f54b5cd582
commit 8b1e42171a
4 changed files with 294 additions and 412 deletions
+113 -266
View File
@@ -1,8 +1,8 @@
#!/usr/bin/env bash
# ──────────────────────────────────────────────────────────────────────────────
# NixPanel Installer · Ubuntu 24.04 LTS · x86_64
# Installs: WHM (NixServer), cPanel (NixClient), Licensing Server,
# Website API, and all system dependencies.
# Installs the NixPanel control panel (WHM + cPanel) on a customer server.
# License validation runs against https://license.nixpanel.io
# ──────────────────────────────────────────────────────────────────────────────
set -euo pipefail
@@ -44,14 +44,13 @@ ARCH=$(uname -m)
# ── Paths ─────────────────────────────────────────────────────────────────────
INSTALL_DIR="/opt/nixpanel"
BIN_DIR="$INSTALL_DIR/bin"
KEYS_DIR="$INSTALL_DIR/keys"
LOG_DIR="/var/log/nixpanel"
STEP_DIR="/var/lib/nixpanel/install"
SRC_DIR="$INSTALL_DIR/src"
GITHUB_REPO="NixReaper/nixpanel"
LICENSING_URL="https://license.nixpanel.io"
mkdir -p "$INSTALL_DIR" "$BIN_DIR" "$KEYS_DIR" "$LOG_DIR" "$STEP_DIR" "$SRC_DIR"
chmod 700 "$KEYS_DIR"
mkdir -p "$INSTALL_DIR" "$BIN_DIR" "$LOG_DIR" "$STEP_DIR" "$SRC_DIR"
mark_done() { touch "$STEP_DIR/$1.done"; }
step_done() { [[ -f "$STEP_DIR/$1.done" ]]; }
@@ -89,13 +88,15 @@ if ! step_done "resolved_stub"; then
fi
success "Port 53 free"
# ── 3. System packages (including ondrej/php PPA for PHP 8.2 on Ubuntu 24.04) ─
# ── 3. System packages ────────────────────────────────────────────────────────
step "Installing system packages"
if ! step_done "packages"; then
export DEBIAN_FRONTEND=noninteractive
# Ensure PPA tooling is present, then add ondrej/php for PHP 8.2
# Prereqs for add-apt-repository
apt-get install -y -qq ca-certificates gnupg software-properties-common
# ondrej/php PPA is required for PHP 8.2 on Ubuntu 24.04
if ! grep -rq "ondrej/php" /etc/apt/sources.list /etc/apt/sources.list.d/ 2>/dev/null; then
info "Adding ondrej/php PPA (required for PHP 8.2 on Ubuntu 24.04)…"
add-apt-repository -y ppa:ondrej/php
@@ -120,8 +121,8 @@ if ! step_done "packages"; then
spamassassin spamc \
certbot python3-certbot-apache \
fail2ban \
nodejs npm \
openssl
mark_done "packages"
fi
success "System packages installed"
@@ -129,13 +130,10 @@ success "System packages installed"
# ── 4. Rust toolchain ─────────────────────────────────────────────────────────
step "Installing Rust toolchain"
if ! step_done "rust"; then
# Install for root (used by this script) and persist for system builds
curl -fsSL https://sh.rustup.rs | sh -s -- -y --default-toolchain stable --profile minimal
source "$HOME/.cargo/env"
rustup target add x86_64-unknown-linux-gnu
mark_done "rust"
else
# Ensure cargo is on PATH for subsequent steps
source "$HOME/.cargo/env" 2>/dev/null || true
fi
CARGO=$(command -v cargo) || error "cargo not found — Rust install may have failed"
@@ -152,47 +150,31 @@ if ! step_done "services_start"; then
fi
success "Service stack running"
# ── 6. MariaDB databases ──────────────────────────────────────────────────────
step "Configuring MariaDB databases"
# ── 6. MariaDB — panel database only ─────────────────────────────────────────
step "Configuring MariaDB"
if ! step_done "mariadb_setup"; then
DB_PASS_PANEL=$(openssl rand -hex 20)
DB_PASS_LICENSE=$(openssl rand -hex 20)
DB_PASS_WEBSITE=$(openssl rand -hex 20)
mysql -u root <<SQL
CREATE DATABASE IF NOT EXISTS nixpanel CHARACTER SET utf8mb4 COLLATE utf8mb4_unicode_ci;
CREATE DATABASE IF NOT EXISTS nixpanel_licensing CHARACTER SET utf8mb4 COLLATE utf8mb4_unicode_ci;
CREATE DATABASE IF NOT EXISTS nixpanel_website CHARACTER SET utf8mb4 COLLATE utf8mb4_unicode_ci;
CREATE USER IF NOT EXISTS 'nixpanel'@'127.0.0.1' IDENTIFIED BY '${DB_PASS_PANEL}';
CREATE USER IF NOT EXISTS 'nixpanel_license'@'127.0.0.1' IDENTIFIED BY '${DB_PASS_LICENSE}';
CREATE USER IF NOT EXISTS 'nixpanel_web'@'127.0.0.1' IDENTIFIED BY '${DB_PASS_WEBSITE}';
GRANT ALL PRIVILEGES ON nixpanel.* TO 'nixpanel'@'127.0.0.1';
GRANT ALL PRIVILEGES ON nixpanel_licensing.* TO 'nixpanel_license'@'127.0.0.1';
GRANT ALL PRIVILEGES ON nixpanel_website.* TO 'nixpanel_web'@'127.0.0.1';
CREATE DATABASE IF NOT EXISTS nixpanel CHARACTER SET utf8mb4 COLLATE utf8mb4_unicode_ci;
CREATE USER IF NOT EXISTS 'nixpanel'@'127.0.0.1' IDENTIFIED BY '${DB_PASS_PANEL}';
GRANT ALL PRIVILEGES ON nixpanel.* TO 'nixpanel'@'127.0.0.1';
FLUSH PRIVILEGES;
SQL
# Store credentials for use below
echo "$DB_PASS_PANEL" > "$INSTALL_DIR/.db_pass_panel"
echo "$DB_PASS_LICENSE" > "$INSTALL_DIR/.db_pass_license"
echo "$DB_PASS_WEBSITE" > "$INSTALL_DIR/.db_pass_website"
chmod 600 "$INSTALL_DIR"/.db_pass_*
echo "$DB_PASS_PANEL" > "$INSTALL_DIR/.db_pass_panel"
chmod 600 "$INSTALL_DIR/.db_pass_panel"
mark_done "mariadb_setup"
else
DB_PASS_PANEL=$(cat "$INSTALL_DIR/.db_pass_panel")
DB_PASS_LICENSE=$(cat "$INSTALL_DIR/.db_pass_license")
DB_PASS_WEBSITE=$(cat "$INSTALL_DIR/.db_pass_website")
fi
success "Databases created"
success "Database ready"
# ── 7. Download / update source ───────────────────────────────────────────────
# ── 7. Download / update panel source ────────────────────────────────────────
step "Downloading NixPanel source"
if ! step_done "source"; then
LATEST_TAG=$(curl -fsSL "https://api.github.com/repos/${GITHUB_REPO}/releases/latest" \
| grep '"tag_name"' | cut -d'"' -f4 || echo "main")
| grep '"tag_name"' | cut -d'"' -f4 || true)
[[ -z "$LATEST_TAG" ]] && LATEST_TAG="main"
info "Fetching tag: $LATEST_TAG"
@@ -208,223 +190,96 @@ if ! step_done "source"; then
fi
success "Source ready"
# ── 8. Build Rust binaries ────────────────────────────────────────────────────
step "Building nixpanel-licensing (Rust)"
if ! step_done "build_licensing"; then
cd "$SRC_DIR/nixpanel-licensing"
$CARGO build --release --quiet
cp target/release/nixpanel-licensing "$BIN_DIR/nixpanel-licensing"
cp target/release/keygen "$BIN_DIR/nixpanel-keygen"
chmod 755 "$BIN_DIR/nixpanel-licensing" "$BIN_DIR/nixpanel-keygen"
mark_done "build_licensing"
# ── 8. Build panel binary ─────────────────────────────────────────────────────
step "Building nixpanel (Rust)"
if ! step_done "build_panel"; then
if [[ -f "$SRC_DIR/Cargo.toml" ]]; then
cd "$SRC_DIR"
$CARGO build --release --quiet
# Copy any produced binaries
[[ -f "target/release/nixpanel" ]] && \
cp target/release/nixpanel "$BIN_DIR/nixpanel" && chmod 755 "$BIN_DIR/nixpanel"
mark_done "build_panel"
success "Panel binary built"
else
warn "Panel Rust source not yet present in repo — skipping build"
warn "This is expected during early development. Re-run installer when source is ready."
fi
fi
success "nixpanel-licensing built"
step "Building nixpanel-website-api (Rust)"
if ! step_done "build_website_api"; then
cd "$SRC_DIR/nixpanel-website/api"
$CARGO build --release --quiet
cp target/release/nixpanel-website-api "$BIN_DIR/nixpanel-website-api"
chmod 755 "$BIN_DIR/nixpanel-website-api"
mark_done "build_website_api"
fi
success "nixpanel-website-api built"
# ── 9. RSA key generation ─────────────────────────────────────────────────────
step "Generating RSA-4096 license signing keys"
if ! step_done "keygen"; then
# Run keygen from the licensing source dir so it finds ./keys/
cd "$SRC_DIR/nixpanel-licensing"
"$BIN_DIR/nixpanel-keygen"
cp keys/private.pem "$KEYS_DIR/license_private.pem"
cp keys/public.pem "$KEYS_DIR/license_public.pem"
chmod 600 "$KEYS_DIR/license_private.pem"
chmod 644 "$KEYS_DIR/license_public.pem"
mark_done "keygen"
fi
success "RSA keys generated → $KEYS_DIR"
# ── 10. Secrets ───────────────────────────────────────────────────────────────
# ── 9. Secrets ────────────────────────────────────────────────────────────────
step "Generating secrets"
if ! step_done "secrets"; then
JWT_SECRET_LICENSE=$(openssl rand -hex 64)
JWT_SECRET_WEBSITE=$(openssl rand -hex 64)
JWT_SECRET_PANEL=$(openssl rand -hex 64)
LICENSING_API_KEY=$(openssl rand -hex 32)
echo "$JWT_SECRET_LICENSE" > "$INSTALL_DIR/.jwt_license"
echo "$JWT_SECRET_WEBSITE" > "$INSTALL_DIR/.jwt_website"
echo "$JWT_SECRET_PANEL" > "$INSTALL_DIR/.jwt_panel"
echo "$LICENSING_API_KEY" > "$INSTALL_DIR/.licensing_api_key"
chmod 600 "$INSTALL_DIR"/.jwt_* "$INSTALL_DIR/.licensing_api_key"
echo "$JWT_SECRET_PANEL" > "$INSTALL_DIR/.jwt_panel"
chmod 600 "$INSTALL_DIR/.jwt_panel"
mark_done "secrets"
else
JWT_SECRET_LICENSE=$(cat "$INSTALL_DIR/.jwt_license")
JWT_SECRET_WEBSITE=$(cat "$INSTALL_DIR/.jwt_website")
JWT_SECRET_PANEL=$(cat "$INSTALL_DIR/.jwt_panel")
LICENSING_API_KEY=$(cat "$INSTALL_DIR/.licensing_api_key")
JWT_SECRET_PANEL=$(cat "$INSTALL_DIR/.jwt_panel")
fi
success "Secrets ready"
# ── 11. Environment files ─────────────────────────────────────────────────────
step "Writing environment files"
# nixpanel-licensing
cat > "$INSTALL_DIR/licensing.env" <<EOF
HOST=127.0.0.1
PORT=3000
RUST_LOG=nixpanel_licensing=info,tower_http=warn
DATABASE_URL=mysql://nixpanel_license:${DB_PASS_LICENSE}@127.0.0.1:3306/nixpanel_licensing
JWT_SECRET=${JWT_SECRET_LICENSE}
JWT_EXPIRES_IN_SECS=86400
LICENSE_PRIVATE_KEY_PATH=${KEYS_DIR}/license_private.pem
LICENSE_PUBLIC_KEY_PATH=${KEYS_DIR}/license_public.pem
LICENSE_TOKEN_TTL_DAYS=30
LICENSE_GRACE_PERIOD_DAYS=7
EOF
# nixpanel-website-api (filled in after admin prompt below)
# Written at step 13
# Main panel
cat > "$INSTALL_DIR/.env" <<EOF
NODE_ENV=production
PORT=4000
JWT_SECRET=${JWT_SECRET_PANEL}
DATABASE_URL=mysql://nixpanel:${DB_PASS_PANEL}@127.0.0.1:3306/nixpanel
INSTALL_DIR=${INSTALL_DIR}
EOF
chmod 600 "$INSTALL_DIR/licensing.env" "$INSTALL_DIR/.env"
success "Environment files written"
# ── 12. systemd — licensing server ───────────────────────────────────────────
step "Installing systemd service: nixpanel-licensing"
if ! step_done "systemd_licensing"; then
cat > /etc/systemd/system/nixpanel-licensing.service <<EOF
[Unit]
Description=NixPanel Licensing Server
Documentation=https://nixpanel.io/docs
After=network.target mariadb.service
Wants=mariadb.service
[Service]
Type=simple
User=root
ExecStart=${BIN_DIR}/nixpanel-licensing
WorkingDirectory=${INSTALL_DIR}
EnvironmentFile=${INSTALL_DIR}/licensing.env
Restart=on-failure
RestartSec=5
StandardOutput=append:${LOG_DIR}/licensing.log
StandardError=append:${LOG_DIR}/licensing-error.log
LimitNOFILE=65536
[Install]
WantedBy=multi-user.target
EOF
systemctl daemon-reload
systemctl enable nixpanel-licensing
systemctl start nixpanel-licensing
mark_done "systemd_licensing"
fi
success "nixpanel-licensing service running"
# ── 13. Admin account + website env ──────────────────────────────────────────
step "Creating admin account"
# ── 10. Admin setup ───────────────────────────────────────────────────────────
step "Panel configuration"
if ! step_done "admin_account"; then
echo ""
echo -e " ${BOLD}Create your NixPanel admin account${RESET}"
read -rp " Admin username [admin]: " ADMIN_USER
read -rp " Admin username [admin]: " ADMIN_USER
ADMIN_USER="${ADMIN_USER:-admin}"
read -rsp " Admin password: " ADMIN_PASS; echo ""
read -rsp " Confirm password: " ADMIN_PASS2; echo ""
read -rsp " Admin password: " ADMIN_PASS; echo ""
read -rsp " Confirm password: " ADMIN_PASS2; echo ""
[[ "$ADMIN_PASS" != "$ADMIN_PASS2" ]] && error "Passwords do not match"
read -rp " Admin email: " ADMIN_EMAIL
read -rp " Server hostname/domain [$(hostname -f)]: " SERVER_HOST
read -rp " Admin email: " ADMIN_EMAIL
read -rp " Server hostname/domain [$(hostname -f)]: " SERVER_HOST
SERVER_HOST="${SERVER_HOST:-$(hostname -f)}"
read -rp " NixPanel license key: " LICENSE_KEY
# Prompt for Stripe keys (can be left blank for now)
echo ""
echo -e " ${BOLD}Stripe billing (press Enter to skip — configure later in .env)${RESET}"
read -rp " Stripe secret key (sk_live_...): " STRIPE_SK; STRIPE_SK="${STRIPE_SK:-}"
read -rp " Stripe webhook secret (whsec_...): " STRIPE_WEBHOOK; STRIPE_WEBHOOK="${STRIPE_WEBHOOK:-}"
read -rp " SMTP host [smtp.mailgun.org]: " MAIL_HOST; MAIL_HOST="${MAIL_HOST:-smtp.mailgun.org}"
read -rp " SMTP user: " MAIL_USER; MAIL_USER="${MAIL_USER:-}"
read -rsp " SMTP password: " MAIL_PASS; MAIL_PASS="${MAIL_PASS:-}"; echo ""
echo "$SERVER_HOST" > "$INSTALL_DIR/.server_host"
echo "$LICENSE_KEY" > "$INSTALL_DIR/.license_key"
chmod 600 "$INSTALL_DIR/.server_host" "$INSTALL_DIR/.license_key"
# Write website-api env now that we have the answers
cat > "$INSTALL_DIR/website.env" <<EOF
HOST=127.0.0.1
PORT=4001
RUST_LOG=nixpanel_website_api=info,tower_http=warn
DATABASE_URL=mysql://nixpanel_web:${DB_PASS_WEBSITE}@127.0.0.1:3306/nixpanel_website
JWT_SECRET=${JWT_SECRET_WEBSITE}
JWT_EXPIRES_IN_SECS=604800
APP_URL=https://${SERVER_HOST}
CORS_ORIGIN=https://${SERVER_HOST}
STRIPE_SECRET_KEY=${STRIPE_SK}
STRIPE_WEBHOOK_SECRET=${STRIPE_WEBHOOK}
STRIPE_PRICE_SOLO_MONTHLY=
STRIPE_PRICE_SOLO_ANNUAL=
STRIPE_PRICE_HOST_MONTHLY=
STRIPE_PRICE_HOST_ANNUAL=
STRIPE_PRICE_AGENCY_MONTHLY=
STRIPE_PRICE_AGENCY_ANNUAL=
LICENSING_SERVER_URL=http://127.0.0.1:3000
LICENSING_SERVER_API_KEY=${LICENSING_API_KEY}
MAIL_HOST=${MAIL_HOST}
MAIL_PORT=587
MAIL_USER=${MAIL_USER}
MAIL_PASSWORD=${MAIL_PASS}
MAIL_FROM=noreply@${SERVER_HOST}
EOF
chmod 600 "$INSTALL_DIR/website.env"
# Validate license key against central server
info "Validating license key with ${LICENSING_URL}…"
SERVER_IP=$(hostname -I | awk '{print $1}')
HTTP_STATUS=$(curl -s -o /tmp/lic_resp.json -w "%{http_code}" \
-X POST "${LICENSING_URL}/api/v1/activate" \
-H "Content-Type: application/json" \
-d "{\"license_key\":\"${LICENSE_KEY}\",\"server_ip\":\"${SERVER_IP}\"}" \
2>/dev/null || echo "000")
# Create admin via main panel script
node "$INSTALL_DIR/scripts/create-admin.js" \
--username "$ADMIN_USER" \
--password "$ADMIN_PASS" \
--email "$ADMIN_EMAIL" \
2>/dev/null || warn "Admin creation script not found — set credentials via panel after install"
if [[ "$HTTP_STATUS" == "200" ]]; then
success "License activated"
elif [[ "$HTTP_STATUS" == "000" ]]; then
warn "Could not reach ${LICENSING_URL} — proceeding in grace period mode"
else
warn "License server returned HTTP ${HTTP_STATUS}:"
cat /tmp/lic_resp.json 2>/dev/null || true
echo ""
warn "Continuing install — fix license key in ${INSTALL_DIR}/.license_key and restart nixpanel"
fi
mark_done "admin_account"
else
SERVER_HOST=$(cat "$INSTALL_DIR/.server_host" 2>/dev/null || hostname -f)
fi
success "Admin account ready"
success "Panel configuration done"
# ── 14. systemd — website API ─────────────────────────────────────────────────
step "Installing systemd service: nixpanel-website-api"
if ! step_done "systemd_website"; then
cat > /etc/systemd/system/nixpanel-website-api.service <<EOF
[Unit]
Description=NixPanel Website API
Documentation=https://nixpanel.io/docs
After=network.target mariadb.service nixpanel-licensing.service
Wants=mariadb.service
[Service]
Type=simple
User=root
ExecStart=${BIN_DIR}/nixpanel-website-api
WorkingDirectory=${INSTALL_DIR}
EnvironmentFile=${INSTALL_DIR}/website.env
Restart=on-failure
RestartSec=5
StandardOutput=append:${LOG_DIR}/website-api.log
StandardError=append:${LOG_DIR}/website-api-error.log
LimitNOFILE=65536
[Install]
WantedBy=multi-user.target
# ── 11. Environment file ──────────────────────────────────────────────────────
step "Writing environment file"
cat > "$INSTALL_DIR/.env" <<EOF
RUST_LOG=nixpanel=info,tower_http=warn
PORT=4000
JWT_SECRET=${JWT_SECRET_PANEL}
DATABASE_URL=mysql://nixpanel:${DB_PASS_PANEL}@127.0.0.1:3306/nixpanel
SERVER_HOST=${SERVER_HOST:-$(hostname -f)}
LICENSING_SERVER_URL=${LICENSING_URL}
LICENSE_KEY_PATH=${INSTALL_DIR}/.license_key
INSTALL_DIR=${INSTALL_DIR}
EOF
systemctl daemon-reload
systemctl enable nixpanel-website-api
systemctl start nixpanel-website-api
mark_done "systemd_website"
fi
success "nixpanel-website-api service running"
chmod 600 "$INSTALL_DIR/.env"
success "Environment file written"
# ── 15. systemd — main panel ──────────────────────────────────────────────────
# ── 12. systemd — panel ───────────────────────────────────────────────────────
step "Installing systemd service: nixpanel"
if ! step_done "systemd_panel"; then
cat > /etc/systemd/system/nixpanel.service <<EOF
@@ -437,7 +292,7 @@ Wants=mariadb.service
[Service]
Type=simple
User=root
ExecStart=${INSTALL_DIR}/bin/nixpanel
ExecStart=${BIN_DIR}/nixpanel
WorkingDirectory=${INSTALL_DIR}
EnvironmentFile=${INSTALL_DIR}/.env
Restart=on-failure
@@ -451,16 +306,21 @@ WantedBy=multi-user.target
EOF
systemctl daemon-reload
systemctl enable nixpanel
systemctl start nixpanel
# Only start if the binary exists
if [[ -f "$BIN_DIR/nixpanel" ]]; then
systemctl start nixpanel
else
warn "Panel binary not built yet — service enabled but not started"
warn "Re-run installer after panel source is added to the repo"
fi
mark_done "systemd_panel"
fi
success "nixpanel service running"
success "nixpanel service configured"
# ── 16. Apache vhosts ─────────────────────────────────────────────────────────
# ── 13. Apache vhosts ─────────────────────────────────────────────────────────
step "Configuring Apache reverse proxies"
if ! step_done "apache_vhost"; then
# Add non-standard ports if not already present
for port in 2083 2087 4001; do
for port in 2083 2087; do
grep -q "^Listen ${port}" /etc/apache2/ports.conf \
|| echo "Listen ${port}" >> /etc/apache2/ports.conf
done
@@ -499,13 +359,6 @@ if ! step_done "apache_vhost"; then
ErrorLog /var/log/nixpanel/nixclient-error.log
CustomLog /var/log/nixpanel/nixclient-access.log combined
</VirtualHost>
# ── NixPanel Website API (port 4001) ──────────────────────────────────────────
<VirtualHost *:4001>
ProxyPreserveHost On
ProxyPass / http://127.0.0.1:4001/
ProxyPassReverse / http://127.0.0.1:4001/
</VirtualHost>
APACHEEOF
a2ensite nixpanel
@@ -514,13 +367,13 @@ APACHEEOF
fi
success "Apache vhosts configured"
# ── 17. Fail2ban ──────────────────────────────────────────────────────────────
# ── 14. Fail2ban ──────────────────────────────────────────────────────────────
step "Configuring Fail2ban"
if ! step_done "fail2ban"; then
cat > /etc/fail2ban/jail.d/nixpanel.conf <<'EOF'
[nixpanel-auth]
enabled = true
port = 2083,2087,4001
port = 2083,2087
filter = nixpanel-auth
logpath = /var/log/nixpanel/*.log
maxretry = 10
@@ -532,23 +385,20 @@ EOF
fi
success "Fail2ban configured"
# ── 18. File permissions ──────────────────────────────────────────────────────
# ── 15. File permissions ──────────────────────────────────────────────────────
step "Setting permissions"
chown -R root:root "$INSTALL_DIR"
chmod 700 "$KEYS_DIR"
chmod 600 "$INSTALL_DIR"/.env \
"$INSTALL_DIR"/licensing.env \
"$INSTALL_DIR"/website.env 2>/dev/null || true
find "$INSTALL_DIR/bin" -type f -exec chmod 755 {} \;
chmod 600 "$INSTALL_DIR/.env" 2>/dev/null || true
find "$INSTALL_DIR/bin" -type f -exec chmod 755 {} \; 2>/dev/null || true
[[ -d "$INSTALL_DIR/nixserver/dist" ]] && \
find "$INSTALL_DIR/nixserver/dist" \( -type d -exec chmod 755 {} \; -o -type f -exec chmod 644 {} \; \)
[[ -d "$INSTALL_DIR/nixclient/dist" ]] && \
find "$INSTALL_DIR/nixclient/dist" \( -type d -exec chmod 755 {} \; -o -type f -exec chmod 644 {} \; \)
success "Permissions set"
# ── 19. Service health check ──────────────────────────────────────────────────
# ── 16. Service health check ──────────────────────────────────────────────────
step "Verifying services"
sleep 2 # give systemd a moment
sleep 2
check_service() {
if systemctl is-active --quiet "$1"; then
@@ -558,11 +408,13 @@ check_service() {
fi
}
check_service nixpanel-licensing
check_service nixpanel-website-api
check_service nixpanel
check_service apache2
check_service mariadb
check_service fail2ban
if [[ -f "$BIN_DIR/nixpanel" ]]; then
check_service nixpanel
fi
# ── Done ──────────────────────────────────────────────────────────────────────
SERVER_IP=$(hostname -I | awk '{print $1}')
@@ -572,18 +424,13 @@ echo -e "${BOLD}${GREEN}━━━━━━━━━━━━━━━━━━
echo -e "${BOLD}${GREEN} NixPanel Installation Complete!${RESET}"
echo -e "${BOLD}${GREEN}━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━${RESET}"
echo ""
echo -e " ${BOLD}WHM (Admin panel):${RESET} http://${SERVER_IP}:2087"
echo -e " ${BOLD}cPanel (User panel):${RESET} http://${SERVER_IP}:2083"
echo -e " ${BOLD}Website API:${RESET} http://${SERVER_IP}:4001"
echo -e " ${BOLD}Licensing server:${RESET} http://127.0.0.1:3000 (internal only)"
echo -e " ${BOLD}WHM (Admin panel):${RESET} http://${SERVER_IP}:2087"
echo -e " ${BOLD}cPanel (User panel):${RESET} http://${SERVER_IP}:2083"
echo -e " ${BOLD}Licensing server:${RESET} ${LICENSING_URL} (central)"
echo ""
echo -e " ${BOLD}RSA public key:${RESET} ${KEYS_DIR}/license_public.pem"
echo -e " ${BOLD}Logs:${RESET} ${LOG_DIR}/"
echo -e " ${BOLD}Config:${RESET} ${INSTALL_DIR}/*.env"
echo ""
echo -e " ${YELLOW}Stripe Price IDs must still be added to:${RESET}"
echo -e " ${INSTALL_DIR}/website.env"
echo -e " ${BOLD}Logs:${RESET} ${LOG_DIR}/"
echo -e " ${BOLD}Config:${RESET} ${INSTALL_DIR}/.env"
echo ""
echo -e " To add SSL: certbot --apache"
echo -e " To restart: systemctl restart nixpanel nixpanel-licensing nixpanel-website-api"
echo -e " To restart: systemctl restart nixpanel"
echo ""