Skip to content

Latest commit

 

History

History
732 lines (579 loc) · 19.6 KB

File metadata and controls

732 lines (579 loc) · 19.6 KB

PUQcloud Installation Script Documentation for HestiaCP (Administrative Version)

Overview

install_hestiacp_admin.sh is a comprehensive PUQcloud installation script for HestiaCP that operates with administrative privileges and provides full system control. The script automates the entire installation and configuration process of PUQcloud with support for modern technologies and security best practices.

🔧 Key Features

Administrative Functions

  • Root privileges operation - full access to system functions
  • HestiaCP CLI integration - use of built-in management commands
  • Automatic user and domain selection - interactive menus
  • System services management - Redis, Supervisor, PHP-FPM

Extended Installation Features

  • 🔴 Automatic Redis installation and configuration with password
  • 🟢 Node.js installation via official repository
  • 🔵 Laravel Horizon for queue management
  • ⚙️ Supervisor for process monitoring
  • 🎨 Automatic frontend assets compilation
  • 🔒 pcntl functions configuration for proper Horizon operation

Update Functions

  • 🔄 Regular update - standard update process
  • 💥 Hard update - with full migration rollback
  • ⏸️ Safe update - with process suspension
  • 🛡️ Security verification after update

📊 Process Flow Diagram

See diagram above

🚀 Usage

Basic Syntax

# Interactive mode
sudo bash install_hestiacp_admin.sh

# With parameters
sudo bash install_hestiacp_admin.sh [user] [domain] [admin_email] [admin_password] [admin_name]

# Example
sudo bash install_hestiacp_admin.sh myuser mydomain.com admin@mydomain.com mypassword "Admin Name"

Launch Requirements

# REQUIRED: root privileges
sudo su

# Check HestiaCP
ls /usr/local/hestia

# Check CLI commands
v-list-users

📋 Detailed Stage Description

1. Initialization and Privilege Check (Function: check_admin_privileges)

# Check if we're running as root or have admin privileges
check_admin_privileges() {
    if [ "$EUID" -ne 0 ]; then
        type_text "Error: This script must be run as root or with sudo."
        exit 1
    fi
    
    if [ ! -d "/usr/local/hestia" ]; then
        type_text "Error: HestiaCP not detected."
        exit 1
    fi
}

What happens:

  • Check execution as root (EUID -ne 0)
  • Check HestiaCP presence (/usr/local/hestia)
  • Check HestiaCP CLI commands availability (v-list-users)

2. Configuration Management (Functions: load_previous_values, save_current_values)

# Configuration file for saving previous values
SCRIPT_DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)"
CONFIG_FILE="$SCRIPT_DIR/install_config_admin.txt"

What happens:

  • Load previous values from configuration file
  • Save current settings for reuse
  • Simplify reinstallation or update process

3. HestiaCP User Selection (Function: select_hestia_user)

# Get list of users
USERS_LIST=$(v-list-users plain 2>/dev/null | awk '{print $1}' | grep -v "USER" | grep -v "^$")

# Show selection menu
type_text "Available HestiaCP users:"
for i in "${!USERS_ARRAY[@]}"; do
    echo "  $((i+1))) ${USERS_ARRAY[$i]}"
done

What happens:

  • Retrieve list of all HestiaCP users via CLI
  • Display interactive selection menu
  • Option for manual username input

4. Domain Selection (Function: select_domain)

# Get list of domains for the selected user
DOMAINS_LIST=$(v-list-web-domains "$HESTIA_USER" plain 2>/dev/null | awk '{print $1}')

# Show selection menu with domains
for i in "${!DOMAINS_ARRAY[@]}"; do
    echo "  $((i+1))) ${DOMAINS_ARRAY[$i]}"
done

What happens:

  • Retrieve domain list for selected user
  • Interactive selection from existing domains
  • Option to specify custom domain

5. Redis Installation and Configuration (Function: check_install_redis)

# Generate secure Redis password
REDIS_PASSWORD="$(tr -dc 'a-zA-Z0-9!@$%^&*()_+=-' </dev/urandom | head -c 32)"

# Install Redis server if not present
if ! command -v redis-server &> /dev/null; then
    apt update && apt install -y redis-server
