Skip to content

Universal Deployment Script Reference

Complete reference documentation for deploy-customer.sh - the universal DirectAdmin deployment script that works with any DirectAdmin hosting provider.

Overview

The deploy-customer.sh script provides automated website deployment to any DirectAdmin hosting provider with professional-grade features:

  • Universal compatibility - Works with SatoshiHost or any DirectAdmin host
  • API-first approach - Uses DirectAdmin API for reliability
  • Intelligent fallback - Manual instructions if API fails
  • Professional validation - HTML checking, permission setting, access testing
  • Git integration - Optional version control automation
  • Business ready - Supports customer management workflows

Script Usage

Basic Syntax

./deploy-customer.sh [options] domain [path] [server] [port]

Arguments

Argument Required Default Description
domain - Target domain name
path domains/DOMAIN/public_html Upload path on server
server directadmin-de.kxe.io DirectAdmin server hostname
port 2222 DirectAdmin port

Options

Option Description
--auto Run in automated mode (no prompts)
--help Show usage information

Examples

# Deploy to SatoshiHost (default)
export DA_USERNAME='customer123'
export DA_PASSWORD='password123'
./deploy-customer.sh example.com

# Deploy to external DirectAdmin host
./deploy-customer.sh client.com public_html external-host.com 2222

# Automated deployment (no prompts)
./deploy-customer.sh --auto example.com

# Show help
./deploy-customer.sh --help

Environment Variables

Required Variables

# DirectAdmin credentials (required)
export DA_USERNAME='hosting_username'  # DirectAdmin username
export DA_PASSWORD='hosting_password'  # DirectAdmin password

Optional Variables

# Server configuration (optional - intelligent defaults)
export DA_SERVER='directadmin-server.com'     # Default: directadmin-de.kxe.io
export DA_PORT='2222'                         # Default: 2222
export DA_PATH='domains/example.com/public_html' # Default: auto-generated

Script Features

1. Environment Detection

The script intelligently detects and configures the deployment environment:

# Parse command line arguments or use environment defaults
DA_DOMAIN="${1:-$DA_DOMAIN}"
DA_PATH="${2:-$DA_PATH}"
DA_SERVER="${3:-$DA_SERVER}"
DA_PORT="${4:-${DA_PORT:-2222}}"

# Set intelligent defaults
DA_PATH="${DA_PATH:-domains/$DA_DOMAIN/public_html}"    # Standard DirectAdmin path
DA_SERVER="${DA_SERVER:-directadmin-de.kxe.io}"        # SatoshiHost default

2. Credential Validation

Secure credential handling with validation:

# Security: Use environment variables only
DA_USER="$DA_USERNAME"  # Never expose credentials in command line
DA_PASS="$DA_PASSWORD"  # Secure environment variable handling

# Validate required credentials
if [[ -z "$DA_USERNAME" || -z "$DA_PASSWORD" ]]; then
    echo "❌ DirectAdmin credentials required:"
    echo "   export DA_USERNAME='your_username'"
    echo "   export DA_PASSWORD='your_password'"
    exit 1
fi

3. File Validation

HTML validation and optimization:

# Validate HTML files using HTML Tidy
if command -v tidy > /dev/null; then
    for html_file in *.html; do
        if [ -f "$html_file" ]; then
            echo "Checking $html_file..."
            tidy -q -e "$html_file" || echo "⚠️ Warnings in $html_file"
        fi
    done
else
    echo "⚠️ HTML Tidy not installed - skipping validation"
fi

4. Git Integration

Optional git workflow automation:

# Check if we're in a git repository
if git rev-parse --git-dir > /dev/null 2>&1; then
    if [[ -n $(git status --porcelain) ]]; then
        echo "📝 Changes detected:"
        git status --short

        # Handle commit message (auto or interactive)
        if $AUTO_MODE; then
            COMMIT_MSG="Deploy $DA_DOMAIN: $(date '+%Y-%m-%d %H:%M')"
        else
            read -p "Enter commit message (or press Enter to skip): " COMMIT_MSG
        fi

        # Commit if message provided
        if [[ -n "$COMMIT_MSG" ]]; then
            git add .
            git commit -m "$COMMIT_MSG"
            echo "✅ Committed: $COMMIT_MSG"
        fi
    fi
