Add traefik-gimini3.sh

bash -c "$(curl -fsSL http://192.168.1.43:3000/maq/helper-scripts/raw/branch/main/traefik-gimini3.sh)"
This commit is contained in:
maq
2025-08-23 06:50:56 -07:00
parent 9442597ac3
commit 56fff5b852

498
traefik-gimini3.sh Normal file
View File

@@ -0,0 +1,498 @@
#!/usr/bin/env bash
# Robust Traefik Install Script for Proxmox VE with Proxmox Provider Plugin
# Includes comprehensive error handling and testing.
set -Eeuo pipefail
# Colors for output
RED='\033[0;31m'
GREEN='\033[0;32m'
YELLOW='\033[1;33m'
BLUE='\033[0;34m'
NC='\033[0m' # No Color
# Global variables for cleanup
TEMP_FILES=()
CLEANUP_CTID=""
# Default configuration variables
CTID=""
HOSTNAME="traefik"
CORES=1
MEMORY=512
SWAP=512
DISK=2
UNPRIVILEGED=1
FEATURES="keyctl=1,nesting=1"
PASSWORD=""
IP=""
GATEWAY=""
DNS="1.1.1.1"
BRIDGE="vmbr0"
START_CT=1
TAG=""
CLOUDFLARE_API_TOKEN=""
CLOUDFLARE_EMAIL=""
DOMAIN=""
PROXMOX_API_URL="https://$(hostname):8006"
PROXMOX_API_USER=""
PROXMOX_API_TOKEN=""
# Plugin variables
PROXMOX_PLUGIN_VERSION="v0.1.0"
PROXMOX_PLUGIN_URL="https://plugins.traefik.io/public/plugins/67dd8d209fc1afd96d902040/traefik-proxmox-provider_${PROXMOX_PLUGIN_VERSION}_linux_amd64.zip"
# --- Function Definitions ---
# Cleanup function to remove temp files and handle incomplete containers
cleanup() {
local exit_code=$?
echo -e "\n${BLUE}[INFO]${NC} Performing cleanup..."
# Remove temporary files
for file in "${TEMP_FILES[@]}"; do
if [[ -f "$file" ]]; then
rm -f "$file" && echo "Removed temp file: $file"
fi
done
# If script fails before container is finalized, try to clean up the partial container
if [[ -n "$CLEANUP_CTID" ]] && pct status "$CLEANUP_CTID" &>/dev/null; then
if pct status "$CLEANUP_CTID" | grep -q "stopped"; then
pct destroy "$CLEANUP_CTID" && echo "Destroyed incomplete container $CLEANUP_CTID"
elif pct status "$CLEANUP_CTID" | grep -q "running"; then
pct stop "$CLEANUP_CTID" && sleep 2
pct destroy "$CLEANUP_CTID" && echo "Destroyed incomplete container $CLEANUP_CTID"
fi
fi
if [[ $exit_code -ne 0 ]]; then
echo -e "${RED}[ERROR]${NC} Script exited with error (code: $exit_code). Cleanup performed."
fi
exit $exit_code
}
# Register the cleanup function to run on script exit or interruption
trap cleanup EXIT INT TERM
log_info() { echo -e "${BLUE}[INFO]${NC} $1"; }
log_success() { echo -e "${GREEN}[SUCCESS]${NC} $1"; }
log_warning() { echo -e "${YELLOW}[WARNING]${NC} $1"; }
log_error() { echo -e "${RED}[ERROR]${NC} $1" >&2; }
# Check if command exists
command_exists() {
command -v "$1" >/dev/null 2>&1
}
# Check if running as root
check_root() {
if [[ $EUID -ne 0 ]]; then
log_error "This script must be run as root. Try: sudo bash $0"
exit 1
fi
}
# Validate CTID is available
validate_ctid() {
local id=$1
if [[ ! "$id" =~ ^[0-9]+$ ]]; then
log_error "Invalid CTID: $id. Must be a number."
return 1
fi
if pct status "$id" 2>/dev/null | grep -q "running\|stopped"; then
log_error "CTID $id is already in use. Please choose another."
return 1
fi
return 0
}
# Validate IP address format (simple validation)
validate_ip() {
local ip=$1
if [[ "$ip" == "dhcp" ]]; then
return 0
fi
# Check for CIDR format (e.g., 192.168.1.100/24)
if [[ ! "$ip" =~ ^[0-9]+\.[0-9]+\.[0-9]+\.[0-9]+/[0-9]{1,2}$ ]]; then
log_error "Invalid IP format: $ip. Must be in CIDR format (e.g., 192.168.1.100/24) or 'dhcp'."
return 1
fi
return 0
}
show_menu() {
echo -e "\n${BLUE}==== Proxmox VE Traefik Installer ====${NC}"
echo "1) Default Setup (Quick Install)"
echo "2) Custom Setup (Configure Options)"
echo "3) Add Cloudflare DNS Challenge"
echo "4) Configure Proxmox Provider"
echo "5) Exit"
read -rp "Please choose an option [1-5]: " main_choice
}
custom_setup() {
echo -e "\n${YELLOW}--- Custom Container Configuration ---${NC}"
while true; do
read -rp "Enter CTID (e.g., 200): " CTID
if validate_ctid "$CTID"; then
break
fi
done
read -rp "Enter Hostname [traefik]: " HOSTNAME_INPUT
HOSTNAME="${HOSTNAME_INPUT:-$HOSTNAME}"
read -rp "Enter Cores [1]: " CORES_INPUT
CORES="${CORES_INPUT:-$CORES}"
read -rp "Enter Memory (MB) [512]: " MEMORY_INPUT
MEMORY="${MEMORY_INPUT:-$MEMORY}"
read -rp "Enter Swap (MB) [512]: " SWAP_INPUT
SWAP="${SWAP_INPUT:-$SWAP}"
read -rp "Enter Disk Size (GB) [2]: " DISK_INPUT
DISK="${DISK_INPUT:-$DISK}"
while true; do
read -rp "Enter IP Address (CIDR format, e.g., 192.168.1.100/24) or 'dhcp': " IP
if validate_ip "$IP"; then
break
fi
done
if [[ "$IP" != "dhcp" ]]; then
read -rp "Enter Gateway [192.168.1.1]: " GATEWAY_INPUT
GATEWAY="${GATEWAY_INPUT:-$GATEWAY}"
read -rp "Enter DNS Server [1.1.1.1]: " DNS_INPUT
DNS="${DNS_INPUT:-$DNS}"
fi
read -rp "Enter Bridge [vmbr0]: " BRIDGE_INPUT
BRIDGE="${BRIDGE_INPUT:-$BRIDGE}"
read -srp "Enter Root Password for Container: " PASSWORD
echo
read -rp "Start container after creation? (y/n) [y]: " START_CT_INPUT
START_CT_INPUT="${START_CT_INPUT:-y}"
[[ $START_CT_INPUT == "n" ]] && START_CT=0
read -rp "Enter Proxmox VE Tag (optional): " TAG
}
setup_cloudflare() {
echo -e "\n${YELLOW}--- Cloudflare DNS Challenge Setup ---${NC}"
log_info "This will configure Traefik to use Cloudflare DNS for wildcard certificates."
log_info "Ensure your domain's nameservers are pointed to Cloudflare."
read -rp "Enter your domain (e.g., example.com): " DOMAIN
read -rp "Enter your Cloudflare Email: " CLOUDFLARE_EMAIL
read -srp "Enter your Cloudflare API Token: " CLOUDFLARE_API_TOKEN
echo
}
setup_proxmox_provider() {
echo -e "\n${YELLOW}--- Proxmox Provider Configuration ---${NC}"
log_info "The Traefik Proxmox Provider will automatically discover services in your containers/VMs."
log_warning "You need to create an API Token in the Proxmox web UI first."
echo
read -rp "Enter the Proxmox API User (e.g., 'traefik-api@pve'): " PROXMOX_API_USER
read -srp "Enter the Proxmox API Token Secret: " PROXMOX_API_TOKEN
echo
read -rp "Enter Proxmox API URL [${PROXMOX_API_URL}]: " PROXMOX_API_URL_INPUT
PROXMOX_API_URL="${PROXMOX_API_URL_INPUT:-$PROXMOX_API_URL}"
}
create_container() {
local id=$1
local TEMPLATE_NAME="debian-12-standard_12.7-1_amd64.tar.zst"
# Check and download template if it doesn't exist
if ! pveam list local | grep -q "$TEMPLATE_NAME"; then
log_info "LXC template '$TEMPLATE_NAME' not found locally. Downloading..."
if ! pveam download local "$TEMPLATE_NAME"; then
log_error "Failed to download the required LXC template. Please check your internet connection or Proxmox template mirrors."
return 1
fi
log_success "Template downloaded successfully."
fi
log_info "Creating LXC container (ID: $id)..."
local CREATE_CMD="pct create $id \
\"local:vztmpl/$TEMPLATE_NAME\" \
--arch amd64 \
--cores $CORES \
--memory $MEMORY \
--swap $SWAP \
--rootfs local-lvm:${DISK} \
--hostname $HOSTNAME \
--password \"$PASSWORD\" \
--features \"$FEATURES\" \
--unprivileged $UNPRIVILEGED \
--onboot 1"
if [[ "$IP" == "dhcp" ]]; then
CREATE_CMD="$CREATE_CMD --net0 name=eth0,bridge=$BRIDGE,ip=dhcp"
else
CREATE_CMD="$CREATE_CMD --net0 name=eth0,bridge=$BRIDGE,ip=$IP,gw=$GATEWAY"
CREATE_CMD="$CREATE_CMD --nameserver \"$DNS\""
fi
if ! eval "$CREATE_CMD"; then
log_error "Failed to create container $id. Check parameters and try again."
return 1
fi
CLEANUP_CTID="$id" # Set global for cleanup after successful creation
if [[ -n "$TAG" ]]; then
if ! pct set "$id" --tags "$TAG"; then
log_warning "Failed to apply tag '$TAG' to container $id. Continuing..."
else
log_info "Tag '$TAG' applied to container $id."
fi
fi
if [[ $START_CT -eq 1 ]]; then
if ! pct start "$id"; then
log_error "Failed to start container $id. Check 'pct status $id' for details."
return 1
fi
log_info "Starting container $id..."
for i in {1..10}; do
if pct status "$id" | grep -q "running"; then
break
fi
sleep 1
done
if ! pct status "$id" | grep -q "running"; then
log_warning "Container $id may not be fully ready. Proceeding with caution..."
fi
else
log_info "Container $id created but not started."
fi
CLEANUP_CTID="" # Clear cleanup ID since container was created successfully
return 0
}
safe_container_exec() {
local id=$1
shift
local command="$*"
local max_retries=3
local retry_count=0
while [[ $retry_count -lt $max_retries ]]; do
if pct exec "$id" -- bash -c "$command"; then
return 0
else
((retry_count++))
if [[ $retry_count -eq $max_retries ]]; then
log_warning "Command failed after $max_retries attempts: $command"
return 1
fi
sleep 2
fi
done
}
install_traefik() {
local id=$1
log_info "Installing Traefik in container $id..."
if ! safe_container_exec "$id" "apt-get update"; then
log_warning "apt-get update had issues. Network might be slow. Continuing..."
fi
if ! safe_container_exec "$id" "apt-get install -y curl wget sudo unzip"; then
log_error "Failed to install essential packages in container $id."
return 1
fi
log_info "Installing Traefik binary and service..."
if ! safe_container_exec "$id" "wget -qO- https://raw.githubusercontent.com/traefik/traefik/master/install.sh | bash -s -- --version v2.11 --daemon"; then
log_error "Failed to install Traefik binary. Please check for errors."
return 1
fi
log_success "Traefik binary installed."
if ! safe_container_exec "$id" "mkdir -p /etc/traefik/conf.d"; then
log_warning "Could not create conf.d directory. This might cause issues later."
fi
# Install Proxmox Provider plugin if configured
if [[ -n "$PROXMOX_API_USER" && -n "$PROXMOX_API_TOKEN" ]]; then
log_info "Downloading and installing Traefik Proxmox Provider plugin version ${PROXMOX_PLUGIN_VERSION}..."
if ! safe_container_exec "$id" "wget --timeout=30 -O /tmp/proxmox-plugin.zip ${PROXMOX_PLUGIN_URL}"; then
log_warning "Failed to download Proxmox Provider plugin. Check internet connection."
else
if ! safe_container_exec "$id" "unzip -o /tmp/proxmox-plugin.zip -d /tmp/ && install -m 755 /tmp/traefik-proxmox-provider /usr/local/bin/ && rm -f /tmp/proxmox-plugin.zip /tmp/traefik-proxmox-provider"; then
log_warning "Failed to install Proxmox Provider plugin properly."
else
log_success "Proxmox Provider plugin installed."
fi
fi
fi
# Configure Traefik
log_info "Configuring Traefik..."
if ! safe_container_exec "$id" "cat > /etc/traefik/traefik.yml <<EOF
global:
sendAnonymousUsage: false
api:
dashboard: true
insecure: false
entryPoints:
web:
address: :80
websecure:
address: :443
providers:
docker:
endpoint: \"unix:///var/run/docker.sock\"
exposedByDefault: false
file:
directory: /etc/traefik/conf.d
watch: true
EOF"; then
log_error "Failed to write base Traefik configuration."
return 1
fi
# Cloudflare configuration
if [[ -n "$CLOUDFLARE_API_TOKEN" && -n "$DOMAIN" ]]; then
log_info "Adding Cloudflare configuration..."
if ! safe_container_exec "$id" "cat >> /etc/traefik/traefik.yml <<EOF
certificatesResolvers:
cloudflare:
acme:
email: $CLOUDFLARE_EMAIL
storage: /etc/traefik/acme.json
dnsChallenge:
provider: cloudflare
delayBeforeCheck: 30
resolvers:
- \"1.1.1.1:53\"
- \"1.0.0.1:53\"
EOF"; then
log_warning "Failed to append Cloudflare configuration to Traefik config."
fi
if ! safe_container_exec "$id" "echo \"CF_API_EMAIL=$CLOUDFLARE_EMAIL\" > /etc/traefik/cloudflare.env && echo \"CF_DNS_API_TOKEN=$CLOUDFLARE_API_TOKEN\" >> /etc/traefik/cloudflare.env && chmod 600 /etc/traefik/cloudflare.env"; then
log_warning "Failed to create Cloudflare environment file."
fi
fi
# Proxmox Provider configuration
if [[ -n "$PROXMOX_API_USER" && -n "$PROXMOX_API_TOKEN" ]]; then
log_info "Adding Proxmox Provider configuration..."
if ! safe_container_exec "$id" "cat >> /etc/traefik/traefik.yml <<EOF
plugin:
proxmox:
apiURL: \"$PROXMOX_API_URL\"
insecure: false
user: \"$PROXMOX_API_USER\"
token: \"$PROXMOX_API_TOKEN\"
tls:
ca: /etc/traefik/proxmox-ca.pem
refreshInterval: 30s
exposedByDefault: false
EOF"; then
log_warning "Failed to append Proxmox Provider configuration to Traefik config."
fi
# Try to get Proxmox CA certificate
log_info "Attempting to retrieve Proxmox CA certificate automatically..."
if ! safe_container_exec "$id" "curl -s --insecure \"$PROXMOX_API_URL/json/nodes/\" 2>&1 | awk 'BEGIN {cert=0} /^.*SSL certificate problem/ {cert=1} {if(cert==1) print}' | sed -n '/-----BEGIN CERTIFICATE-----/,/-----END CERTIFICATE-----/p' > /etc/traefik/proxmox-ca.pem"; then
log_warning "Could not automatically retrieve Proxmox CA certificate. The certificate download attempt was made using an insecure method, and it is recommended to transfer the certificate manually for enhanced security. You may need to add it manually to /etc/traefik/proxmox-ca.pem in the container."
fi
fi
# Restart Traefik
log_info "Restarting Traefik to apply configuration..."
if ! safe_container_exec "$id" "systemctl restart traefik"; then
log_error "Failed to restart Traefik service. Check configuration manually."
return 1
fi
log_success "Traefik installation and configuration complete in container $id."
return 0
}
main() {
check_root
# Test for required commands
if ! command_exists pct; then
log_error "Proxmox CLI tools (pct) not found. Are you running this on a Proxmox node?"
exit 1
fi
while true; do
show_menu
case $main_choice in
1)
CTID=$(( 200 + RANDOM % 100 ))
if ! validate_ctid "$CTID"; then
CTID=$(( CTID + 1 )) # Simple retry
validate_ctid "$CTID" || exit 1
fi
IP="dhcp"
GATEWAY=""
DNS="1.1.1.1"
PASSWORD=$(tr -dc A-Za-z0-9 </dev/urandom | head -c 16 ; echo '')
log_info "Generated random CTID: $CTID"
log_info "Generated random password: $PASSWORD"
log_warning "SECURITY WARNING: The password above is for initial access only. It is strongly recommended that you log in and change it immediately."
if create_container "$CTID"; then
if install_traefik "$CTID"; then
log_success "Default setup completed successfully!"
else
log_error "Traefik installation had issues. Check container logs."
fi
fi
break
;;
2)
custom_setup
if [[ -z "$CTID" || -z "$PASSWORD" || ( "$IP" != "dhcp" && -z "$IP" ) ]]; then
log_error "Missing required parameters (CTID, Password, or IP)."
else
if create_container "$CTID"; then
if install_traefik "$CTID"; then
log_success "Custom setup completed successfully!"
else
log_error "Traefik installation had issues. Check container logs."
fi
fi
fi
break
;;
3)
setup_cloudflare
log_info "Cloudflare settings saved."
;;
4)
setup_proxmox_provider
log_info "Proxmox Provider settings saved."
;;
5)
log_info "Exiting. Nothing was installed."
exit 0
;;
*)
log_error "Invalid option. Please choose 1, 2, 3, 4, or 5."
;;
esac
done
log_success "Script execution finished!"
log_info "Container ID: $CTID"
log_info "Hostname: $HOSTNAME"
[[ -n "$PASSWORD" ]] && log_info "Root Password: $PASSWORD"
[[ -n "$PROXMOX_API_USER" ]] && log_info "Proxmox Provider is CONFIGURED for auto-discovery."
[[ -n "$DOMAIN" ]] && log_info "Cloudflare DNS challenge configured for domain: $DOMAIN"
log_info "You can access the container: pct enter $CTID"
}
main "$@"