fi

# Configure Redis with password authentication
echo "requirepass $REDIS_PASSWORD" >> "$REDIS_CONFIG"
echo "bind 127.0.0.1 ::1" >> "$REDIS_CONFIG"
echo "protected-mode no" >> "$REDIS_CONFIG"

What happens:

  • Generate secure Redis password (32 characters)
  • Install Redis server via apt
  • Configure password authentication
  • Restrict access to localhost only
  • Automatic Redis restart with new configuration
  • Install PHP Redis extension

6. Node.js Installation (Function: install_nodejs)

# Install Node.js and npm
if ! command -v node &> /dev/null || ! command -v npm &> /dev/null; then
    curl -fsSL https://deb.nodesource.com/setup_lts.x | bash -
    apt install -y nodejs
fi

What happens:

  • Check Node.js and npm availability
  • Add official NodeSource repository
  • Install latest LTS Node.js version
  • Verify installation success

7. Enable pcntl Functions (Function: enable_pcntl_functions)

# Enable pcntl functions for Laravel Horizon
for php_version in $($HESTIA/bin/v-list-sys-php plain); do
    PCNTL_CLI_CONFIG="/etc/php/$php_version/cli/conf.d/99-enable-pcntl.ini"
    # Remove pcntl functions from disable_functions
    CURRENT_DISABLED=$(php$php_version -i | grep "disable_functions")
    NEW_DISABLED=$(echo "$CURRENT_DISABLED" | sed 's/pcntl_[^,]*,\?//g')
    echo "disable_functions = $NEW_DISABLED" >> "$PCNTL_CLI_CONFIG"
done

What happens:

  • Get list of all installed PHP versions
  • Create configuration files for CLI and FPM
  • Remove pcntl functions from disabled list
  • Restart PHP-FPM services
  • Required for proper Laravel Horizon operation

8. Database Creation (Function: create_database)

# Generate database credentials
DB_NAME_CLEAN="puqcloud_$(tr -dc 'a-zA-Z0-9' </dev/urandom | head -c 8)"
DB_USER_CLEAN="puq_$(tr -dc 'a-zA-Z0-9' </dev/urandom | head -c 8)"
DB_PASS="$(tr -dc 'a-zA-Z0-9' </dev/urandom | head -c 16)"

# Create database via HestiaCP CLI
v-add-database "$HESTIA_USER" "$DB_NAME_CLEAN" "$DB_USER_CLEAN" "$DB_PASS"

What happens:

  • Generate random secure database and user names
  • Create database via HestiaCP CLI
  • Automatic user prefix addition
  • Fallback to manual creation on failure

9. Laravel Horizon Installation (Function: install_laravel_horizon)

# Install Horizon via Composer as target user
sudo -u "$HESTIA_USER" "$COMPOSER_PATH" require laravel/horizon --no-interaction

# Publish Horizon assets
sudo -u "$HESTIA_USER" php artisan horizon:publish

What happens:

  • Install Laravel Horizon via Composer
  • Execute commands as target user
  • Publish assets for Horizon web interface
  • Prepare for Redis queue operations

10. Frontend Assets Compilation (Function: compile_frontend_assets)

# Check if user has NVM installation
NVM_DIR="/home/$HESTIA_USER/.nvm"
if [ -d "$NVM_DIR" ]; then
    # Use NVM Node.js
    NPM_PATH="$NVM_DIR/versions/node/$NODE_VERSION/bin/npm"
else
    # Use global Node.js
    NPM_PATH=$(which npm)
fi

# Install npm dependencies and compile
sudo -u "$HESTIA_USER" "$NPM_PATH" install
sudo -u "$HESTIA_USER" "$NPM_PATH" run prod

What happens:

  • Determine npm path (NVM or global installation)
  • Clear cache and old node_modules
  • Install dependencies as user
  • Compile production assets
  • Verify mix-manifest.json creation

11. .env File Configuration (Function: improve_env_configuration)

# Get server timezone automatically
SERVER_TIMEZONE=$(get_server_timezone)

