Add Proxmox LXC helper script for deployment
Creates a Debian 12 LXC container with Docker and deploys the portfolio automatically. Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
This commit is contained in:
+203
@@ -0,0 +1,203 @@
|
||||
#!/usr/bin/env bash
|
||||
|
||||
# LisiLou Portfolio - Proxmox LXC Helper Script
|
||||
# Run this script on your Proxmox host to create an LXC container with the portfolio
|
||||
|
||||
set -e
|
||||
|
||||
# Colors for output
|
||||
RED='\033[0;31m'
|
||||
GREEN='\033[0;32m'
|
||||
YELLOW='\033[1;33m'
|
||||
BLUE='\033[0;34m'
|
||||
NC='\033[0m' # No Color
|
||||
|
||||
# Default values
|
||||
CTID="${CTID:-}"
|
||||
HOSTNAME="${HOSTNAME:-lisilou-portfolio}"
|
||||
MEMORY="${MEMORY:-512}"
|
||||
DISK="${DISK:-4}"
|
||||
CORES="${CORES:-1}"
|
||||
STORAGE="${STORAGE:-local-lvm}"
|
||||
TEMPLATE_STORAGE="${TEMPLATE_STORAGE:-local}"
|
||||
BRIDGE="${BRIDGE:-vmbr0}"
|
||||
REPO_URL="https://github.com/jhodgkin/lisilou-portfolio.git"
|
||||
|
||||
header() {
|
||||
echo -e "\n${BLUE}━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━${NC}"
|
||||
echo -e "${BLUE} $1${NC}"
|
||||
echo -e "${BLUE}━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━${NC}\n"
|
||||
}
|
||||
|
||||
msg() {
|
||||
echo -e "${GREEN}[INFO]${NC} $1"
|
||||
}
|
||||
|
||||
warn() {
|
||||
echo -e "${YELLOW}[WARN]${NC} $1"
|
||||
}
|
||||
|
||||
error() {
|
||||
echo -e "${RED}[ERROR]${NC} $1"
|
||||
exit 1
|
||||
}
|
||||
|
||||
header "LisiLou Photography Portfolio - Proxmox Installer"
|
||||
|
||||
# Check if running on Proxmox
|
||||
if ! command -v pveversion &> /dev/null; then
|
||||
error "This script must be run on a Proxmox VE host"
|
||||
fi
|
||||
|
||||
msg "Proxmox VE $(pveversion | cut -d'/' -f2) detected"
|
||||
|
||||
# Get next available CTID if not specified
|
||||
if [ -z "$CTID" ]; then
|
||||
CTID=$(pvesh get /cluster/nextid)
|
||||
msg "Using next available CTID: $CTID"
|
||||
fi
|
||||
|
||||
# Prompt for configuration
|
||||
echo ""
|
||||
read -p "Container ID [$CTID]: " input
|
||||
CTID="${input:-$CTID}"
|
||||
|
||||
read -p "Hostname [$HOSTNAME]: " input
|
||||
HOSTNAME="${input:-$HOSTNAME}"
|
||||
|
||||
read -p "Memory in MB [$MEMORY]: " input
|
||||
MEMORY="${input:-$MEMORY}"
|
||||
|
||||
read -p "Disk size in GB [$DISK]: " input
|
||||
DISK="${input:-$DISK}"
|
||||
|
||||
read -p "CPU cores [$CORES]: " input
|
||||
CORES="${input:-$CORES}"
|
||||
|
||||
read -p "Storage [$STORAGE]: " input
|
||||
STORAGE="${input:-$STORAGE}"
|
||||
|
||||
read -p "Network bridge [$BRIDGE]: " input
|
||||
BRIDGE="${input:-$BRIDGE}"
|
||||
|
||||
echo ""
|
||||
read -p "Use DHCP for networking? [Y/n]: " use_dhcp
|
||||
use_dhcp="${use_dhcp:-Y}"
|
||||
|
||||
if [[ "${use_dhcp,,}" != "y" ]]; then
|
||||
read -p "IP Address (e.g., 192.168.1.100/24): " IP_ADDR
|
||||
read -p "Gateway: " GATEWAY
|
||||
NET_CONFIG="name=eth0,bridge=$BRIDGE,ip=$IP_ADDR,gw=$GATEWAY"
|
||||
else
|
||||
NET_CONFIG="name=eth0,bridge=$BRIDGE,ip=dhcp"
|
||||
fi
|
||||
|
||||
# Download Debian template if not exists
|
||||
header "Checking Container Template"
|
||||
TEMPLATE="debian-12-standard_12.7-1_amd64.tar.zst"
|
||||
TEMPLATE_PATH="/var/lib/vz/template/cache/$TEMPLATE"
|
||||
|
||||
if [ ! -f "$TEMPLATE_PATH" ]; then
|
||||
msg "Downloading Debian 12 template..."
|
||||
pveam update
|
||||
pveam download $TEMPLATE_STORAGE $TEMPLATE
|
||||
else
|
||||
msg "Template already exists"
|
||||
fi
|
||||
|
||||
# Create container
|
||||
header "Creating LXC Container"
|
||||
msg "Creating container $CTID ($HOSTNAME)..."
|
||||
|
||||
pct create $CTID "$TEMPLATE_STORAGE:vztmpl/$TEMPLATE" \
|
||||
--hostname $HOSTNAME \
|
||||
--memory $MEMORY \
|
||||
--cores $CORES \
|
||||
--rootfs $STORAGE:$DISK \
|
||||
--net0 $NET_CONFIG \
|
||||
--unprivileged 1 \
|
||||
--features nesting=1,keyctl=1 \
|
||||
--onboot 1 \
|
||||
--start 0
|
||||
|
||||
msg "Container created successfully"
|
||||
|
||||
# Start container
|
||||
msg "Starting container..."
|
||||
pct start $CTID
|
||||
sleep 5
|
||||
|
||||
# Wait for network
|
||||
msg "Waiting for network..."
|
||||
for i in {1..30}; do
|
||||
if pct exec $CTID -- ping -c 1 google.com &> /dev/null; then
|
||||
break
|
||||
fi
|
||||
sleep 2
|
||||
done
|
||||
|
||||
# Install Docker and setup application
|
||||
header "Installing Docker & Application"
|
||||
|
||||
pct exec $CTID -- bash -c "
|
||||
set -e
|
||||
|
||||
echo '[INFO] Updating system...'
|
||||
apt-get update
|
||||
apt-get upgrade -y
|
||||
|
||||
echo '[INFO] Installing dependencies...'
|
||||
apt-get install -y ca-certificates curl gnupg git
|
||||
|
||||
echo '[INFO] Adding Docker repository...'
|
||||
install -m 0755 -d /etc/apt/keyrings
|
||||
curl -fsSL https://download.docker.com/linux/debian/gpg | gpg --dearmor -o /etc/apt/keyrings/docker.gpg
|
||||
chmod a+r /etc/apt/keyrings/docker.gpg
|
||||
|
||||
echo \"deb [arch=\$(dpkg --print-architecture) signed-by=/etc/apt/keyrings/docker.gpg] https://download.docker.com/linux/debian \$(. /etc/os-release && echo \$VERSION_CODENAME) stable\" > /etc/apt/sources.list.d/docker.list
|
||||
|
||||
echo '[INFO] Installing Docker...'
|
||||
apt-get update
|
||||
apt-get install -y docker-ce docker-ce-cli containerd.io docker-buildx-plugin docker-compose-plugin
|
||||
|
||||
echo '[INFO] Enabling Docker service...'
|
||||
systemctl enable docker
|
||||
systemctl start docker
|
||||
|
||||
echo '[INFO] Cloning repository...'
|
||||
cd /opt
|
||||
git clone $REPO_URL
|
||||
cd lisilou-portfolio
|
||||
|
||||
echo '[INFO] Creating Docker network...'
|
||||
docker network create web || true
|
||||
|
||||
echo '[INFO] Starting application...'
|
||||
docker compose up -d
|
||||
|
||||
echo '[INFO] Installation complete!'
|
||||
"
|
||||
|
||||
# Get container IP
|
||||
header "Installation Complete!"
|
||||
CONTAINER_IP=$(pct exec $CTID -- hostname -I | awk '{print $1}')
|
||||
|
||||
echo -e "${GREEN}━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━${NC}"
|
||||
echo -e "${GREEN} LisiLou Portfolio has been deployed successfully!${NC}"
|
||||
echo -e "${GREEN}━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━${NC}"
|
||||
echo ""
|
||||
echo -e " ${BLUE}Container ID:${NC} $CTID"
|
||||
echo -e " ${BLUE}Hostname:${NC} $HOSTNAME"
|
||||
echo -e " ${BLUE}IP Address:${NC} $CONTAINER_IP"
|
||||
echo -e " ${BLUE}Portfolio URL:${NC} http://$CONTAINER_IP:8080"
|
||||
echo ""
|
||||
echo -e " ${YELLOW}Configuration:${NC}"
|
||||
echo -e " Edit: /opt/lisilou-portfolio/config/site.json"
|
||||
echo ""
|
||||
echo -e " ${YELLOW}Useful commands (run inside container):${NC}"
|
||||
echo -e " pct enter $CTID"
|
||||
echo -e " cd /opt/lisilou-portfolio"
|
||||
echo -e " docker compose logs -f"
|
||||
echo -e " docker compose restart"
|
||||
echo ""
|
||||
echo -e "${GREEN}━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━${NC}"
|
||||
Reference in New Issue
Block a user