Files
proxmox-lxc-shell-commands/proxmox-lxc-zoraxy.sh

366 lines
12 KiB
Bash
Raw Permalink Blame History

This file contains invisible Unicode characters
This file contains invisible Unicode characters that are indistinguishable to humans but may be processed differently by a computer. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
#!/usr/bin/env bash
# Zoraxy LXC Installation Script
# Description: Installs Zoraxy reverse proxy with Web UI
# OS: Debian 12 (Bookworm)
# Ports: Web UI: 8000, HTTP: 80, HTTPS: 443
# Repository: https://github.com/tobychui/zoraxy
# Last Updated: 2025-01
set -euo pipefail
#################################################################
# Configuration Variables
#################################################################
# Container Configuration
CT_ID=${CT_ID:-10002}
CT_HOSTNAME=${CT_HOSTNAME:-"zoraxy"}
CT_CORES=${CT_CORES:-2}
CT_MEMORY=${CT_MEMORY:-1024}
CT_SWAP=${CT_SWAP:-512}
CT_DISK_SIZE=${CT_DISK_SIZE:-8}
# Network Configuration
CT_IP=${CT_IP:-"dhcp"}
CT_GATEWAY=${CT_GATEWAY:-""}
CT_BRIDGE=${CT_BRIDGE:-"vmbr0"}
CT_NAMESERVER=${CT_NAMESERVER:-"8.8.8.8"}
# Storage Configuration
CT_STORAGE=${CT_STORAGE:-"local-lvm"}
TEMPLATE_STORAGE=${TEMPLATE_STORAGE:-"local"}
# Debian Template
DEBIAN_VERSION="12"
TEMPLATE_NAME=""
# Application Configuration
ZORAXY_PORT=${ZORAXY_PORT:-8000}
ZORAXY_HTTP_PORT=${ZORAXY_HTTP_PORT:-80}
ZORAXY_HTTPS_PORT=${ZORAXY_HTTPS_PORT:-443}
ZORAXY_VERSION=${ZORAXY_VERSION:-"latest"}
# Container Options
CT_ONBOOT=${CT_ONBOOT:-1}
CT_UNPRIVILEGED=${CT_UNPRIVILEGED:-1}
CT_FEATURES=${CT_FEATURES:-"keyctl=1,nesting=1"}
#################################################################
# Color Output Functions
#################################################################
RED='\033[0;31m'
GREEN='\033[0;32m'
YELLOW='\033[1;33m'
BLUE='\033[0;34m'
NC='\033[0m'
info() { echo -e "${BLUE}[INFO]${NC} $1"; }
success() { echo -e "${GREEN}[SUCCESS]${NC} $1"; }
warn() { echo -e "${YELLOW}[WARN]${NC} $1"; }
error() { echo -e "${RED}[ERROR]${NC} $1"; }
#################################################################
# Validation Functions
#################################################################
check_root() {
if [[ $EUID -ne 0 ]]; then
error "This script must be run as root"
exit 1
fi
}
check_proxmox() {
if ! command -v pct &> /dev/null; then
error "This script must be run on a Proxmox VE host"
exit 1
fi
}
check_container_exists() {
if pct status "$CT_ID" &> /dev/null; then
error "Container ID $CT_ID already exists"
exit 1
fi
}
detect_and_download_template() {
info "Updating template database..."
pveam update 2>&1 || true
info "Detecting available Debian ${DEBIAN_VERSION} template..."
local available_template
available_template=$(pveam available --section system 2>/dev/null | grep "debian-${DEBIAN_VERSION}" | grep "standard" | tail -1 | awk '{print $2}')
if [[ -z "$available_template" ]]; then
error "No Debian ${DEBIAN_VERSION} template found"
exit 1
fi
TEMPLATE_NAME="$available_template"
info "Found template: $TEMPLATE_NAME"
if pveam list "$TEMPLATE_STORAGE" 2>/dev/null | grep -q "$TEMPLATE_NAME"; then
success "Template already downloaded"
return 0
fi
warn "Downloading Debian template..."
pveam download "$TEMPLATE_STORAGE" "$TEMPLATE_NAME" 2>&1 || {
error "Failed to download template"
exit 1
}
success "Template downloaded successfully"
}
#################################################################
# Container Creation Functions
#################################################################
create_container() {
info "Creating LXC container $CT_ID ($CT_HOSTNAME)..."
local net_config="name=eth0,bridge=${CT_BRIDGE},ip=${CT_IP}"
if [[ "$CT_IP" != "dhcp" ]] && [[ -n "$CT_GATEWAY" ]]; then
net_config="${net_config},gw=${CT_GATEWAY}"
fi
pct create "$CT_ID" \
"${TEMPLATE_STORAGE}:vztmpl/${TEMPLATE_NAME}" \
--hostname "$CT_HOSTNAME" \
--cores "$CT_CORES" \
--memory "$CT_MEMORY" \
--swap "$CT_SWAP" \
--rootfs "${CT_STORAGE}:${CT_DISK_SIZE}" \
--net0 "$net_config" \
--nameserver "$CT_NAMESERVER" \
--onboot "$CT_ONBOOT" \
--unprivileged "$CT_UNPRIVILEGED" \
--features "$CT_FEATURES" \
--ostype debian || {
error "Failed to create container"
exit 1
}
success "Container $CT_ID created successfully"
}
start_container() {
info "Starting container $CT_ID..."
pct start "$CT_ID" || {
error "Failed to start container"
exit 1
}
info "Waiting for container to boot..."
sleep 5
success "Container started successfully"
}
configure_autologin() {
info "Configuring automatic console login..."
pct exec "$CT_ID" -- bash -c "mkdir -p /etc/systemd/system/container-getty@1.service.d"
pct exec "$CT_ID" -- bash -c 'cat > /etc/systemd/system/container-getty@1.service.d/override.conf << EOF
[Service]
ExecStart=
ExecStart=-/sbin/agetty --autologin root --noclear --keep-baud tty%I 115200,38400,9600 \$TERM
EOF'
pct exec "$CT_ID" -- bash -c "systemctl daemon-reload"
pct exec "$CT_ID" -- bash -c "systemctl restart container-getty@1.service" 2>/dev/null || true
success "Automatic console login configured"
}
#################################################################
# Application Installation Functions
#################################################################
install_zoraxy() {
info "Installing Zoraxy in container $CT_ID..."
# Update and install required packages
info "Updating package list..."
pct exec "$CT_ID" -- bash -c "apt-get update -qq"
info "Installing required packages..."
pct exec "$CT_ID" -- bash -c "DEBIAN_FRONTEND=noninteractive apt-get install -y -qq curl ca-certificates wget jq"
# Create zoraxy directory
pct exec "$CT_ID" -- bash -c "mkdir -p /opt/zoraxy"
# Get latest release URL
info "Fetching latest Zoraxy release..."
local download_url
download_url=$(pct exec "$CT_ID" -- bash -c "curl -s https://api.github.com/repos/tobychui/zoraxy/releases/latest | jq -r '.assets[] | select(.name | contains(\"linux_amd64\")) | .browser_download_url'")
if [[ -z "$download_url" || "$download_url" == "null" ]]; then
error "Failed to get Zoraxy download URL"
exit 1
fi
info "Downloading Zoraxy from: $download_url"
pct exec "$CT_ID" -- bash -c "cd /opt/zoraxy && wget -q '$download_url' -O zoraxy && chmod +x zoraxy"
success "Zoraxy installed successfully"
}
configure_service() {
info "Configuring Zoraxy service..."
# Create systemd service file
pct exec "$CT_ID" -- bash -c "cat > /etc/systemd/system/zoraxy.service <<'EOF'
[Unit]
Description=Zoraxy Reverse Proxy
After=network.target
[Service]
Type=simple
User=root
WorkingDirectory=/opt/zoraxy
ExecStart=/opt/zoraxy/zoraxy -port=:${ZORAXY_PORT}
Restart=on-failure
RestartSec=5s
[Install]
WantedBy=multi-user.target
EOF"
# Reload systemd and enable service
pct exec "$CT_ID" -- bash -c "systemctl daemon-reload"
pct exec "$CT_ID" -- bash -c "systemctl enable zoraxy"
pct exec "$CT_ID" -- bash -c "systemctl start zoraxy"
# Wait for service to start
sleep 5
# Check service status
if pct exec "$CT_ID" -- bash -c "systemctl is-active --quiet zoraxy"; then
success "Zoraxy service configured and started"
else
warn "Service may still be initializing..."
pct exec "$CT_ID" -- bash -c "systemctl status zoraxy" || true
fi
}
add_container_notes() {
info "Adding container notes..."
local container_ip
if [[ "$CT_IP" == "dhcp" ]]; then
sleep 3
container_ip=$(pct exec "$CT_ID" -- hostname -I 2>/dev/null | awk '{print $1}')
if [[ -z "$container_ip" ]]; then
container_ip="[DHCP - check after boot]"
fi
else
container_ip="${CT_IP%/*}"
fi
local notes="Zoraxy Reverse Proxy
━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━
📋 CONTAINER DETAILS
━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━
Container ID: ${CT_ID}
Hostname: ${CT_HOSTNAME}
IP Address: ${container_ip}
CPU Cores: ${CT_CORES}
Memory: ${CT_MEMORY}MB
Disk Size: ${CT_DISK_SIZE}GB
🌐 APPLICATION ACCESS
━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━
Web UI: http://${container_ip}:${ZORAXY_PORT}
HTTP Port: ${ZORAXY_HTTP_PORT}
HTTPS Port: ${ZORAXY_HTTPS_PORT}
📝 FIRST TIME SETUP
━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━
1. Access Web UI at http://${container_ip}:${ZORAXY_PORT}
2. Create admin account on first visit
3. Configure reverse proxy rules via UI
4. Settings persist without restart!
🔧 SERVICE MANAGEMENT
━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━
Status: pct exec ${CT_ID} -- systemctl status zoraxy
Start: pct exec ${CT_ID} -- systemctl start zoraxy
Stop: pct exec ${CT_ID} -- systemctl stop zoraxy
Restart: pct exec ${CT_ID} -- systemctl restart zoraxy
Logs: pct exec ${CT_ID} -- journalctl -u zoraxy -f
🔌 API ACCESS (No restart needed!)
━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━
API Endpoint: http://${container_ip}:${ZORAXY_PORT}/api/
Documentation: https://github.com/tobychui/zoraxy/wiki/API
📦 CONTAINER MANAGEMENT
━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━
Enter: pct enter ${CT_ID}
Start: pct start ${CT_ID}
Stop: pct stop ${CT_ID}
AUTO-GENERATED BY: proxmox-infra/proxmox-lxc-shell-commands"
pct set "$CT_ID" -description "$notes" 2>/dev/null || warn "Failed to add notes"
success "Container notes added"
}
#################################################################
# Information Display
#################################################################
display_info() {
local container_ip
if [[ "$CT_IP" == "dhcp" ]]; then
container_ip=$(pct exec "$CT_ID" -- hostname -I | awk '{print $1}')
else
container_ip="${CT_IP%/*}"
fi
echo ""
echo "================================================================="
success "Zoraxy LXC Container Setup Complete!"
echo "================================================================="
echo ""
info "Container Details:"
echo " • Container ID: $CT_ID"
echo " • Hostname: $CT_HOSTNAME"
echo " • IP Address: $container_ip"
echo ""
info "Application Access:"
echo " • Web UI: http://${container_ip}:${ZORAXY_PORT}"
echo ""
warn "First time setup:"
echo " 1. Open Web UI and create admin account"
echo " 2. All settings can be changed via UI without restart!"
echo ""
echo "================================================================="
}
#################################################################
# Main Execution
#################################################################
main() {
info "Starting Zoraxy LXC container creation..."
echo ""
check_root
check_proxmox
check_container_exists
detect_and_download_template
create_container
start_container
configure_autologin
install_zoraxy
configure_service
add_container_notes
display_info
}
main "$@"