# Set basic application settings for production
sed -i "s/APP_ENV=.*/APP_ENV=production/" .env
sed -i "s/APP_DEBUG=.*/APP_DEBUG=false/" .env
sed -i "s|APP_TIMEZONE=.*|APP_TIMEZONE=${SERVER_TIMEZONE}|" .env

# Redis configuration with password
sed -i "s/REDIS_CLIENT=.*/REDIS_CLIENT=phpredis/" .env
echo "REDIS_PASSWORD=${REDIS_PASSWORD}" >> .env

What happens:

  • Automatic server timezone detection
  • Configure production environment (DEBUG=false)
  • Configure Redis with password
  • Set queues and cache to Redis
  • Set TEMPLATE_CLIENT=puqcloud (critically important!)

12. Supervisor Configuration (Function: configure_supervisor)

# Create Horizon configuration for Supervisor
cat <<EOL > /etc/supervisor/conf.d/horizon-${HESTIA_USER}-${DOMAIN}.conf
[program:horizon-${HESTIA_USER}-${DOMAIN}]
process_name=%(program_name)s
command=php $PROJECT_PATH/artisan horizon
autostart=true
autorestart=true
user=$HESTIA_USER
redirect_stderr=true
stdout_logfile=$PROJECT_PATH/storage/logs/horizon.log
stopwaitsecs=3600
EOL

# Reload and start
supervisorctl reread
supervisorctl update
supervisorctl start horizon-${HESTIA_USER}-${DOMAIN}

What happens:

  • Create Supervisor configuration for Horizon
  • Unique program name for each user/domain
  • Automatic start and restart
  • Logging to storage/logs/horizon.log
  • Proper process termination (stopwaitsecs=3600)

13. Cron Jobs Configuration (Function: setup_cron_jobs)

# Check for existing Laravel scheduler cron job
find_laravel_cron_job() {
    v-list-cron-jobs "$HESTIA_USER" plain | grep "artisan schedule:run" | awk '{print $1}'
}

# Create new cron job via HestiaCP CLI
CRON_COMMAND="cd $PROJECT_PATH && php artisan schedule:run >> /dev/null 2>&1"
v-add-cron-job "$HESTIA_USER" "*" "*" "*" "*" "*" "$CRON_COMMAND"

What happens:

  • Check existing cron jobs via HestiaCP CLI
  • Update existing job or create new one
  • Use HestiaCP CLI for cron management
  • Fallback to standard crontab on failure
  • Configure Laravel Scheduler (every minute)

14. Update Process (Function: update_application)

# Suspend Laravel scheduler before update
suspend_laravel_cron_job() {
    CRON_JOB_ID=$(find_laravel_cron_job true)
    v-suspend-cron-job "$HESTIA_USER" "$CRON_JOB_ID" no
}

# Hard update option with migration rollback
if [[ "$hard_update" == "Yes" ]]; then
    while [ $ROLLBACK_COUNT -lt $MAX_ROLLBACKS ]; do
        sudo -u "$HESTIA_USER" php artisan migrate:rollback --force --step=1
        ROLLBACK_COUNT=$((ROLLBACK_COUNT + 1))
    done
fi

What happens:

  • Suspend cron jobs before update
  • Stop Horizon processes
  • Optional hard update with full migration rollback
  • Safe rollback counter (maximum 50)
  • Update repository and dependencies
  • Resume all processes after update

15. Security Verification (Function: verify_production_security)

# Check production security settings
verify_production_security() {
    DEBUG_SETTING=$(grep "^APP_DEBUG=" .env | cut -d'=' -f2)
    if [[ "$DEBUG_SETTING" == "false" ]]; then
        type_text "✓ APP_DEBUG is safely set to false"
    fi
    
    ENV_SETTING=$(grep "^APP_ENV=" .env | cut -d'=' -f2)
    if [[ "$ENV_SETTING" == "production" ]]; then
        type_text "✓ APP_ENV is correctly set to production"
    fi
}

What happens:

  • Check APP_DEBUG=false
  • Check APP_ENV=production
  • Check LOG_LEVEL=error
  • Check Redis password presence
  • Warnings about insecure settings

🔧 Technical Features

User and Permission Management

# All commands executed as target user
sudo -u "$HESTIA_USER" command

