mirror of
https://github.com/Grace-Solutions/Depl0y-Custom.git
synced 2026-07-26 11:28:19 +00:00
Initial Commit
This commit is contained in:
@@ -0,0 +1,344 @@
|
||||
#!/bin/bash
|
||||
|
||||
# Depl0y Native Installation Script (No Docker)
|
||||
# This script sets up Depl0y directly on the host system
|
||||
|
||||
set -e
|
||||
|
||||
echo "========================================="
|
||||
echo " Depl0y Native Installation"
|
||||
echo "========================================="
|
||||
echo ""
|
||||
|
||||
# Check if running as root
|
||||
if [ "$EUID" -ne 0 ]; then
|
||||
echo "Please run as root (use sudo)"
|
||||
exit 1
|
||||
fi
|
||||
|
||||
# Get the script directory
|
||||
SCRIPT_DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)"
|
||||
PROJECT_DIR="$(dirname "$SCRIPT_DIR")"
|
||||
|
||||
echo "Installing to: $PROJECT_DIR"
|
||||
echo ""
|
||||
|
||||
# Detect OS
|
||||
if [ -f /etc/os-release ]; then
|
||||
. /etc/os-release
|
||||
OS=$ID
|
||||
else
|
||||
echo "Cannot detect OS. Exiting."
|
||||
exit 1
|
||||
fi
|
||||
|
||||
echo "Detected OS: $OS"
|
||||
echo ""
|
||||
|
||||
# Install system dependencies
|
||||
echo "Installing system dependencies..."
|
||||
if [ "$OS" = "ubuntu" ] || [ "$OS" = "debian" ]; then
|
||||
apt-get update
|
||||
apt-get install -y \
|
||||
python3 \
|
||||
python3-venv \
|
||||
python3-pip \
|
||||
mariadb-server \
|
||||
nginx \
|
||||
nodejs \
|
||||
npm \
|
||||
gcc \
|
||||
g++ \
|
||||
libmariadb-dev \
|
||||
pkg-config \
|
||||
git
|
||||
elif [ "$OS" = "centos" ] || [ "$OS" = "rhel" ] || [ "$OS" = "rocky" ] || [ "$OS" = "almalinux" ]; then
|
||||
yum install -y epel-release
|
||||
yum install -y \
|
||||
python311 \
|
||||
python3-pip \
|
||||
mariadb-server \
|
||||
nginx \
|
||||
nodejs \
|
||||
npm \
|
||||
gcc \
|
||||
gcc-c++ \
|
||||
mariadb-devel \
|
||||
git
|
||||
else
|
||||
echo "Unsupported OS: $OS"
|
||||
exit 1
|
||||
fi
|
||||
|
||||
echo "System dependencies installed"
|
||||
echo ""
|
||||
|
||||
# Start and enable MariaDB
|
||||
echo "Configuring MariaDB..."
|
||||
systemctl enable mariadb
|
||||
systemctl start mariadb
|
||||
|
||||
# Secure MariaDB installation
|
||||
DB_ROOT_PASSWORD=$(openssl rand -hex 16)
|
||||
mysql -e "ALTER USER 'root'@'localhost' IDENTIFIED BY '${DB_ROOT_PASSWORD}';" || true
|
||||
mysql -u root -p"${DB_ROOT_PASSWORD}" -e "DELETE FROM mysql.user WHERE User='';" || true
|
||||
mysql -u root -p"${DB_ROOT_PASSWORD}" -e "DELETE FROM mysql.user WHERE User='root' AND Host NOT IN ('localhost', '127.0.0.1', '::1');" || true
|
||||
mysql -u root -p"${DB_ROOT_PASSWORD}" -e "DROP DATABASE IF EXISTS test;" || true
|
||||
mysql -u root -p"${DB_ROOT_PASSWORD}" -e "DELETE FROM mysql.db WHERE Db='test' OR Db='test\\_%';" || true
|
||||
mysql -u root -p"${DB_ROOT_PASSWORD}" -e "FLUSH PRIVILEGES;" || true
|
||||
|
||||
# Create database and user
|
||||
DB_PASSWORD=$(openssl rand -hex 16)
|
||||
mysql -u root -p"${DB_ROOT_PASSWORD}" << EOF
|
||||
CREATE DATABASE IF NOT EXISTS depl0y;
|
||||
CREATE USER IF NOT EXISTS 'depl0y'@'localhost' IDENTIFIED BY '${DB_PASSWORD}';
|
||||
GRANT ALL PRIVILEGES ON depl0y.* TO 'depl0y'@'localhost';
|
||||
FLUSH PRIVILEGES;
|
||||
EOF
|
||||
|
||||
echo "MariaDB configured"
|
||||
echo ""
|
||||
|
||||
# Create application user
|
||||
echo "Creating depl0y user..."
|
||||
useradd -r -s /bin/bash -d /opt/depl0y -m depl0y || true
|
||||
|
||||
# Create directories
|
||||
echo "Creating directories..."
|
||||
mkdir -p /opt/depl0y/{backend,frontend}
|
||||
mkdir -p /var/lib/depl0y/{isos,cloud-init,ssh_keys}
|
||||
mkdir -p /var/log/depl0y
|
||||
mkdir -p /etc/depl0y
|
||||
|
||||
# Copy application files
|
||||
echo "Copying application files..."
|
||||
cp -r "$PROJECT_DIR/backend"/* /opt/depl0y/backend/
|
||||
cp -r "$PROJECT_DIR/frontend"/* /opt/depl0y/frontend/
|
||||
|
||||
# Set permissions
|
||||
chown -R depl0y:depl0y /opt/depl0y
|
||||
chown -R depl0y:depl0y /var/lib/depl0y
|
||||
chown -R depl0y:depl0y /var/log/depl0y
|
||||
|
||||
# Generate secrets
|
||||
echo "Generating secrets..."
|
||||
SECRET_KEY=$(openssl rand -hex 32)
|
||||
ENCRYPTION_KEY=$(python3 -c "from cryptography.fernet import Fernet; print(Fernet.generate_key().decode())")
|
||||
|
||||
# Create environment file
|
||||
cat > /etc/depl0y/config.env << EOF
|
||||
# Database Configuration
|
||||
DATABASE_URL=mysql+pymysql://depl0y:${DB_PASSWORD}@localhost:3306/depl0y
|
||||
|
||||
# Security
|
||||
SECRET_KEY=${SECRET_KEY}
|
||||
ENCRYPTION_KEY=${ENCRYPTION_KEY}
|
||||
DEBUG=false
|
||||
|
||||
# Application Settings
|
||||
LOG_LEVEL=INFO
|
||||
LOG_FILE=/var/log/depl0y/app.log
|
||||
|
||||
# Storage Paths
|
||||
ISO_STORAGE_PATH=/var/lib/depl0y/isos
|
||||
CLOUDINIT_TEMPLATE_PATH=/var/lib/depl0y/cloud-init
|
||||
SSH_KEY_PATH=/var/lib/depl0y/ssh_keys
|
||||
|
||||
# API
|
||||
API_V1_PREFIX=/api/v1
|
||||
EOF
|
||||
|
||||
chmod 600 /etc/depl0y/config.env
|
||||
chown depl0y:depl0y /etc/depl0y/config.env
|
||||
|
||||
# Install Python dependencies
|
||||
echo "Installing Python dependencies..."
|
||||
cd /opt/depl0y/backend
|
||||
sudo -u depl0y python3 -m venv venv
|
||||
sudo -u depl0y /opt/depl0y/backend/venv/bin/pip install --upgrade pip
|
||||
sudo -u depl0y /opt/depl0y/backend/venv/bin/pip install -r requirements.txt
|
||||
|
||||
# Initialize database
|
||||
echo "Initializing database..."
|
||||
cd /opt/depl0y/backend
|
||||
sudo -u depl0y bash -c "source venv/bin/activate && source /etc/depl0y/config.env && python3 -c 'from app.core.database import init_db; init_db()'"
|
||||
|
||||
# Build frontend
|
||||
echo "Building frontend..."
|
||||
cd /opt/depl0y/frontend
|
||||
sudo -u depl0y npm install
|
||||
sudo -u depl0y npm run build
|
||||
|
||||
# Create systemd service for backend
|
||||
echo "Creating systemd service..."
|
||||
cat > /etc/systemd/system/depl0y-backend.service << 'EOF'
|
||||
[Unit]
|
||||
Description=Depl0y Backend API
|
||||
After=network.target mariadb.service
|
||||
Wants=mariadb.service
|
||||
|
||||
[Service]
|
||||
Type=simple
|
||||
User=depl0y
|
||||
Group=depl0y
|
||||
WorkingDirectory=/opt/depl0y/backend
|
||||
EnvironmentFile=/etc/depl0y/config.env
|
||||
ExecStart=/opt/depl0y/backend/venv/bin/uvicorn app.main:app --host 127.0.0.1 --port 8000
|
||||
Restart=always
|
||||
RestartSec=10
|
||||
|
||||
[Install]
|
||||
WantedBy=multi-user.target
|
||||
EOF
|
||||
|
||||
# Configure Nginx
|
||||
echo "Configuring Nginx..."
|
||||
cat > /etc/nginx/sites-available/depl0y << 'EOF'
|
||||
server {
|
||||
listen 80;
|
||||
server_name _;
|
||||
|
||||
client_max_body_size 10G;
|
||||
|
||||
# Frontend
|
||||
location / {
|
||||
root /opt/depl0y/frontend/dist;
|
||||
try_files $uri $uri/ /index.html;
|
||||
|
||||
location ~* \.(js|css|png|jpg|jpeg|gif|ico|svg|woff|woff2|ttf|eot)$ {
|
||||
expires 1y;
|
||||
add_header Cache-Control "public, immutable";
|
||||
}
|
||||
}
|
||||
|
||||
# Backend API
|
||||
location /api {
|
||||
proxy_pass http://127.0.0.1:8000;
|
||||
proxy_set_header Host $host;
|
||||
proxy_set_header X-Real-IP $remote_addr;
|
||||
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
|
||||
proxy_set_header X-Forwarded-Proto $scheme;
|
||||
proxy_http_version 1.1;
|
||||
proxy_set_header Upgrade $http_upgrade;
|
||||
proxy_set_header Connection "upgrade";
|
||||
proxy_connect_timeout 300s;
|
||||
proxy_send_timeout 300s;
|
||||
proxy_read_timeout 300s;
|
||||
}
|
||||
|
||||
# Health check
|
||||
location /health {
|
||||
proxy_pass http://127.0.0.1:8000/health;
|
||||
access_log off;
|
||||
}
|
||||
|
||||
access_log /var/log/nginx/depl0y_access.log;
|
||||
error_log /var/log/nginx/depl0y_error.log;
|
||||
}
|
||||
EOF
|
||||
|
||||
# Enable nginx site
|
||||
if [ "$OS" = "ubuntu" ] || [ "$OS" = "debian" ]; then
|
||||
ln -sf /etc/nginx/sites-available/depl0y /etc/nginx/sites-enabled/
|
||||
rm -f /etc/nginx/sites-enabled/default
|
||||
else
|
||||
cp /etc/nginx/sites-available/depl0y /etc/nginx/conf.d/depl0y.conf
|
||||
fi
|
||||
|
||||
# Test nginx configuration
|
||||
nginx -t
|
||||
|
||||
# Create admin user
|
||||
echo ""
|
||||
echo "========================================="
|
||||
echo "Creating admin user..."
|
||||
echo "========================================="
|
||||
read -p "Enter admin username (default: admin): " ADMIN_USER
|
||||
ADMIN_USER=${ADMIN_USER:-admin}
|
||||
|
||||
read -p "Enter admin email: " ADMIN_EMAIL
|
||||
while [ -z "$ADMIN_EMAIL" ]; do
|
||||
echo "Email cannot be empty"
|
||||
read -p "Enter admin email: " ADMIN_EMAIL
|
||||
done
|
||||
|
||||
read -sp "Enter admin password: " ADMIN_PASSWORD
|
||||
echo ""
|
||||
while [ ${#ADMIN_PASSWORD} -lt 8 ]; do
|
||||
echo "Password must be at least 8 characters"
|
||||
read -sp "Enter admin password: " ADMIN_PASSWORD
|
||||
echo ""
|
||||
done
|
||||
|
||||
cd /opt/depl0y/backend
|
||||
sudo -u depl0y bash -c "source venv/bin/activate && source /etc/depl0y/config.env && python3" << PYEOF
|
||||
from app.core.database import SessionLocal
|
||||
from app.models import User, UserRole
|
||||
from app.core.security import get_password_hash
|
||||
|
||||
db = SessionLocal()
|
||||
try:
|
||||
existing_user = db.query(User).filter(User.username == "$ADMIN_USER").first()
|
||||
if existing_user:
|
||||
print("User '$ADMIN_USER' already exists")
|
||||
else:
|
||||
admin = User(
|
||||
username="$ADMIN_USER",
|
||||
email="$ADMIN_EMAIL",
|
||||
hashed_password=get_password_hash("$ADMIN_PASSWORD"),
|
||||
role=UserRole.ADMIN,
|
||||
is_active=True
|
||||
)
|
||||
db.add(admin)
|
||||
db.commit()
|
||||
print("Admin user created successfully")
|
||||
except Exception as e:
|
||||
print(f"Error creating admin user: {e}")
|
||||
import traceback
|
||||
traceback.print_exc()
|
||||
finally:
|
||||
db.close()
|
||||
PYEOF
|
||||
|
||||
# Enable and start services
|
||||
echo ""
|
||||
echo "Starting services..."
|
||||
systemctl daemon-reload
|
||||
systemctl enable depl0y-backend
|
||||
systemctl start depl0y-backend
|
||||
systemctl restart nginx
|
||||
|
||||
# Wait for backend to start
|
||||
echo "Waiting for backend to start..."
|
||||
sleep 5
|
||||
|
||||
# Check service status
|
||||
echo ""
|
||||
echo "Checking service status..."
|
||||
systemctl status depl0y-backend --no-pager || true
|
||||
|
||||
echo ""
|
||||
echo "========================================="
|
||||
echo " Installation Complete!"
|
||||
echo "========================================="
|
||||
echo ""
|
||||
echo "Depl0y is now running!"
|
||||
echo ""
|
||||
SERVER_IP=$(hostname -I | awk '{print $1}')
|
||||
echo "Access the web interface at: http://${SERVER_IP}"
|
||||
echo ""
|
||||
echo "Login credentials:"
|
||||
echo " Username: $ADMIN_USER"
|
||||
echo " Password: (the one you just entered)"
|
||||
echo ""
|
||||
echo "Service management:"
|
||||
echo " Status: sudo systemctl status depl0y-backend"
|
||||
echo " Stop: sudo systemctl stop depl0y-backend"
|
||||
echo " Start: sudo systemctl start depl0y-backend"
|
||||
echo " Restart: sudo systemctl restart depl0y-backend"
|
||||
echo " Logs: sudo journalctl -u depl0y-backend -f"
|
||||
echo ""
|
||||
echo "Database credentials saved to: /etc/depl0y/config.env"
|
||||
echo "MariaDB root password: ${DB_ROOT_PASSWORD}"
|
||||
echo ""
|
||||
echo "========================================="
|
||||
@@ -0,0 +1,652 @@
|
||||
#!/bin/bash
|
||||
#
|
||||
# Depl0y - Automated VM Deployment Panel Installer
|
||||
# Complete automated installation - no manual steps required!
|
||||
# One-line install: curl -fsSL http://deploy.agit8or.net/downloads/install.sh | sudo bash
|
||||
#
|
||||
|
||||
set -e
|
||||
|
||||
# Installer version for tracking
|
||||
INSTALLER_VERSION="1.1.0"
|
||||
INSTALLER_BUILD="$(date +%Y%m%d%H%M%S)"
|
||||
|
||||
echo "╔══════════════════════════════════════════════════════════╗"
|
||||
echo "║ ║"
|
||||
echo "║ ██████╗ ███████╗██████╗ ██╗ ██████╗ ██╗ ██╗ ║"
|
||||
echo "║ ██╔══██╗██╔════╝██╔══██╗██║ ██╔═████╗╚██╗ ██╔╝ ║"
|
||||
echo "║ ██║ ██║█████╗ ██████╔╝██║ ██║██╔██║ ╚████╔╝ ║"
|
||||
echo "║ ██║ ██║██╔══╝ ██╔═══╝ ██║ ████╔╝██║ ╚██╔╝ ║"
|
||||
echo "║ ██████╔╝███████╗██║ ███████╗╚██████╔╝ ██║ ║"
|
||||
echo "║ ╚═════╝ ╚══════╝╚═╝ ╚══════╝ ╚═════╝ ╚═╝ ║"
|
||||
echo "║ ║"
|
||||
echo "║ Automated VM Deployment Panel for Proxmox VE ║"
|
||||
echo "║ https://deploy.agit8or.net ║"
|
||||
echo "║ Version 1.1.5 ║"
|
||||
echo "║ ║"
|
||||
echo "╚══════════════════════════════════════════════════════════╝"
|
||||
echo ""
|
||||
echo "This installer will:"
|
||||
echo " ✓ Install all dependencies"
|
||||
echo " ✓ Set up Depl0y application"
|
||||
echo " ✓ Configure cloud images (optional)"
|
||||
echo " ✓ Configure inter-node SSH (optional)"
|
||||
echo " ✓ No manual steps required!"
|
||||
echo ""
|
||||
|
||||
# Check if running as root
|
||||
if [ "$EUID" -ne 0 ]; then
|
||||
echo "ERROR: Please run as root (use sudo)"
|
||||
exit 1
|
||||
fi
|
||||
|
||||
echo "🚀 Starting Depl0y installation..."
|
||||
echo ""
|
||||
|
||||
# Check if Depl0y is already installed
|
||||
UPGRADE_MODE=false
|
||||
if [ -d "/opt/depl0y" ] && [ -f "/etc/systemd/system/depl0y-backend.service" ]; then
|
||||
UPGRADE_MODE=true
|
||||
echo "📦 Existing Depl0y installation detected"
|
||||
echo " This will upgrade your installation while preserving your database"
|
||||
echo ""
|
||||
fi
|
||||
|
||||
# Detect OS
|
||||
if [ -f /etc/os-release ]; then
|
||||
. /etc/os-release
|
||||
OS=$ID
|
||||
VER=$VERSION_ID
|
||||
else
|
||||
echo "ERROR: Cannot detect OS"
|
||||
exit 1
|
||||
fi
|
||||
|
||||
echo "✓ Detected OS: $OS $VER"
|
||||
|
||||
# Check if Ubuntu/Debian
|
||||
if [[ "$OS" != "ubuntu" && "$OS" != "debian" ]]; then
|
||||
echo "ERROR: This installer currently only supports Ubuntu and Debian"
|
||||
exit 1
|
||||
fi
|
||||
|
||||
# Update system
|
||||
echo ""
|
||||
echo "📦 Updating system packages..."
|
||||
apt-get update -qq
|
||||
|
||||
# Install ALL dependencies
|
||||
echo "📦 Installing dependencies..."
|
||||
echo " This includes: Python, Node.js, nginx, SQLite, PDF libraries, and more"
|
||||
apt-get install -y -qq \
|
||||
python3 \
|
||||
python3-pip \
|
||||
python3-venv \
|
||||
python3-dev \
|
||||
build-essential \
|
||||
nginx \
|
||||
nodejs \
|
||||
npm \
|
||||
sqlite3 \
|
||||
curl \
|
||||
wget \
|
||||
git \
|
||||
sshpass \
|
||||
openssh-client \
|
||||
at \
|
||||
ca-certificates \
|
||||
gnupg \
|
||||
lsb-release \
|
||||
libpango-1.0-0 \
|
||||
libpangocairo-1.0-0 \
|
||||
libgdk-pixbuf2.0-0 \
|
||||
libffi-dev \
|
||||
shared-mime-info
|
||||
|
||||
echo "✓ Dependencies installed"
|
||||
|
||||
# Create depl0y user
|
||||
echo ""
|
||||
echo "👤 Creating depl0y system user..."
|
||||
if ! id -u depl0y > /dev/null 2>&1; then
|
||||
useradd -r -m -d /opt/depl0y -s /bin/bash depl0y
|
||||
echo "✓ User 'depl0y' created"
|
||||
else
|
||||
echo "✓ User 'depl0y' already exists"
|
||||
fi
|
||||
|
||||
# If upgrading, stop the backend service and backup encryption keys
|
||||
if [ "$UPGRADE_MODE" = true ]; then
|
||||
echo "🔄 Preparing for upgrade..."
|
||||
|
||||
# Clear any stale Python cache first
|
||||
echo "🗑️ Clearing old Python cache..."
|
||||
find /opt/depl0y/backend -type d -name __pycache__ -exec rm -rf {} + 2>/dev/null || true
|
||||
find /opt/depl0y/backend -type f -name "*.pyc" -delete 2>/dev/null || true
|
||||
echo "✓ Cache cleared"
|
||||
|
||||
if systemctl is-active --quiet depl0y-backend; then
|
||||
systemctl stop depl0y-backend
|
||||
echo "✓ Stopped backend service"
|
||||
fi
|
||||
|
||||
# Backup encryption keys from existing service
|
||||
KEYS_VALID=false
|
||||
if [ -f /etc/systemd/system/depl0y-backend.service ]; then
|
||||
echo "🔍 Extracting existing encryption keys..."
|
||||
EXISTING_SECRET=$(grep "SECRET_KEY=" /etc/systemd/system/depl0y-backend.service | sed 's/.*SECRET_KEY=\([^"]*\).*/\1/')
|
||||
EXISTING_ENCRYPTION=$(grep "ENCRYPTION_KEY=" /etc/systemd/system/depl0y-backend.service | sed 's/.*ENCRYPTION_KEY=\([^"]*\).*/\1/')
|
||||
|
||||
if [ -n "$EXISTING_SECRET" ] && [ -n "$EXISTING_ENCRYPTION" ]; then
|
||||
echo " Found existing keys, validating..."
|
||||
# Validate the encryption key
|
||||
if python3 -c "from cryptography.fernet import Fernet; Fernet('${EXISTING_ENCRYPTION}'.encode())" 2>/dev/null; then
|
||||
echo "✓ Existing encryption keys are valid and will be preserved"
|
||||
KEYS_VALID=true
|
||||
else
|
||||
echo "⚠️ Existing encryption keys are INVALID (wrong format)"
|
||||
echo " Will generate new keys - you'll need to re-enter Proxmox credentials"
|
||||
fi
|
||||
else
|
||||
echo "⚠️ Could not extract existing keys from service file"
|
||||
echo " Will generate new keys"
|
||||
fi
|
||||
fi
|
||||
fi
|
||||
|
||||
# Download latest Depl0y
|
||||
echo ""
|
||||
echo "⬇️ Downloading Depl0y from deploy.agit8or.net..."
|
||||
cd /tmp
|
||||
rm -f depl0y-latest.tar.gz
|
||||
# Add cache-busting timestamp to ensure fresh download
|
||||
CACHE_BUST=$(date +%s)
|
||||
curl -fsSL "http://deploy.agit8or.net/api/v1/system-updates/download?v=${CACHE_BUST}" -o depl0y-latest.tar.gz
|
||||
|
||||
echo "📦 Extracting Depl0y..."
|
||||
rm -rf /tmp/depl0y-install
|
||||
mkdir -p /tmp/depl0y-install
|
||||
cd /tmp/depl0y-install
|
||||
tar -xzf /tmp/depl0y-latest.tar.gz
|
||||
|
||||
# Install backend
|
||||
echo ""
|
||||
echo "🔧 Installing backend..."
|
||||
mkdir -p /opt/depl0y
|
||||
chmod 755 /opt/depl0y # Allow nginx to traverse
|
||||
cp -r backend /opt/depl0y/
|
||||
chown -R depl0y:depl0y /opt/depl0y/backend
|
||||
chmod -R 755 /opt/depl0y/backend
|
||||
|
||||
# Create Python virtual environment
|
||||
echo "🐍 Setting up Python environment..."
|
||||
cd /opt/depl0y/backend
|
||||
sudo -u depl0y python3 -m venv venv
|
||||
sudo -u depl0y venv/bin/pip install --upgrade pip -q
|
||||
sudo -u depl0y venv/bin/pip install -r requirements.txt -q
|
||||
|
||||
# Install additional Python packages for features
|
||||
echo " Installing additional Python packages..."
|
||||
sudo -u depl0y venv/bin/pip install -q weasyprint markdown requests
|
||||
|
||||
echo "✓ Backend installed"
|
||||
|
||||
# Install scripts
|
||||
echo ""
|
||||
echo "📜 Installing scripts..."
|
||||
if [ -d "/tmp/depl0y-install/scripts" ]; then
|
||||
mkdir -p /opt/depl0y/scripts
|
||||
cp -r /tmp/depl0y-install/scripts/* /opt/depl0y/scripts/
|
||||
chmod -R 755 /opt/depl0y/scripts
|
||||
echo "✓ Scripts installed"
|
||||
else
|
||||
echo "⚠️ No scripts directory found in package"
|
||||
fi
|
||||
|
||||
# Install frontend
|
||||
echo ""
|
||||
echo "🎨 Installing frontend..."
|
||||
|
||||
if [ "$UPGRADE_MODE" = true ]; then
|
||||
# During upgrade, use pre-built frontend from package (much faster!)
|
||||
echo " Using pre-built frontend from package..."
|
||||
if [ -d "/tmp/depl0y-install/frontend/dist" ]; then
|
||||
mkdir -p /opt/depl0y/frontend/dist
|
||||
chmod 755 /opt/depl0y/frontend
|
||||
cp -r /tmp/depl0y-install/frontend/dist/* /opt/depl0y/frontend/dist/
|
||||
chown -R www-data:www-data /opt/depl0y/frontend/dist
|
||||
chmod -R 755 /opt/depl0y/frontend/dist
|
||||
echo "✓ Frontend installed (pre-built)"
|
||||
else
|
||||
echo "⚠️ Pre-built frontend not found, building from source..."
|
||||
cd /tmp/depl0y-install/frontend
|
||||
npm install --silent
|
||||
npm run build
|
||||
mkdir -p /opt/depl0y/frontend/dist
|
||||
chmod 755 /opt/depl0y/frontend
|
||||
cp -r dist/* /opt/depl0y/frontend/dist/
|
||||
chown -R www-data:www-data /opt/depl0y/frontend/dist
|
||||
chmod -R 755 /opt/depl0y/frontend/dist
|
||||
echo "✓ Frontend installed (built from source)"
|
||||
fi
|
||||
else
|
||||
# Fresh install - build frontend from source
|
||||
cd /tmp/depl0y-install/frontend
|
||||
npm install --silent
|
||||
npm run build
|
||||
mkdir -p /opt/depl0y/frontend/dist
|
||||
chmod 755 /opt/depl0y/frontend
|
||||
cp -r dist/* /opt/depl0y/frontend/dist/
|
||||
chown -R www-data:www-data /opt/depl0y/frontend/dist
|
||||
chmod -R 755 /opt/depl0y/frontend/dist
|
||||
echo "✓ Frontend installed"
|
||||
fi
|
||||
|
||||
# Create database directory
|
||||
echo ""
|
||||
echo "💾 Setting up database..."
|
||||
mkdir -p /var/lib/depl0y/db
|
||||
mkdir -p /var/lib/depl0y/cloud-images
|
||||
mkdir -p /var/lib/depl0y/isos
|
||||
mkdir -p /var/lib/depl0y/ssh_keys
|
||||
mkdir -p /var/log/depl0y
|
||||
chown -R depl0y:depl0y /var/lib/depl0y
|
||||
chown -R depl0y:depl0y /var/log/depl0y
|
||||
chmod -R 755 /var/lib/depl0y
|
||||
|
||||
echo "✓ Database directories created"
|
||||
|
||||
# Copy documentation
|
||||
echo ""
|
||||
echo "📚 Installing documentation..."
|
||||
if [ -d "/tmp/depl0y-install/docs" ]; then
|
||||
mkdir -p /opt/depl0y/docs
|
||||
cp -r /tmp/depl0y-install/docs/* /opt/depl0y/docs/
|
||||
chown -R depl0y:depl0y /opt/depl0y/docs
|
||||
echo "✓ Documentation installed"
|
||||
fi
|
||||
|
||||
# Generate or reuse encryption keys
|
||||
echo ""
|
||||
if [ "$UPGRADE_MODE" = true ] && [ "$KEYS_VALID" = true ]; then
|
||||
echo "🔐 Reusing existing encryption keys..."
|
||||
SECRET_KEY="$EXISTING_SECRET"
|
||||
ENCRYPTION_KEY="$EXISTING_ENCRYPTION"
|
||||
echo "✓ Existing encryption keys preserved"
|
||||
else
|
||||
echo "🔐 Generating new encryption keys..."
|
||||
SECRET_KEY=$(python3 -c 'import secrets; print(secrets.token_urlsafe(32))')
|
||||
ENCRYPTION_KEY=$(python3 -c 'from cryptography.fernet import Fernet; print(Fernet.generate_key().decode())')
|
||||
echo "✓ New encryption keys generated"
|
||||
|
||||
if [ "$UPGRADE_MODE" = true ]; then
|
||||
echo ""
|
||||
echo "⚠️ IMPORTANT: New encryption keys have been generated"
|
||||
echo " This means you will need to:"
|
||||
echo " • Log in again (previous sessions are now invalid)"
|
||||
echo " • Re-enter all Proxmox host credentials"
|
||||
echo " • Your database and settings are preserved"
|
||||
fi
|
||||
fi
|
||||
|
||||
# Create systemd service
|
||||
echo ""
|
||||
echo "⚙️ Creating systemd service..."
|
||||
cat > /etc/systemd/system/depl0y-backend.service << SVCEOF
|
||||
[Unit]
|
||||
Description=Depl0y Backend API
|
||||
After=network.target
|
||||
|
||||
[Service]
|
||||
Type=simple
|
||||
User=depl0y
|
||||
Group=depl0y
|
||||
WorkingDirectory=/opt/depl0y/backend
|
||||
Environment="PATH=/opt/depl0y/backend/venv/bin"
|
||||
Environment="SECRET_KEY=${SECRET_KEY}"
|
||||
Environment="ENCRYPTION_KEY=${ENCRYPTION_KEY}"
|
||||
ExecStart=/opt/depl0y/backend/venv/bin/uvicorn app.main:app --host 127.0.0.1 --port 8000
|
||||
Restart=always
|
||||
RestartSec=10
|
||||
|
||||
[Install]
|
||||
WantedBy=multi-user.target
|
||||
SVCEOF
|
||||
|
||||
# Clear Python cache to ensure new code is loaded
|
||||
if [ "$UPGRADE_MODE" = true ]; then
|
||||
echo "🗑️ Clearing Python cache again (ensuring fresh code)..."
|
||||
else
|
||||
echo "🗑️ Clearing Python cache..."
|
||||
fi
|
||||
find /opt/depl0y/backend -type d -name __pycache__ -exec rm -rf {} + 2>/dev/null || true
|
||||
find /opt/depl0y/backend -type f -name "*.pyc" -delete 2>/dev/null || true
|
||||
|
||||
systemctl daemon-reload
|
||||
systemctl enable depl0y-backend
|
||||
|
||||
# Use restart to ensure service loads new code (important for upgrades)
|
||||
if [ "$UPGRADE_MODE" = true ]; then
|
||||
echo "🔄 Restarting backend service with new code..."
|
||||
systemctl restart depl0y-backend
|
||||
else
|
||||
echo "🚀 Starting backend service..."
|
||||
systemctl start depl0y-backend
|
||||
fi
|
||||
|
||||
echo "✓ Backend service started"
|
||||
|
||||
# Configure nginx
|
||||
echo ""
|
||||
echo "🌐 Configuring nginx..."
|
||||
cat > /etc/nginx/sites-available/depl0y << 'NGEOF'
|
||||
server {
|
||||
listen 80;
|
||||
server_name _;
|
||||
|
||||
client_max_body_size 10G;
|
||||
|
||||
# Frontend
|
||||
location / {
|
||||
root /opt/depl0y/frontend/dist;
|
||||
try_files $uri $uri/ /index.html;
|
||||
|
||||
location ~* \.(js|css|png|jpg|jpeg|gif|ico|svg|woff|woff2|ttf|eot)$ {
|
||||
expires 1y;
|
||||
add_header Cache-Control "public, immutable";
|
||||
}
|
||||
}
|
||||
|
||||
# Backend API
|
||||
location /api {
|
||||
proxy_pass http://127.0.0.1:8000;
|
||||
proxy_http_version 1.1;
|
||||
proxy_set_header Upgrade $http_upgrade;
|
||||
proxy_set_header Connection 'upgrade';
|
||||
proxy_set_header Host $host;
|
||||
proxy_cache_bypass $http_upgrade;
|
||||
proxy_set_header X-Real-IP $remote_addr;
|
||||
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
|
||||
proxy_set_header X-Forwarded-Proto $scheme;
|
||||
proxy_connect_timeout 300s;
|
||||
proxy_send_timeout 300s;
|
||||
proxy_read_timeout 300s;
|
||||
}
|
||||
|
||||
access_log /var/log/nginx/depl0y_access.log;
|
||||
error_log /var/log/nginx/depl0y_error.log;
|
||||
}
|
||||
NGEOF
|
||||
|
||||
ln -sf /etc/nginx/sites-available/depl0y /etc/nginx/sites-enabled/depl0y
|
||||
rm -f /etc/nginx/sites-enabled/default
|
||||
|
||||
nginx -t
|
||||
systemctl restart nginx
|
||||
|
||||
echo "✓ Nginx configured"
|
||||
|
||||
# Setup sudoers for depl0y user
|
||||
echo ""
|
||||
echo "🔐 Configuring permissions..."
|
||||
cat > /etc/sudoers.d/depl0y << 'SUDOEOF'
|
||||
# Depl0y user sudo permissions
|
||||
depl0y ALL=(ALL) NOPASSWD: /usr/bin/apt-get install -y -qq sshpass
|
||||
depl0y ALL=(ALL) NOPASSWD: /usr/bin/which sshpass
|
||||
depl0y ALL=(depl0y) NOPASSWD: /usr/bin/mkdir -p /opt/depl0y/.ssh
|
||||
depl0y ALL=(depl0y) NOPASSWD: /usr/bin/ssh-keygen *
|
||||
depl0y ALL=(depl0y) NOPASSWD: /usr/bin/sshpass *
|
||||
depl0y ALL=(depl0y) NOPASSWD: /usr/bin/ssh *
|
||||
depl0y ALL=(depl0y) NOPASSWD: /usr/bin/ssh-copy-id *
|
||||
depl0y ALL=(ALL) NOPASSWD: /usr/bin/systemctl restart depl0y-backend
|
||||
depl0y ALL=(ALL) NOPASSWD: /bin/systemctl restart depl0y-backend
|
||||
depl0y ALL=(ALL) NOPASSWD: /usr/bin/systemctl status depl0y-backend
|
||||
depl0y ALL=(ALL) NOPASSWD: /bin/bash /tmp/depl0y-update-install.sh
|
||||
depl0y ALL=(ALL) NOPASSWD: /opt/depl0y/scripts/update-wrapper.sh *
|
||||
depl0y ALL=(ALL) NOPASSWD: /usr/bin/journalctl -u depl0y-backend *
|
||||
SUDOEOF
|
||||
|
||||
chmod 440 /etc/sudoers.d/depl0y
|
||||
visudo -c
|
||||
|
||||
echo "✓ Permissions configured"
|
||||
|
||||
# Wait for backend to start
|
||||
echo ""
|
||||
echo "⏳ Waiting for backend to start..."
|
||||
sleep 5
|
||||
|
||||
# Check if backend is running
|
||||
if systemctl is-active --quiet depl0y-backend; then
|
||||
echo "✓ Backend is running"
|
||||
else
|
||||
echo ""
|
||||
echo "❌ ERROR: Backend failed to start!"
|
||||
echo ""
|
||||
echo "Last 30 lines of backend logs:"
|
||||
journalctl -u depl0y-backend -n 30 --no-pager
|
||||
echo ""
|
||||
echo "Installation failed. Please check the logs above for errors."
|
||||
exit 1
|
||||
fi
|
||||
|
||||
# Create default admin user
|
||||
echo ""
|
||||
echo "👤 Creating default admin user..."
|
||||
cd /opt/depl0y/backend
|
||||
if sudo -u depl0y /opt/depl0y/backend/venv/bin/python3 create_admin.py; then
|
||||
echo "✓ Default credentials: admin / admin"
|
||||
else
|
||||
echo "❌ ERROR: Failed to create admin user!"
|
||||
echo "Check permissions and database connection."
|
||||
exit 1
|
||||
fi
|
||||
|
||||
# Initialize system settings in database
|
||||
echo ""
|
||||
echo "⚙️ Initializing system settings..."
|
||||
sudo -u depl0y sqlite3 /var/lib/depl0y/db/depl0y.db "CREATE TABLE IF NOT EXISTS system_settings (
|
||||
id INTEGER PRIMARY KEY AUTOINCREMENT,
|
||||
key VARCHAR(100) UNIQUE NOT NULL,
|
||||
value TEXT NOT NULL,
|
||||
description TEXT,
|
||||
updated_at DATETIME DEFAULT CURRENT_TIMESTAMP
|
||||
);" 2>/dev/null || true
|
||||
|
||||
sudo -u depl0y sqlite3 /var/lib/depl0y/db/depl0y.db "INSERT OR REPLACE INTO system_settings (key, value, description) VALUES
|
||||
('app_version', '1.1.9', 'Current application version'),
|
||||
('app_name', 'Depl0y', 'Application name');" 2>/dev/null || true
|
||||
|
||||
echo "✓ System settings initialized"
|
||||
|
||||
# Optional Proxmox setup
|
||||
echo ""
|
||||
echo "━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━"
|
||||
echo " Optional: Proxmox Integration Setup"
|
||||
echo "━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━"
|
||||
echo ""
|
||||
echo "Would you like to configure Proxmox integration now?"
|
||||
echo "This will:"
|
||||
echo " • Set up cloud images for fast VM deployment"
|
||||
echo " • Configure inter-node SSH for multi-node clusters"
|
||||
echo ""
|
||||
read -p "Configure Proxmox now? (y/N): " -n 1 -r SETUP_PROXMOX < /dev/tty || SETUP_PROXMOX="N"
|
||||
echo ""
|
||||
|
||||
if [[ $SETUP_PROXMOX =~ ^[Yy]$ ]]; then
|
||||
echo ""
|
||||
echo "📋 Proxmox Configuration"
|
||||
echo ""
|
||||
|
||||
# Get Proxmox details
|
||||
read -p "Enter Proxmox hostname or IP: " PROXMOX_HOST < /dev/tty
|
||||
read -p "Enter Proxmox root username [root]: " PROXMOX_USER < /dev/tty
|
||||
PROXMOX_USER=${PROXMOX_USER:-root}
|
||||
|
||||
echo ""
|
||||
echo "⚠️ Note: Password will be used to set up SSH keys only"
|
||||
read -s -p "Enter Proxmox root password: " PROXMOX_PASSWORD < /dev/tty
|
||||
echo ""
|
||||
echo ""
|
||||
|
||||
# Setup SSH keys for depl0y user
|
||||
echo "🔑 Setting up SSH keys..."
|
||||
if [ ! -f "/opt/depl0y/.ssh/id_rsa" ]; then
|
||||
sudo -u depl0y mkdir -p /opt/depl0y/.ssh
|
||||
sudo -u depl0y ssh-keygen -t rsa -b 4096 -f /opt/depl0y/.ssh/id_rsa -N "" -q
|
||||
echo "✓ SSH keys generated"
|
||||
else
|
||||
echo "✓ SSH keys already exist"
|
||||
fi
|
||||
|
||||
# Copy SSH key to Proxmox
|
||||
echo "📤 Copying SSH key to Proxmox..."
|
||||
sudo -u depl0y sshpass -p "$PROXMOX_PASSWORD" ssh-copy-id -o StrictHostKeyChecking=no "${PROXMOX_USER}@${PROXMOX_HOST}" 2>/dev/null || {
|
||||
echo "⚠️ Failed to copy SSH key. You may need to do this manually later."
|
||||
}
|
||||
|
||||
# Test SSH connection
|
||||
if sudo -u depl0y ssh -o BatchMode=yes -o ConnectTimeout=5 -o StrictHostKeyChecking=no "${PROXMOX_USER}@${PROXMOX_HOST}" "echo SSH_OK" 2>/dev/null | grep -q "SSH_OK"; then
|
||||
echo "✓ SSH connection verified"
|
||||
|
||||
# Setup cloud images
|
||||
echo ""
|
||||
echo "☁️ Setting up cloud images..."
|
||||
sudo -u depl0y ssh -o StrictHostKeyChecking=no "${PROXMOX_USER}@${PROXMOX_HOST}" 'bash -s' << 'CLOUDEOF'
|
||||
# Check if cloud-init is available
|
||||
if ! which cloud-init >/dev/null 2>&1; then
|
||||
apt-get update -qq
|
||||
apt-get install -y -qq cloud-init
|
||||
fi
|
||||
|
||||
# Create cloud-init snippet storage if needed
|
||||
mkdir -p /var/lib/vz/snippets
|
||||
chmod 755 /var/lib/vz/snippets
|
||||
|
||||
echo "✓ Cloud images configured"
|
||||
CLOUDEOF
|
||||
|
||||
# Setup inter-node SSH for cluster
|
||||
echo ""
|
||||
echo "🔗 Setting up inter-node SSH for cluster..."
|
||||
sudo -u depl0y ssh -o StrictHostKeyChecking=no "${PROXMOX_USER}@${PROXMOX_HOST}" 'bash -s' << 'SSHEOF'
|
||||
# Get cluster nodes
|
||||
NODES=$(pvesh get /cluster/status --output-format json 2>/dev/null | grep -o '"name":"[^"]*"' | cut -d'"' -f4 | grep -v "^$" || echo "")
|
||||
|
||||
if [ -n "$NODES" ]; then
|
||||
echo " Found cluster nodes: $NODES"
|
||||
|
||||
# Generate SSH key on this node if needed
|
||||
if [ ! -f ~/.ssh/id_rsa ]; then
|
||||
ssh-keygen -t rsa -b 4096 -f ~/.ssh/id_rsa -N "" -q
|
||||
fi
|
||||
|
||||
# Copy key to other nodes
|
||||
for node in $NODES; do
|
||||
if [ "$node" != "$(hostname)" ]; then
|
||||
echo " Setting up SSH to $node..."
|
||||
ssh-copy-id -o StrictHostKeyChecking=no "root@$node" 2>/dev/null || true
|
||||
fi
|
||||
done
|
||||
|
||||
echo "✓ Inter-node SSH configured"
|
||||
else
|
||||
echo " Single node or cluster not configured, skipping"
|
||||
fi
|
||||
SSHEOF
|
||||
|
||||
echo ""
|
||||
echo "✓ Proxmox integration complete!"
|
||||
else
|
||||
echo "⚠️ SSH connection failed. You can set this up later via Settings in the web interface."
|
||||
fi
|
||||
else
|
||||
echo ""
|
||||
echo "⏭️ Skipping Proxmox setup. You can configure this later via:"
|
||||
echo " Settings → Cloud Images"
|
||||
echo " Settings → Proxmox Cluster SSH"
|
||||
fi
|
||||
|
||||
# Cleanup
|
||||
echo ""
|
||||
echo "🧹 Cleaning up..."
|
||||
cd /
|
||||
rm -rf /tmp/depl0y-install
|
||||
rm -f /tmp/depl0y-latest.tar.gz
|
||||
|
||||
# Final restart for upgrades to ensure new code is loaded
|
||||
if [ "$UPGRADE_MODE" = true ]; then
|
||||
echo ""
|
||||
echo "🔄 Final restart to load new code..."
|
||||
find /opt/depl0y/backend -type d -name __pycache__ -exec rm -rf {} + 2>/dev/null || true
|
||||
find /opt/depl0y/backend -type f -name "*.pyc" -delete 2>/dev/null || true
|
||||
systemctl restart depl0y-backend
|
||||
sleep 3
|
||||
if systemctl is-active --quiet depl0y-backend; then
|
||||
echo "✓ Backend restarted successfully"
|
||||
else
|
||||
echo "⚠️ Backend restart may have issues, check logs"
|
||||
fi
|
||||
fi
|
||||
|
||||
# Get IP address
|
||||
IP=$(hostname -I | awk '{print $1}')
|
||||
|
||||
echo ""
|
||||
if [ "$UPGRADE_MODE" = true ]; then
|
||||
echo "╔══════════════════════════════════════════════════════════╗"
|
||||
echo "║ ║"
|
||||
echo "║ ✅ UPGRADE COMPLETE ║"
|
||||
echo "║ ║"
|
||||
echo "╚══════════════════════════════════════════════════════════╝"
|
||||
echo ""
|
||||
echo "🎉 Depl0y v1.1.9 has been successfully upgraded!"
|
||||
echo ""
|
||||
echo "📍 Access Depl0y at:"
|
||||
echo " http://$IP"
|
||||
echo ""
|
||||
echo "✨ What's new in v1.1.9:"
|
||||
echo " • Automatic backend restart after upgrades"
|
||||
echo " • No manual restart needed - updates apply immediately"
|
||||
echo " • Fixed JavaScript error (version not defined)"
|
||||
echo " • One-click automatic updates from Settings"
|
||||
echo ""
|
||||
echo "📚 Note:"
|
||||
echo " • Your database has been preserved"
|
||||
echo " • Your encryption keys have been preserved"
|
||||
echo " • All users and settings retained"
|
||||
else
|
||||
echo "╔══════════════════════════════════════════════════════════╗"
|
||||
echo "║ ║"
|
||||
echo "║ ✅ INSTALLATION COMPLETE ║"
|
||||
echo "║ ║"
|
||||
echo "╚══════════════════════════════════════════════════════════╝"
|
||||
echo ""
|
||||
echo "🎉 Depl0y v1.1.9 has been successfully installed!"
|
||||
echo ""
|
||||
echo "📍 Access Depl0y at:"
|
||||
echo " http://$IP"
|
||||
echo ""
|
||||
echo "👤 Default Credentials:"
|
||||
echo " Username: admin"
|
||||
echo " Password: admin"
|
||||
echo " 🔐 2FA: Disabled (enable in Settings after login)"
|
||||
echo " ⚠️ CHANGE PASSWORD IMMEDIATELY AFTER FIRST LOGIN!"
|
||||
echo ""
|
||||
echo "✨ Features:"
|
||||
echo " • High Availability wizard"
|
||||
echo " • Cloud image management"
|
||||
echo " • Automated VM deployment"
|
||||
echo ""
|
||||
echo "📚 Next Steps:"
|
||||
echo " 1. Access the web interface"
|
||||
echo " 2. Change the default password"
|
||||
echo " 3. Add your Proxmox host in Settings (if not done)"
|
||||
echo " 4. Try the HA Setup Wizard!"
|
||||
fi
|
||||
echo ""
|
||||
echo "📖 Documentation: http://$IP → Documentation"
|
||||
echo "🆘 Support: Check /opt/depl0y/docs/"
|
||||
echo ""
|
||||
echo "Thank you for using Depl0y! 🚀"
|
||||
echo ""
|
||||
@@ -0,0 +1,187 @@
|
||||
#!/bin/bash
|
||||
|
||||
# Depl0y Quick Setup with SQLite (simplest installation)
|
||||
|
||||
set -e
|
||||
|
||||
echo "========================================="
|
||||
echo " Depl0y Quick Setup (SQLite)"
|
||||
echo "========================================="
|
||||
echo ""
|
||||
|
||||
if [ "$EUID" -ne 0 ]; then
|
||||
echo "Please run as root"
|
||||
exit 1
|
||||
fi
|
||||
|
||||
cd /home/administrator/depl0y
|
||||
|
||||
# Create directories
|
||||
echo "Creating directories..."
|
||||
mkdir -p /opt/depl0y/{backend,frontend}
|
||||
mkdir -p /var/lib/depl0y/{isos,cloud-init,ssh_keys,db}
|
||||
mkdir -p /var/log/depl0y
|
||||
mkdir -p /etc/depl0y
|
||||
|
||||
# Copy files
|
||||
echo "Copying files..."
|
||||
cp -r backend/* /opt/depl0y/backend/
|
||||
cp -r frontend/* /opt/depl0y/frontend/
|
||||
|
||||
# Create user
|
||||
useradd -r -s /bin/bash -d /opt/depl0y -m depl0y 2>/dev/null || true
|
||||
|
||||
# Set permissions
|
||||
chown -R depl0y:depl0y /opt/depl0y /var/lib/depl0y /var/log/depl0y
|
||||
|
||||
# Generate config
|
||||
echo "Generating configuration..."
|
||||
SECRET_KEY=$(openssl rand -hex 32)
|
||||
ENCRYPTION_KEY=$(python3 -c "from cryptography.fernet import Fernet; print(Fernet.generate_key().decode())")
|
||||
|
||||
cat > /etc/depl0y/config.env << EOF
|
||||
DATABASE_URL=sqlite:////var/lib/depl0y/db/depl0y.db
|
||||
SECRET_KEY=${SECRET_KEY}
|
||||
ENCRYPTION_KEY=${ENCRYPTION_KEY}
|
||||
DEBUG=false
|
||||
LOG_LEVEL=INFO
|
||||
LOG_FILE=/var/log/depl0y/app.log
|
||||
ISO_STORAGE_PATH=/var/lib/depl0y/isos
|
||||
CLOUDINIT_TEMPLATE_PATH=/var/lib/depl0y/cloud-init
|
||||
SSH_KEY_PATH=/var/lib/depl0y/ssh_keys
|
||||
API_V1_PREFIX=/api/v1
|
||||
EOF
|
||||
|
||||
chmod 600 /etc/depl0y/config.env
|
||||
chown depl0y:depl0y /etc/depl0y/config.env
|
||||
|
||||
# Install Python deps
|
||||
echo "Installing Python dependencies..."
|
||||
cd /opt/depl0y/backend
|
||||
sudo -u depl0y python3 -m venv venv
|
||||
sudo -u depl0y venv/bin/pip install --upgrade pip -q
|
||||
sudo -u depl0y venv/bin/pip install -r requirements.txt -q
|
||||
|
||||
echo "✓ Python dependencies installed"
|
||||
|
||||
# Init database
|
||||
echo "Initializing database..."
|
||||
sudo -u depl0y bash -c "source venv/bin/activate && source /etc/depl0y/config.env && python3 -c 'from app.core.database import init_db; init_db()'"
|
||||
|
||||
echo "✓ Database initialized"
|
||||
|
||||
# Create admin
|
||||
echo "Creating admin user..."
|
||||
sudo -u depl0y bash -c "source venv/bin/activate && source /etc/depl0y/config.env && python3" << 'PYEOF'
|
||||
from app.core.database import SessionLocal
|
||||
from app.models import User, UserRole
|
||||
from app.core.security import get_password_hash
|
||||
|
||||
db = SessionLocal()
|
||||
try:
|
||||
admin = User(
|
||||
username="admin",
|
||||
email="admin@depl0y.local",
|
||||
hashed_password=get_password_hash("Admin123!"),
|
||||
role=UserRole.ADMIN,
|
||||
is_active=True
|
||||
)
|
||||
db.add(admin)
|
||||
db.commit()
|
||||
print("✓ Admin created")
|
||||
except Exception as e:
|
||||
print(f"Note: {e}")
|
||||
finally:
|
||||
db.close()
|
||||
PYEOF
|
||||
|
||||
# Build frontend
|
||||
echo "Building frontend..."
|
||||
cd /opt/depl0y/frontend
|
||||
sudo -u depl0y npm install -q
|
||||
sudo -u depl0y npm run build
|
||||
|
||||
echo "✓ Frontend built"
|
||||
|
||||
# Create service
|
||||
cat > /etc/systemd/system/depl0y-backend.service << 'EOF'
|
||||
[Unit]
|
||||
Description=Depl0y Backend
|
||||
After=network.target
|
||||
|
||||
[Service]
|
||||
Type=simple
|
||||
User=depl0y
|
||||
Group=depl0y
|
||||
WorkingDirectory=/opt/depl0y/backend
|
||||
EnvironmentFile=/etc/depl0y/config.env
|
||||
ExecStart=/opt/depl0y/backend/venv/bin/uvicorn app.main:app --host 127.0.0.1 --port 8000
|
||||
Restart=always
|
||||
|
||||
[Install]
|
||||
WantedBy=multi-user.target
|
||||
EOF
|
||||
|
||||
# Configure nginx
|
||||
cat > /etc/nginx/sites-available/depl0y << 'EOF'
|
||||
server {
|
||||
listen 80 default_server;
|
||||
server_name _;
|
||||
|
||||
client_max_body_size 10G;
|
||||
|
||||
location / {
|
||||
root /opt/depl0y/frontend/dist;
|
||||
try_files $uri $uri/ /index.html;
|
||||
}
|
||||
|
||||
location /api {
|
||||
proxy_pass http://127.0.0.1:8000;
|
||||
proxy_set_header Host $host;
|
||||
proxy_set_header X-Real-IP $remote_addr;
|
||||
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
|
||||
proxy_http_version 1.1;
|
||||
proxy_connect_timeout 300s;
|
||||
proxy_send_timeout 300s;
|
||||
proxy_read_timeout 300s;
|
||||
}
|
||||
|
||||
location /health {
|
||||
proxy_pass http://127.0.0.1:8000/health;
|
||||
access_log off;
|
||||
}
|
||||
}
|
||||
EOF
|
||||
|
||||
ln -sf /etc/nginx/sites-available/depl0y /etc/nginx/sites-enabled/
|
||||
rm -f /etc/nginx/sites-enabled/default
|
||||
nginx -t
|
||||
|
||||
# Start everything
|
||||
echo "Starting services..."
|
||||
systemctl daemon-reload
|
||||
systemctl enable depl0y-backend
|
||||
systemctl restart depl0y-backend
|
||||
systemctl reload nginx
|
||||
|
||||
sleep 3
|
||||
|
||||
SERVER_IP=$(hostname -I | awk '{print $1}')
|
||||
|
||||
echo ""
|
||||
echo "========================================="
|
||||
echo " ✓ Depl0y is Running!"
|
||||
echo "========================================="
|
||||
echo ""
|
||||
echo "URL: http://${SERVER_IP}"
|
||||
echo ""
|
||||
echo "Login:"
|
||||
echo " Username: admin"
|
||||
echo " Password: Admin123!"
|
||||
echo ""
|
||||
echo "Commands:"
|
||||
echo " sudo systemctl status depl0y-backend"
|
||||
echo " sudo systemctl restart depl0y-backend"
|
||||
echo " sudo journalctl -u depl0y-backend -f"
|
||||
echo ""
|
||||
echo "========================================="
|
||||
@@ -0,0 +1,236 @@
|
||||
#!/bin/bash
|
||||
|
||||
# Depl0y Quick Start (assumes MariaDB already installed)
|
||||
|
||||
set -e
|
||||
|
||||
echo "========================================="
|
||||
echo " Depl0y Quick Start"
|
||||
echo "========================================="
|
||||
echo ""
|
||||
|
||||
# Check if running as root
|
||||
if [ "$EUID" -ne 0 ]; then
|
||||
echo "Please run as root (use sudo)"
|
||||
exit 1
|
||||
fi
|
||||
|
||||
PROJECT_DIR="/home/administrator/depl0y"
|
||||
cd "$PROJECT_DIR"
|
||||
|
||||
# Setup MariaDB database
|
||||
echo "Setting up database..."
|
||||
mysql -u root << 'EOF'
|
||||
CREATE DATABASE IF NOT EXISTS depl0y;
|
||||
CREATE USER IF NOT EXISTS 'depl0y'@'localhost' IDENTIFIED BY 'depl0y_password_123';
|
||||
GRANT ALL PRIVILEGES ON depl0y.* TO 'depl0y'@'localhost';
|
||||
FLUSH PRIVILEGES;
|
||||
EOF
|
||||
|
||||
echo "Database created"
|
||||
|
||||
# Create application user and directories
|
||||
echo "Creating directories..."
|
||||
useradd -r -s /bin/bash -d /opt/depl0y -m depl0y 2>/dev/null || true
|
||||
mkdir -p /opt/depl0y/{backend,frontend}
|
||||
mkdir -p /var/lib/depl0y/{isos,cloud-init,ssh_keys}
|
||||
mkdir -p /var/log/depl0y
|
||||
mkdir -p /etc/depl0y
|
||||
|
||||
# Copy files
|
||||
echo "Copying application files..."
|
||||
cp -r "$PROJECT_DIR/backend"/* /opt/depl0y/backend/
|
||||
cp -r "$PROJECT_DIR/frontend"/* /opt/depl0y/frontend/
|
||||
|
||||
# Set permissions
|
||||
chown -R depl0y:depl0y /opt/depl0y
|
||||
chown -R depl0y:depl0y /var/lib/depl0y
|
||||
chown -R depl0y:depl0y /var/log/depl0y
|
||||
|
||||
# Generate secrets
|
||||
echo "Generating configuration..."
|
||||
SECRET_KEY=$(openssl rand -hex 32)
|
||||
ENCRYPTION_KEY=$(python3 -c "from cryptography.fernet import Fernet; print(Fernet.generate_key().decode())")
|
||||
|
||||
# Create config file
|
||||
cat > /etc/depl0y/config.env << EOF
|
||||
DATABASE_URL=mysql+pymysql://depl0y:depl0y_password_123@localhost:3306/depl0y
|
||||
SECRET_KEY=${SECRET_KEY}
|
||||
ENCRYPTION_KEY=${ENCRYPTION_KEY}
|
||||
DEBUG=false
|
||||
LOG_LEVEL=INFO
|
||||
LOG_FILE=/var/log/depl0y/app.log
|
||||
ISO_STORAGE_PATH=/var/lib/depl0y/isos
|
||||
CLOUDINIT_TEMPLATE_PATH=/var/lib/depl0y/cloud-init
|
||||
SSH_KEY_PATH=/var/lib/depl0y/ssh_keys
|
||||
API_V1_PREFIX=/api/v1
|
||||
EOF
|
||||
|
||||
chmod 600 /etc/depl0y/config.env
|
||||
chown depl0y:depl0y /etc/depl0y/config.env
|
||||
|
||||
# Install Python dependencies
|
||||
echo "Installing Python dependencies (this may take a few minutes)..."
|
||||
cd /opt/depl0y/backend
|
||||
sudo -u depl0y python3 -m venv venv
|
||||
sudo -u depl0y /opt/depl0y/backend/venv/bin/pip install --upgrade pip --quiet
|
||||
sudo -u depl0y /opt/depl0y/backend/venv/bin/pip install -r requirements.txt --quiet
|
||||
|
||||
echo "Python dependencies installed"
|
||||
|
||||
# Initialize database
|
||||
echo "Initializing database..."
|
||||
cd /opt/depl0y/backend
|
||||
sudo -u depl0y bash -c "source venv/bin/activate && source /etc/depl0y/config.env && python3 -c 'from app.core.database import init_db; init_db()'"
|
||||
|
||||
echo "Database initialized"
|
||||
|
||||
# Build frontend
|
||||
echo "Building frontend (this may take a few minutes)..."
|
||||
cd /opt/depl0y/frontend
|
||||
sudo -u depl0y npm install --quiet
|
||||
sudo -u depl0y npm run build
|
||||
|
||||
echo "Frontend built"
|
||||
|
||||
# Create systemd service
|
||||
echo "Creating systemd service..."
|
||||
cat > /etc/systemd/system/depl0y-backend.service << 'SVCEOF'
|
||||
[Unit]
|
||||
Description=Depl0y Backend API
|
||||
After=network.target mariadb.service
|
||||
Wants=mariadb.service
|
||||
|
||||
[Service]
|
||||
Type=simple
|
||||
User=depl0y
|
||||
Group=depl0y
|
||||
WorkingDirectory=/opt/depl0y/backend
|
||||
EnvironmentFile=/etc/depl0y/config.env
|
||||
ExecStart=/opt/depl0y/backend/venv/bin/uvicorn app.main:app --host 127.0.0.1 --port 8000
|
||||
Restart=always
|
||||
RestartSec=10
|
||||
|
||||
[Install]
|
||||
WantedBy=multi-user.target
|
||||
SVCEOF
|
||||
|
||||
# Configure Nginx
|
||||
echo "Configuring Nginx..."
|
||||
cat > /etc/nginx/sites-available/depl0y << 'NGEOF'
|
||||
server {
|
||||
listen 80;
|
||||
server_name _;
|
||||
|
||||
client_max_body_size 10G;
|
||||
|
||||
location / {
|
||||
root /opt/depl0y/frontend/dist;
|
||||
try_files $uri $uri/ /index.html;
|
||||
|
||||
location ~* \.(js|css|png|jpg|jpeg|gif|ico|svg|woff|woff2|ttf|eot)$ {
|
||||
expires 1y;
|
||||
add_header Cache-Control "public, immutable";
|
||||
}
|
||||
}
|
||||
|
||||
location /api {
|
||||
proxy_pass http://127.0.0.1:8000;
|
||||
proxy_set_header Host $host;
|
||||
proxy_set_header X-Real-IP $remote_addr;
|
||||
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
|
||||
proxy_set_header X-Forwarded-Proto $scheme;
|
||||
proxy_http_version 1.1;
|
||||
proxy_set_header Upgrade $http_upgrade;
|
||||
proxy_set_header Connection "upgrade";
|
||||
proxy_connect_timeout 300s;
|
||||
proxy_send_timeout 300s;
|
||||
proxy_read_timeout 300s;
|
||||
}
|
||||
|
||||
location /health {
|
||||
proxy_pass http://127.0.0.1:8000/health;
|
||||
access_log off;
|
||||
}
|
||||
|
||||
access_log /var/log/nginx/depl0y_access.log;
|
||||
error_log /var/log/nginx/depl0y_error.log;
|
||||
}
|
||||
NGEOF
|
||||
|
||||
ln -sf /etc/nginx/sites-available/depl0y /etc/nginx/sites-enabled/
|
||||
rm -f /etc/nginx/sites-enabled/default
|
||||
|
||||
# Test nginx
|
||||
nginx -t
|
||||
|
||||
# Create admin user
|
||||
echo ""
|
||||
echo "Creating admin user..."
|
||||
cd /opt/depl0y/backend
|
||||
sudo -u depl0y bash -c "source venv/bin/activate && source /etc/depl0y/config.env && python3" << 'PYEOF'
|
||||
from app.core.database import SessionLocal
|
||||
from app.models import User, UserRole
|
||||
from app.core.security import get_password_hash
|
||||
|
||||
db = SessionLocal()
|
||||
try:
|
||||
# Delete existing admin if exists
|
||||
existing = db.query(User).filter(User.username == "admin").first()
|
||||
if existing:
|
||||
db.delete(existing)
|
||||
db.commit()
|
||||
|
||||
# Create new admin
|
||||
admin = User(
|
||||
username="admin",
|
||||
email="admin@depl0y.local",
|
||||
hashed_password=get_password_hash("Admin123!"),
|
||||
role=UserRole.ADMIN,
|
||||
is_active=True
|
||||
)
|
||||
db.add(admin)
|
||||
db.commit()
|
||||
print("✓ Admin user created")
|
||||
except Exception as e:
|
||||
print(f"Error: {e}")
|
||||
import traceback
|
||||
traceback.print_exc()
|
||||
finally:
|
||||
db.close()
|
||||
PYEOF
|
||||
|
||||
# Start services
|
||||
echo ""
|
||||
echo "Starting services..."
|
||||
systemctl daemon-reload
|
||||
systemctl enable depl0y-backend
|
||||
systemctl restart depl0y-backend
|
||||
systemctl reload nginx
|
||||
|
||||
# Wait for startup
|
||||
echo "Waiting for services to start..."
|
||||
sleep 5
|
||||
|
||||
# Get server IP
|
||||
SERVER_IP=$(hostname -I | awk '{print $1}')
|
||||
|
||||
echo ""
|
||||
echo "========================================="
|
||||
echo " Installation Complete!"
|
||||
echo "========================================="
|
||||
echo ""
|
||||
echo "✓ Depl0y is now running!"
|
||||
echo ""
|
||||
echo "Access: http://${SERVER_IP}"
|
||||
echo ""
|
||||
echo "Login:"
|
||||
echo " Username: admin"
|
||||
echo " Password: Admin123!"
|
||||
echo ""
|
||||
echo "Commands:"
|
||||
echo " Status: sudo systemctl status depl0y-backend"
|
||||
echo " Restart: sudo systemctl restart depl0y-backend"
|
||||
echo " Logs: sudo journalctl -u depl0y-backend -f"
|
||||
echo ""
|
||||
echo "========================================="
|
||||
@@ -0,0 +1,175 @@
|
||||
#!/bin/bash
|
||||
|
||||
# Depl0y Setup Script
|
||||
# This script sets up Depl0y on a fresh server
|
||||
|
||||
set -e
|
||||
|
||||
echo "========================================="
|
||||
echo " Depl0y Installation Script"
|
||||
echo "========================================="
|
||||
echo ""
|
||||
|
||||
# Check if running as root
|
||||
if [ "$EUID" -ne 0 ]; then
|
||||
echo "Please run as root (use sudo)"
|
||||
exit 1
|
||||
fi
|
||||
|
||||
# Detect OS
|
||||
if [ -f /etc/os-release ]; then
|
||||
. /etc/os-release
|
||||
OS=$ID
|
||||
VERSION=$VERSION_ID
|
||||
else
|
||||
echo "Cannot detect OS. Exiting."
|
||||
exit 1
|
||||
fi
|
||||
|
||||
echo "Detected OS: $OS $VERSION"
|
||||
echo ""
|
||||
|
||||
# Install Docker and Docker Compose
|
||||
echo "Installing Docker and Docker Compose..."
|
||||
if ! command -v docker &> /dev/null; then
|
||||
curl -fsSL https://get.docker.com | sh
|
||||
systemctl enable docker
|
||||
systemctl start docker
|
||||
echo "Docker installed successfully"
|
||||
else
|
||||
echo "Docker is already installed"
|
||||
fi
|
||||
|
||||
if ! command -v docker-compose &> /dev/null; then
|
||||
curl -L "https://github.com/docker/compose/releases/latest/download/docker-compose-$(uname -s)-$(uname -m)" -o /usr/local/bin/docker-compose
|
||||
chmod +x /usr/local/bin/docker-compose
|
||||
echo "Docker Compose installed successfully"
|
||||
else
|
||||
echo "Docker Compose is already installed"
|
||||
fi
|
||||
|
||||
echo ""
|
||||
|
||||
# Generate secrets
|
||||
echo "Generating secure secrets..."
|
||||
|
||||
if [ ! -f .env ]; then
|
||||
cp .env.example .env
|
||||
|
||||
# Generate SECRET_KEY (64 character random string)
|
||||
SECRET_KEY=$(openssl rand -hex 32)
|
||||
sed -i "s|SECRET_KEY=.*|SECRET_KEY=$SECRET_KEY|" .env
|
||||
|
||||
# Generate ENCRYPTION_KEY (Fernet key)
|
||||
ENCRYPTION_KEY=$(python3 -c "from cryptography.fernet import Fernet; print(Fernet.generate_key().decode())" 2>/dev/null || openssl rand -base64 32)
|
||||
sed -i "s|ENCRYPTION_KEY=.*|ENCRYPTION_KEY=$ENCRYPTION_KEY|" .env
|
||||
|
||||
# Generate database passwords
|
||||
MYSQL_ROOT_PASSWORD=$(openssl rand -hex 16)
|
||||
MYSQL_PASSWORD=$(openssl rand -hex 16)
|
||||
sed -i "s|MYSQL_ROOT_PASSWORD=.*|MYSQL_ROOT_PASSWORD=$MYSQL_ROOT_PASSWORD|" .env
|
||||
sed -i "s|MYSQL_PASSWORD=.*|MYSQL_PASSWORD=$MYSQL_PASSWORD|" .env
|
||||
|
||||
echo ".env file created with secure random secrets"
|
||||
else
|
||||
echo ".env file already exists, skipping secret generation"
|
||||
fi
|
||||
|
||||
echo ""
|
||||
|
||||
# Create necessary directories
|
||||
echo "Creating directories..."
|
||||
mkdir -p /var/lib/depl0y/{isos,cloud-init,ssh_keys}
|
||||
mkdir -p /var/log/depl0y
|
||||
chmod 755 /var/lib/depl0y
|
||||
chmod 755 /var/log/depl0y
|
||||
|
||||
echo ""
|
||||
|
||||
# Build and start containers
|
||||
echo "Building and starting Docker containers..."
|
||||
docker-compose up -d --build
|
||||
|
||||
echo ""
|
||||
echo "Waiting for services to start..."
|
||||
sleep 10
|
||||
|
||||
# Run database migrations
|
||||
echo "Running database migrations..."
|
||||
docker-compose exec -T backend alembic upgrade head || echo "Note: Alembic migrations may need to be configured"
|
||||
|
||||
# Create default admin user
|
||||
echo ""
|
||||
echo "Creating default admin user..."
|
||||
read -p "Enter admin username (default: admin): " ADMIN_USER
|
||||
ADMIN_USER=${ADMIN_USER:-admin}
|
||||
|
||||
read -p "Enter admin email: " ADMIN_EMAIL
|
||||
while [ -z "$ADMIN_EMAIL" ]; do
|
||||
echo "Email cannot be empty"
|
||||
read -p "Enter admin email: " ADMIN_EMAIL
|
||||
done
|
||||
|
||||
read -sp "Enter admin password: " ADMIN_PASSWORD
|
||||
echo ""
|
||||
while [ ${#ADMIN_PASSWORD} -lt 8 ]; do
|
||||
echo "Password must be at least 8 characters"
|
||||
read -sp "Enter admin password: " ADMIN_PASSWORD
|
||||
echo ""
|
||||
done
|
||||
|
||||
# Create admin user via Python script
|
||||
docker-compose exec -T backend python3 << EOF
|
||||
from app.core.database import SessionLocal
|
||||
from app.models import User, UserRole
|
||||
from app.core.security import get_password_hash
|
||||
|
||||
db = SessionLocal()
|
||||
try:
|
||||
# Check if user exists
|
||||
existing_user = db.query(User).filter(User.username == "$ADMIN_USER").first()
|
||||
if existing_user:
|
||||
print("User '$ADMIN_USER' already exists")
|
||||
else:
|
||||
# Create admin user
|
||||
admin = User(
|
||||
username="$ADMIN_USER",
|
||||
email="$ADMIN_EMAIL",
|
||||
hashed_password=get_password_hash("$ADMIN_PASSWORD"),
|
||||
role=UserRole.ADMIN,
|
||||
is_active=True
|
||||
)
|
||||
db.add(admin)
|
||||
db.commit()
|
||||
print("Admin user created successfully")
|
||||
except Exception as e:
|
||||
print(f"Error creating admin user: {e}")
|
||||
finally:
|
||||
db.close()
|
||||
EOF
|
||||
|
||||
echo ""
|
||||
echo "========================================="
|
||||
echo " Installation Complete!"
|
||||
echo "========================================="
|
||||
echo ""
|
||||
echo "Depl0y is now running!"
|
||||
echo ""
|
||||
echo "Access the web interface at: http://$(hostname -I | awk '{print $1}')"
|
||||
echo ""
|
||||
echo "Default credentials:"
|
||||
echo " Username: $ADMIN_USER"
|
||||
echo " Password: (the one you just entered)"
|
||||
echo ""
|
||||
echo "Important: Change the default admin password after first login!"
|
||||
echo ""
|
||||
echo "To view logs:"
|
||||
echo " docker-compose logs -f"
|
||||
echo ""
|
||||
echo "To stop Depl0y:"
|
||||
echo " docker-compose down"
|
||||
echo ""
|
||||
echo "To start Depl0y:"
|
||||
echo " docker-compose up -d"
|
||||
echo ""
|
||||
echo "========================================="
|
||||
@@ -0,0 +1,203 @@
|
||||
#!/bin/bash
|
||||
#
|
||||
# Depl0y Uninstaller
|
||||
# Completely removes Depl0y from your system
|
||||
#
|
||||
|
||||
set -e
|
||||
|
||||
echo "╔══════════════════════════════════════════════════════════╗"
|
||||
echo "║ ║"
|
||||
echo "║ ██████╗ ███████╗██████╗ ██╗ ██████╗ ██╗ ██╗ ║"
|
||||
echo "║ ██╔══██╗██╔════╝██╔══██╗██║ ██╔═████╗╚██╗ ██╔╝ ║"
|
||||
echo "║ ██║ ██║█████╗ ██████╔╝██║ ██║██╔██║ ╚████╔╝ ║"
|
||||
echo "║ ██║ ██║██╔══╝ ██╔═══╝ ██║ ████╔╝██║ ╚██╔╝ ║"
|
||||
echo "║ ██████╔╝███████╗██║ ███████╗╚██████╔╝ ██║ ║"
|
||||
echo "║ ╚═════╝ ╚══════╝╚═╝ ╚══════╝ ╚═════╝ ╚═╝ ║"
|
||||
echo "║ ║"
|
||||
echo "║ UNINSTALLER ║"
|
||||
echo "║ ║"
|
||||
echo "╚══════════════════════════════════════════════════════════╝"
|
||||
echo ""
|
||||
|
||||
# Check if running as root
|
||||
if [ "$EUID" -ne 0 ]; then
|
||||
echo "ERROR: Please run as root (use sudo)"
|
||||
exit 1
|
||||
fi
|
||||
|
||||
# Check for -y flag or if stdin is not a terminal (piped input)
|
||||
SKIP_CONFIRM=false
|
||||
if [[ "$1" == "-y" || "$1" == "--yes" ]]; then
|
||||
SKIP_CONFIRM=true
|
||||
elif [ ! -t 0 ]; then
|
||||
# Not running in terminal (piped through curl)
|
||||
echo "⚠️ WARNING: Running in non-interactive mode"
|
||||
echo ""
|
||||
echo "To uninstall Depl0y, run this command:"
|
||||
echo " curl -fsSL http://deploy.agit8or.net/downloads/uninstall.sh | sudo bash -s -- -y"
|
||||
echo ""
|
||||
echo "Or download and run locally:"
|
||||
echo " curl -fsSL http://deploy.agit8or.net/downloads/uninstall.sh -o uninstall.sh"
|
||||
echo " sudo bash uninstall.sh"
|
||||
echo ""
|
||||
exit 1
|
||||
fi
|
||||
|
||||
if [ "$SKIP_CONFIRM" = false ]; then
|
||||
echo "⚠️ WARNING: This will completely remove Depl0y from your system"
|
||||
echo ""
|
||||
echo "This will:"
|
||||
echo " • Stop and remove the depl0y-backend service"
|
||||
echo " • Remove all Depl0y files from /opt/depl0y"
|
||||
echo " • Remove database and logs from /var/lib/depl0y and /var/log/depl0y"
|
||||
echo " • Remove nginx configuration"
|
||||
echo " • Remove the depl0y system user"
|
||||
echo " • Remove sudo permissions"
|
||||
echo " • Remove installed dependencies (Python packages, Node.js packages)"
|
||||
echo ""
|
||||
echo "⚠️ DATABASE WILL BE DELETED - All VM configurations will be lost!"
|
||||
echo ""
|
||||
read -p "Are you sure you want to uninstall Depl0y? (yes/NO): " -r CONFIRM < /dev/tty || CONFIRM="NO"
|
||||
echo ""
|
||||
|
||||
if [ "$CONFIRM" != "yes" ]; then
|
||||
echo "Uninstall cancelled."
|
||||
exit 0
|
||||
fi
|
||||
else
|
||||
echo "⚠️ Uninstalling Depl0y (confirmation skipped with -y flag)..."
|
||||
echo ""
|
||||
fi
|
||||
|
||||
echo "Starting uninstallation..."
|
||||
echo ""
|
||||
|
||||
# Stop and disable backend service
|
||||
echo "🛑 Stopping depl0y-backend service..."
|
||||
if systemctl is-active --quiet depl0y-backend; then
|
||||
systemctl stop depl0y-backend
|
||||
echo "✓ Service stopped"
|
||||
else
|
||||
echo "✓ Service was not running"
|
||||
fi
|
||||
|
||||
if systemctl is-enabled --quiet depl0y-backend 2>/dev/null; then
|
||||
systemctl disable depl0y-backend
|
||||
echo "✓ Service disabled"
|
||||
fi
|
||||
|
||||
# Remove systemd service file
|
||||
echo ""
|
||||
echo "🗑️ Removing systemd service..."
|
||||
if [ -f /etc/systemd/system/depl0y-backend.service ]; then
|
||||
rm -f /etc/systemd/system/depl0y-backend.service
|
||||
systemctl daemon-reload
|
||||
echo "✓ Service file removed"
|
||||
fi
|
||||
|
||||
# Remove application files
|
||||
echo ""
|
||||
echo "🗑️ Removing application files..."
|
||||
if [ -d /opt/depl0y ]; then
|
||||
rm -rf /opt/depl0y
|
||||
echo "✓ Removed /opt/depl0y"
|
||||
fi
|
||||
|
||||
# Remove data and logs
|
||||
echo ""
|
||||
echo "🗑️ Removing database and logs..."
|
||||
if [ -d /var/lib/depl0y ]; then
|
||||
rm -rf /var/lib/depl0y
|
||||
echo "✓ Removed /var/lib/depl0y (database, cloud images, ISOs)"
|
||||
fi
|
||||
|
||||
if [ -d /var/log/depl0y ]; then
|
||||
rm -rf /var/log/depl0y
|
||||
echo "✓ Removed /var/log/depl0y"
|
||||
fi
|
||||
|
||||
# Remove nginx configuration
|
||||
echo ""
|
||||
echo "🗑️ Removing nginx configuration..."
|
||||
if [ -f /etc/nginx/sites-enabled/depl0y ]; then
|
||||
rm -f /etc/nginx/sites-enabled/depl0y
|
||||
echo "✓ Removed nginx sites-enabled/depl0y"
|
||||
fi
|
||||
|
||||
if [ -f /etc/nginx/sites-available/depl0y ]; then
|
||||
rm -f /etc/nginx/sites-available/depl0y
|
||||
echo "✓ Removed nginx sites-available/depl0y"
|
||||
fi
|
||||
|
||||
# Restore default site if it existed
|
||||
if [ -f /etc/nginx/sites-available/default ] && [ ! -f /etc/nginx/sites-enabled/default ]; then
|
||||
ln -s /etc/nginx/sites-available/default /etc/nginx/sites-enabled/default
|
||||
echo "✓ Restored nginx default site"
|
||||
fi
|
||||
|
||||
# Test and reload nginx
|
||||
if nginx -t >/dev/null 2>&1; then
|
||||
systemctl reload nginx
|
||||
echo "✓ Nginx reloaded"
|
||||
else
|
||||
echo "⚠️ Nginx configuration test failed, skipping reload"
|
||||
fi
|
||||
|
||||
# Remove sudoers file
|
||||
echo ""
|
||||
echo "🗑️ Removing sudo permissions..."
|
||||
if [ -f /etc/sudoers.d/depl0y ]; then
|
||||
rm -f /etc/sudoers.d/depl0y
|
||||
echo "✓ Removed /etc/sudoers.d/depl0y"
|
||||
fi
|
||||
|
||||
# Remove depl0y user
|
||||
echo ""
|
||||
echo "👤 Removing depl0y system user..."
|
||||
if id -u depl0y >/dev/null 2>&1; then
|
||||
userdel -r depl0y 2>/dev/null || userdel depl0y 2>/dev/null || true
|
||||
echo "✓ User 'depl0y' removed"
|
||||
else
|
||||
echo "✓ User 'depl0y' does not exist"
|
||||
fi
|
||||
|
||||
# Remove temporary files and caches
|
||||
echo ""
|
||||
echo "🧹 Cleaning up temporary files and caches..."
|
||||
rm -f /tmp/depl0y-*.tar.gz 2>/dev/null || true
|
||||
rm -rf /tmp/depl0y-install 2>/dev/null || true
|
||||
rm -f /tmp/enable_cloud_images.sh 2>/dev/null || true
|
||||
rm -rf /tmp/depl0y* 2>/dev/null || true
|
||||
echo "✓ Temporary files cleaned"
|
||||
|
||||
# Optional: Remove installed packages (commented out by default for safety)
|
||||
echo ""
|
||||
echo "📦 Package cleanup..."
|
||||
echo " Note: System packages (Python, Node.js, nginx, etc.) were NOT removed"
|
||||
echo " as they may be used by other applications."
|
||||
echo ""
|
||||
echo " To remove them manually if desired:"
|
||||
echo " sudo apt-get remove --purge python3-venv python3-dev nodejs npm nginx"
|
||||
echo " sudo apt-get autoremove"
|
||||
|
||||
echo ""
|
||||
echo "╔══════════════════════════════════════════════════════════╗"
|
||||
echo "║ ║"
|
||||
echo "║ ✅ UNINSTALL COMPLETE ║"
|
||||
echo "║ ║"
|
||||
echo "╚══════════════════════════════════════════════════════════╝"
|
||||
echo ""
|
||||
echo "Depl0y has been completely removed from your system."
|
||||
echo ""
|
||||
echo "The following were NOT automatically removed (remove manually if needed):"
|
||||
echo " • System packages: python3, nodejs, npm, nginx, sqlite3"
|
||||
echo " • (These may be used by other applications)"
|
||||
echo ""
|
||||
echo "To remove system packages manually:"
|
||||
echo " sudo apt-get remove --purge python3-venv python3-dev nodejs npm nginx sqlite3"
|
||||
echo " sudo apt-get autoremove"
|
||||
echo ""
|
||||
echo "To reinstall Depl0y:"
|
||||
echo " curl -fsSL http://deploy.agit8or.net/downloads/install.sh | sudo bash"
|
||||
echo ""
|
||||
@@ -0,0 +1,29 @@
|
||||
#!/bin/bash
|
||||
# Depl0y Update Wrapper - Completely detaches installer from backend service
|
||||
# This ensures the installer survives when it stops the backend
|
||||
|
||||
INSTALLER_PATH="$1"
|
||||
|
||||
if [ -z "$INSTALLER_PATH" ]; then
|
||||
echo "ERROR: No installer path provided"
|
||||
exit 1
|
||||
fi
|
||||
|
||||
if [ ! -f "$INSTALLER_PATH" ]; then
|
||||
echo "ERROR: Installer not found at $INSTALLER_PATH"
|
||||
exit 1
|
||||
fi
|
||||
|
||||
# Use 'at' to schedule the installer to run immediately but completely detached
|
||||
# The 'at' daemon will run the job in its own process tree, independent of the backend service
|
||||
# IMPORTANT: Must run with sudo since installer needs root permissions
|
||||
echo "/usr/bin/sudo /bin/bash $INSTALLER_PATH > /tmp/depl0y-update.log 2>&1" | /usr/bin/at now 2>&1
|
||||
|
||||
if [ $? -eq 0 ]; then
|
||||
echo "Update scheduled successfully via 'at' daemon"
|
||||
echo "The installer will run independently and survive backend restarts"
|
||||
exit 0
|
||||
else
|
||||
echo "ERROR: Failed to schedule update"
|
||||
exit 1
|
||||
fi
|
||||
Reference in New Issue
Block a user