fi

5. Package Creation

Efficient file packaging for upload:

# Create timestamped deployment package
TIMESTAMP=$(date '+%Y%m%d_%H%M%S')
PACKAGE_NAME="${DA_DOMAIN}_${TIMESTAMP}.zip"

# Package all web files
if command -v zip > /dev/null; then
    zip -r "$PACKAGE_NAME" \
        *.html *.css *.js \
        *.png *.jpg *.jpeg *.gif *.svg *.ico \
        *.pdf *.md \
        2>/dev/null || {
        echo "⚠️ No files to package, will upload individually"
        PACKAGE_NAME=""
    }
else
    echo "⚠️ No zip utility found, will upload files individually"
    PACKAGE_NAME=""
fi

6. DirectAdmin API Functions

Robust API communication with error handling:

function da_api_call() {
    local endpoint="$1"
    local data="$2"
    local method="${3:-POST}"

    curl -s -X "$method" \
        "https://${DA_SERVER}:${DA_PORT}/CMD_API_${endpoint}" \
        -d "$data" \
        -u "${DA_USER}:${DA_PASS}" \
        --connect-timeout 10 \
        --max-time 30 \
        --insecure  # DirectAdmin often uses self-signed certificates
}

7. API Connection Testing

Reliable connection validation:

# Test DirectAdmin API access
echo "🔌 Connecting to $DA_SERVER:$DA_PORT..."
API_TEST=$(da_api_call "SHOW_USER_CONFIG" "" "GET" 2>/dev/null || echo "FAILED")

if [[ "$API_TEST" == "FAILED" ]] || [[ "$API_TEST" == *"error"* ]]; then
    echo "❌ DirectAdmin API connection failed!"
    # Automatic fallback to manual instructions
    show_manual_deployment_instructions
    exit 1
else
    echo "✅ DirectAdmin API connection successful!"
fi

8. File Upload

Multi-strategy upload with fallback:

# Strategy 1: Bulk ZIP upload
if [[ -n "$PACKAGE_NAME" ]]; then
    echo "📦 Uploading package: $PACKAGE_NAME"
    UPLOAD_RESULT=$(da_api_call "FILE_MANAGER" "action=upload&path=/$DA_PATH" "POST" -F "file=@$PACKAGE_NAME")

    if [[ "$UPLOAD_RESULT" == *"error"* ]] || [[ "$UPLOAD_RESULT" == "FAILED" ]]; then
        echo "❌ Package upload failed, trying individual files..."
        PACKAGE_NAME=""  # Fall back to individual uploads
    else
        echo "✅ Package uploaded successfully"
        # Extract the ZIP file
        da_api_call "FILE_MANAGER" "action=extract&path=/$DA_PATH/$PACKAGE_NAME"
        echo "✅ Package extracted"
    fi
fi

# Strategy 2: Individual file upload
if [[ -z "$PACKAGE_NAME" ]]; then
    echo "📋 Uploading individual files..."
    for file in *.html *.css *.js *.png *.jpg *.jpeg *.gif *.svg *.ico *.pdf *.md; do
        if [ -f "$file" ]; then
            echo "Uploading: $file"
            UPLOAD_RESULT=$(da_api_call "FILE_MANAGER" "action=upload&path=/$DA_PATH" "POST" -F "file=@$file")
            if [[ "$UPLOAD_RESULT" == "FAILED" ]] || [[ "$UPLOAD_RESULT" == *"error"* ]]; then
                echo "❌ Failed to upload $file"
            else
                echo "✅ Uploaded $file"
            fi
        fi
    done
fi

9. Permission Setting

Secure file permission configuration:

# Set proper file permissions (644 for files, 755 for directories)
echo "🔒 Setting proper permissions..."
for file in *.html *.css *.js *.png *.jpg *.jpeg *.gif *.svg *.ico *.pdf *.md; do
    if [ -f "$file" ]; then
        da_api_call "FILE_MANAGER" "action=chmod&path=/$DA_PATH/$file&chmod=644" >/dev/null 2>&1
        echo "Set 644: $file"
    fi
done

10. Deployment Testing

Comprehensive deployment verification:

# Test HTTP/HTTPS access
echo "📋 Testing site access..."
HTTP_STATUS=$(curl -s -o /dev/null -w "%{http_code}" "http://$DA_DOMAIN" --connect-timeout 10 2>/dev/null || echo "000")
HTTPS_STATUS=$(curl -s -o /dev/null -w "%{http_code}" "https://$DA_DOMAIN" --connect-timeout 10 2>/dev/null || echo "000")

# Report results
if [[ "$HTTP_STATUS" == "200" ]]; then
    echo "✅ HTTP access working: http://$DA_DOMAIN"
else
    echo "❌ HTTP access failed (status: $HTTP_STATUS)"
fi

if [[ "$HTTPS_STATUS" == "200" ]]; then
    echo "✅ HTTPS access working: https://$DA_DOMAIN"
elif [[ "$HTTPS_STATUS" == "000" ]]; then
    echo "⚠️ HTTPS not configured yet"
else
    echo "❌ HTTPS access failed (status: $HTTPS_STATUS)"
fi

Manual Fallback System

When API deployment fails, the script provides comprehensive manual instructions:

function show_manual_deployment_instructions() {
    echo "❌ DirectAdmin API connection failed!"
    echo "📝 Falling back to File Manager instructions..."
    echo ""
    echo "📋 Manual DirectAdmin Deployment Steps:"
    echo "   1. Login to DirectAdmin: https://$DA_SERVER:$DA_PORT"
    echo "   2. Go to File Manager"
    echo "   3. Navigate to: $DA_PATH"
    echo "   4. Upload all site files (*.html, *.css, *.js, images, etc.)"
    echo "   5. Set permissions: 644 for files, 755 for directories"
    echo "   6. Test: https://$DA_DOMAIN"
    echo ""
    echo "📋 Files to upload:"
    ls -la *.html *.css *.js *.png *.jpg *.jpeg *.gif *.svg *.ico *.pdf *.md 2>/dev/null || echo "   (Check current directory for all files)"
}

Error Handling

Connection Errors

# Handle API connection failures
if [[ "$API_TEST" == "FAILED" ]]; then
    echo "❌ API connection failed - check credentials and network"
    show_manual_deployment_instructions
    exit 1
fi

Upload Errors

# Handle upload failures with automatic retry
if [[ "$UPLOAD_RESULT" == *"error"* ]]; then
    echo "❌ Upload failed, retrying with different method..."
    # Automatic fallback to individual file upload
fi

Network Timeouts

# Robust timeout handling
curl -s -X POST \
    --connect-timeout 10 \    # Connection timeout
    --max-time 30 \          # Total operation timeout
    "$API_ENDPOINT"

Customization Options

File Type Configuration

Modify which files are deployed:

# Standard web files
FILE_PATTERNS="*.html *.css *.js *.png *.jpg *.jpeg *.gif *.svg *.ico *.pdf *.md"

# Add more file types
FILE_PATTERNS="$FILE_PATTERNS *.woff *.woff2 *.ttf *.eot *.json *.xml"

# Exclude certain files
zip -r "$PACKAGE_NAME" $FILE_PATTERNS -x "*.tmp" "*.log" "*.bak"

Path Customization

# Custom upload paths for different hosting setups
case "$DA_SERVER" in
    "satoshihost"*)
        DA_PATH="domains/$DA_DOMAIN/public_html"
        ;;
    "hostgator"*)
        DA_PATH="public_html"
        ;;
    "cpanel"*)
        DA_PATH="public_html"
        ;;
    *)
        DA_PATH="${DA_PATH:-domains/$DA_DOMAIN/public_html}"
        ;;
esac

Validation Customization