# Proper user path configuration
PATH="/home/$HESTIA_USER/.local/bin:$PATH"

# File ownership configuration
chown -R "$HESTIA_USER:www-data" "$PROJECT_PATH"

Error Handling and Fallback Mechanisms

# Example of safe installation with fallback
if v-add-database "$HESTIA_USER" "$DB_NAME_CLEAN" "$DB_USER_CLEAN" "$DB_PASS"; then
    type_text "✓ Database created successfully!"
else
    type_text "❌ Failed to create database via HestiaCP CLI."
    type_text "Please create database manually..."
    read -p "Press Enter after creating the database..."
fi

Automatic Environment Detection

# Server timezone detection
get_server_timezone() {
    if command -v timedatectl &> /dev/null; then
        timezone=$(timedatectl show --property=Timezone --value)
    elif [ -f /etc/timezone ]; then
        timezone=$(cat /etc/timezone)
    else
        timezone="UTC"
    fi
    echo "$timezone"
}

⚠️ Important Notes

Security Requirements

  1. Must run with sudo - script requires root privileges
  2. Redis password protection - automatically generates secure password
  3. Production settings - APP_DEBUG=false, LOG_LEVEL=error
  4. File permissions - proper file ownership configuration

Limitations

  1. HestiaCP only - script doesn't work without HestiaCP CLI
  2. Internet required - for downloading dependencies and repository
  3. Linux only - uses systemctl, apt and other Linux tools

Usage Recommendations

  1. Test on dev environment before production
  2. Make backups before updates
  3. Check logs after installation
  4. Monitor Horizon via web interface

📝 Conclusion

The install_hestiacp_admin.sh installation script provides a powerful and secure way to deploy PUQcloud in HestiaCP environment with modern technologies and best practices. Complete automation of all installation aspects makes the process fast and reliable, while advanced update and monitoring functions ensure easy system maintenance.

📖 Practical Usage Examples

Example 1: Initial Installation

# Connect to server
ssh root@your-server.com

# Download script
wget https://raw.githubusercontent.com/your-repo/install_hestiacp_admin.sh
chmod +x install_hestiacp_admin.sh

# Run interactive installation
sudo bash install_hestiacp_admin.sh

# Select user from list:
# Available HestiaCP users:
#   1) user1
#   2) user2
#   3) testuser
# Select HestiaCP user (1-3 or 0): 2

# Select domain:
# Available domains for user user2:
#   1) example.com
#   2) test.com
# Select domain (1-2 or 0): 1

# Enter administrator data:
# Enter admin email: admin@example.com
# Enter admin password: [secure password]
# Enter admin name: Administrator

Example 2: Automated Installation with Parameters

sudo bash install_hestiacp_admin.sh user2 example.com admin@example.com "SecurePass123" "Site Administrator"

Example 3: System Update

# Regular update
sudo bash install_hestiacp_admin.sh
# Select user and domain
# Select "update"
# Select "No" for hard update

# Hard update (with migration rollback)
sudo bash install_hestiacp_admin.sh
# Select user and domain
# Select "update"
# Select "Yes" for hard update

🔍 Monitoring and Status Check

Check Installed Services

# Redis status
systemctl status redis-server
redis-cli -a "your_redis_password" ping

# Supervisor and Horizon status
supervisorctl status
supervisorctl status horizon-user-domain

# Cron jobs status
v-list-cron-jobs username
crontab -u username -l

# Check Horizon logs
tail -f /home/username/web/domain.com/public_html/storage/logs/horizon.log

Laravel Configuration Check

cd /home/username/web/domain.com/public_html

# Check application status
sudo -u username php artisan about

# Check Horizon status
sudo -u username php artisan horizon:status

# Check queues
sudo -u username php artisan queue:monitor

# Check scheduled tasks
sudo -u username php artisan schedule:list

🚨 Troubleshooting

Issue: Redis won't start after password installation

# Check Redis logs
journalctl -u redis-server -n 50

# Check configuration
grep "requirepass" /etc/redis/redis.conf

# Restart with correct configuration
systemctl restart redis-server

# Test connection
redis-cli -a "your_password" ping

Issue: Horizon won't start

# Check pcntl functions
php -m | grep pcntl

# Check Supervisor configuration
cat /etc/supervisor/conf.d/horizon-*

# Restart Supervisor
supervisorctl reread
supervisorctl update
supervisorctl restart horizon-user-domain

# Check logs
tail -f /home/user/web/domain.com/public_html/storage/logs/horizon.log

Issue: Frontend assets won't compile

# Check Node.js
node --version
npm --version

# Check permissions
ls -la /home/user/web/domain.com/public_html/node_modules/

# Manual compilation
cd /home/user/web/domain.com/public_html
sudo -u user npm install --force
sudo -u user npm run prod

# Check result
ls -la public/css/ public/js/
cat public/mix-manifest.json

Issue: Cron jobs not executing

# Check cron jobs in HestiaCP
v-list-cron-jobs username

# Check cron job status
v-list-cron-job username job_id

# Check cron logs
grep "schedule:run" /var/log/syslog

# Manual scheduler run
cd /home/user/web/domain.com/public_html
sudo -u user php artisan schedule:run

Issue: Database unavailable

# Check MySQL connection
mysql -u database_user -p database_name

# Check .env configuration
grep "DB_" /home/user/web/domain.com/public_html/.env

# Test Laravel connection
cd /home/user/web/domain.com/public_html
sudo -u user php artisan migrate:status

🎯 Main Advantages of Admin Script

✅ Complete Automation

  • User management - automatic selection from HestiaCP users list
  • Domain management - interactive selection from existing domains
  • Dependency installation - automatic installation of all required components

🔧 Advanced Features

  • Redis with password - automatic installation and secure configuration
  • Node.js - installation via official NodeSource repository
  • Laravel Horizon - complete queue management setup
  • Supervisor - automatic process monitoring configuration
  • pcntl functions - automatic enablement for proper Horizon operation

🛡️ Security and Reliability

  • Production settings - automatic secure environment configuration
  • HestiaCP CLI integration - use of built-in management commands
  • Hard update support - ability to fully rollback migrations
  • Extended security verification - control of critical settings
  • Complete assets compilation - modern frontend with optimization

🛠️ Script Customization

Change Repository

# In script change variable
REPO_URL="https://github.com/your-custom/repo.git"

Add Additional PHP Extensions

# In install_additional_php_extensions function add
REQUIRED_EXTENSIONS=(
    # ... existing extensions ...
    "php$PHP_VERSION-imagick"
    "php$PHP_VERSION-gd"
    "php$PHP_VERSION-intl"
)

Configure Additional Services

# Add function for your service
install_your_service() {
    type_text "Installing your custom service..."
    apt install -y your-service
    systemctl enable your-service
    systemctl start your-service
}

# Call in main process
install_your_service

📚 Additional Resources

Useful HestiaCP CLI Commands

# User management
v-list-users
v-add-user username password email

# Domain management  
v-list-web-domains username
v-add-web-domain username domain.com

# Database management
v-list-databases username
v-add-database username dbname dbuser dbpass

# Cron job management
v-list-cron-jobs username
v-add-cron-job username min hour day month wday command
v-suspend-cron-job username job_id
v-unsuspend-cron-job username job_id

Configuration Files

# HestiaCP configuration
/usr/local/hestia/conf/hestia.conf

# Redis configuration
/etc/redis/redis.conf

# Supervisor configuration
/etc/supervisor/conf.d/

# PHP configuration
/etc/php/*/cli/conf.d/
/etc/php/*/fpm/conf.d/

Important Paths

# User domain
/home/username/web/domain.com/public_html/

# HestiaCP logs
/home/username/web/domain.com/logs/

# Laravel logs
/home/username/web/domain.com/public_html/storage/logs/

# Backups
/home/username/web/domain.com/private/

📞 Support

When encountering issues:

  1. Check logs of all services
  2. Ensure file permissions are correct
  3. Check status of all services (Redis, Supervisor, PHP-FPM)
  4. Check .env file configuration
  5. Refer to Laravel and HestiaCP documentation

For help, create an issue with detailed problem description and include:

  • Script version
  • HestiaCP version
  • PHP version
  • Error logs
  • Output of php artisan about command