# Custom HTML validation
if command -v html5validator > /dev/null; then
    html5validator *.html
elif command -v tidy > /dev/null; then
    tidy -q -e *.html
else
    echo "⚠️ No HTML validator available"
fi

Integration Examples

WordPress Deployment

# Deploy WordPress site
wget https://wordpress.org/latest.zip
unzip latest.zip
mv wordpress/* .
rm -rf wordpress latest.zip

# Configure wp-config.php with database details
# Then deploy
./deploy-customer.sh wordpress-site.com

Static Site Generator

# Jekyll
jekyll build
cp -r _site/* .
./deploy-customer.sh jekyll-site.com

# Hugo
hugo
cp -r public/* .
./deploy-customer.sh hugo-site.com

# Gatsby
gatsby build
cp -r public/* .
./deploy-customer.sh gatsby-site.com

E-commerce Deployment

# WooCommerce
# Download WordPress + WooCommerce
# Configure database and payment settings
# Deploy with larger file limits
export DA_PATH="domains/$DOMAIN/public_html"
./deploy-customer.sh ecommerce-site.com

Performance Optimization

File Compression

# Optimize before packaging
# Compress images
for img in *.jpg *.jpeg *.png; do
    [ -f "$img" ] && jpegoptim "$img" 2>/dev/null || true
done

# Minify CSS/JS
for css in *.css; do
    [ -f "$css" ] && cleancss -o "$css" "$css" 2>/dev/null || true
done

Parallel Operations

# Upload multiple files in parallel
for file in *.html *.css *.js; do
    if [ -f "$file" ]; then
        (
            echo "Uploading: $file"
            da_api_call "FILE_MANAGER" "action=upload&path=/$DA_PATH" "POST" -F "file=@$file"
        ) &
    fi
done
wait  # Wait for all uploads to complete

Caching

# Cache API responses
API_CACHE="/tmp/da_api_cache_$$"
mkdir -p "$API_CACHE"

# Cache user config
if [ ! -f "$API_CACHE/user_config" ]; then
    da_api_call "SHOW_USER_CONFIG" "" "GET" > "$API_CACHE/user_config"
fi

Debugging

Debug Mode

# Enable debug output
set -x  # Show all commands
set -e  # Exit on errors (optional)

# Verbose curl output
export CURL_VERBOSE="-v"

Logging

# Log all operations
LOG_FILE="deployment_$(date +%Y%m%d_%H%M%S).log"
exec > >(tee "$LOG_FILE")
exec 2>&1

echo "Deployment started: $(date)"
# ... deployment operations ...
echo "Deployment completed: $(date)"

Testing

# Test individual components
# Test API connection
da_api_call "SHOW_USER_CONFIG" "" "GET"

# Test file upload
echo "test" > test.txt
da_api_call "FILE_MANAGER" "action=upload&path=/$DA_PATH" "POST" -F "file=@test.txt"

# Test site access
curl -I "https://$DA_DOMAIN"

Security Considerations

Credential Security

# ✅ Secure: Environment variables
export DA_USERNAME='username'
export DA_PASSWORD='password'
./deploy-customer.sh domain.com

# ❌ Insecure: Command line (visible in process list)
./deploy-customer.sh domain.com username password

File Permissions

# Secure script permissions
chmod 700 deploy-customer.sh     # Owner only
chmod 600 customer-config.txt    # Config files
chmod 644 *.html *.css           # Web files

Network Security

# Use HTTPS only
curl -s -X POST \
    "https://${DA_SERVER}:${DA_PORT}/CMD_API_${endpoint}" \
    --insecure  # Only for DirectAdmin self-signed certs

Summary

The deploy-customer.sh universal deployment script provides:

  • Professional reliability with comprehensive error handling
  • Universal compatibility with any DirectAdmin hosting provider
  • Business-ready features supporting customer management workflows
  • Intelligent automation with manual fallback procedures
  • Security best practices for credential and file management
  • Extensible design for customization and integration

This script transforms website deployment from a complex technical process into a simple, reliable business tool that enables developers to deliver professional services efficiently.