added ansible script

This commit is contained in:
liph
2026-02-16 23:40:30 +01:00
parent e6e444fff7
commit 8925d9677e
86 changed files with 15476 additions and 1911 deletions

463
ansible/setup.sh Executable file
View File

@@ -0,0 +1,463 @@
#!/bin/bash
#
# Nextcloud Stack - Interactive Setup Script
# This script collects all configuration variables and generates Ansible inventory
#
set -euo pipefail
# Colors
RED='\033[0;31m'
GREEN='\033[0;32m'
YELLOW='\033[1;33m'
BLUE='\033[0;34m'
CYAN='\033[0;36m'
NC='\033[0m' # No Color
# Header
clear
echo -e "${CYAN}╔════════════════════════════════════════════════════════════╗${NC}"
echo -e "${CYAN}║ Nextcloud Stack - Ansible Deployment Setup ║${NC}"
echo -e "${CYAN}║ Version 1.0 ║${NC}"
echo -e "${CYAN}╚════════════════════════════════════════════════════════════╝${NC}"
echo ""
echo "This script will guide you through configuring your Nextcloud"
echo "deployment. Information will be encrypted using Ansible Vault."
echo ""
# Arrays to store server data
declare -a SERVER_IPS
declare -a SERVER_HOSTNAMES
declare -a SERVER_DOMAINS
declare -a SERVER_SSH_USERS
declare -a SERVER_SSH_KEYS
# Global variables
ADMIN_USER=""
ADMIN_PASSWORD=""
USER_NAME=""
USER_EMAIL=""
TIMEZONE="Europe/Zurich"
INSTALL_RCLONE="y"
ENABLE_PUBLIC_STATUS="n"
ALERT_EMAIL=""
TAILSCALE_AUTH_KEY=""
# Subdomain defaults
SUBDOMAIN_NEXTCLOUD="cloud"
SUBDOMAIN_OFFICE="office"
SUBDOMAIN_DRAW="draw"
SUBDOMAIN_NOTES="notes"
SUBDOMAIN_HOMARR="home"
SUBDOMAIN_DOCKHAND="manage"
SUBDOMAIN_UPTIME="uptime"
# Database defaults
DB_NAME="nextcloud"
DB_USER="nextcloud"
# Generate random password
generate_password() {
openssl rand -base64 32 | tr -d "=+/" | cut -c1-32
}
# Validate IP address
validate_ip() {
local ip=$1
if [[ $ip =~ ^[0-9]{1,3}\.[0-9]{1,3}\.[0-9]{1,3}\.[0-9]{1,3}$ ]]; then
return 0
else
return 1
fi
}
# Validate domain
validate_domain() {
local domain=$1
if [[ $domain =~ ^[a-zA-Z0-9][a-zA-Z0-9-]{0,61}[a-zA-Z0-9]?\.[a-zA-Z]{2,}$ ]]; then
return 0
else
return 1
fi
}
# Server Configuration
echo -e "${GREEN}=== Server Configuration ===${NC}"
echo "Enter server details (press Enter without input to finish):"
echo ""
server_count=0
while true; do
((server_count++))
echo -e "${BLUE}Server $server_count:${NC}"
# IP Address
while true; do
read -p " IP address: " ip
if [[ -z "$ip" ]]; then
((server_count--))
break 2
fi
if validate_ip "$ip"; then
SERVER_IPS+=("$ip")
break
else
echo -e "${RED} Invalid IP address. Please try again.${NC}"
fi
done
# Hostname
read -p " Hostname [cloud$(printf "%02d" $server_count)]: " hostname
hostname=${hostname:-cloud$(printf "%02d" $server_count)}
SERVER_HOSTNAMES+=("$hostname")
# Domain
while true; do
read -p " Domain (e.g., example.com): " domain
if [[ -z "$domain" ]]; then
echo -e "${RED} Domain is required. Please try again.${NC}"
elif validate_domain "$domain"; then
SERVER_DOMAINS+=("$domain")
break
else
echo -e "${RED} Invalid domain format. Please try again.${NC}"
fi
done
# SSH User
read -p " SSH user [root]: " ssh_user
ssh_user=${ssh_user:-root}
SERVER_SSH_USERS+=("$ssh_user")
# SSH Key
read -p " SSH key path [~/.ssh/id_rsa]: " ssh_key
ssh_key=${ssh_key:-~/.ssh/id_rsa}
# Expand tilde
ssh_key="${ssh_key/#\~/$HOME}"
SERVER_SSH_KEYS+=("$ssh_key")
echo ""
done
if [[ ${#SERVER_IPS[@]} -eq 0 ]]; then
echo -e "${RED}Error: At least one server is required.${NC}"
exit 1
fi
echo -e "${GREEN}✓ Configured ${#SERVER_IPS[@]} server(s)${NC}"
echo ""
# User Information
echo -e "${GREEN}=== User Information ===${NC}"
read -p "Your name: " USER_NAME
while [[ -z "$USER_NAME" ]]; do
echo -e "${RED}Name is required.${NC}"
read -p "Your name: " USER_NAME
done
read -p "Your email: " USER_EMAIL
while [[ -z "$USER_EMAIL" ]] || [[ ! "$USER_EMAIL" =~ ^[a-zA-Z0-9._%+-]+@[a-zA-Z0-9.-]+\.[a-zA-Z]{2,}$ ]]; do
echo -e "${RED}Valid email is required.${NC}"
read -p "Your email: " USER_EMAIL
done
read -p "Timezone [Europe/Zurich]: " TIMEZONE
TIMEZONE=${TIMEZONE:-Europe/Zurich}
echo ""
# Nextcloud Admin Account
echo -e "${GREEN}=== Nextcloud Admin Account ===${NC}"
read -p "Admin username [admin]: " ADMIN_USER
ADMIN_USER=${ADMIN_USER:-admin}
while true; do
read -sp "Admin password: " ADMIN_PASSWORD
echo ""
read -sp "Confirm password: " ADMIN_PASSWORD_CONFIRM
echo ""
if [[ "$ADMIN_PASSWORD" == "$ADMIN_PASSWORD_CONFIRM" ]] && [[ ${#ADMIN_PASSWORD} -ge 8 ]]; then
break
elif [[ ${#ADMIN_PASSWORD} -lt 8 ]]; then
echo -e "${RED}Password must be at least 8 characters.${NC}"
else
echo -e "${RED}Passwords do not match. Please try again.${NC}"
fi
done
echo ""
# Subdomain Configuration
echo -e "${GREEN}=== Subdomain Configuration ===${NC}"
echo "Press Enter to use defaults shown in brackets"
read -p "Nextcloud subdomain [cloud]: " SUBDOMAIN_NEXTCLOUD
SUBDOMAIN_NEXTCLOUD=${SUBDOMAIN_NEXTCLOUD:-cloud}
read -p "OnlyOffice subdomain [office]: " SUBDOMAIN_OFFICE
SUBDOMAIN_OFFICE=${SUBDOMAIN_OFFICE:-office}
read -p "Excalidraw subdomain [draw]: " SUBDOMAIN_DRAW
SUBDOMAIN_DRAW=${SUBDOMAIN_DRAW:-draw}
read -p "Obsidian subdomain [notes]: " SUBDOMAIN_NOTES
SUBDOMAIN_NOTES=${SUBDOMAIN_NOTES:-notes}
read -p "Homarr subdomain [home]: " SUBDOMAIN_HOMARR
SUBDOMAIN_HOMARR=${SUBDOMAIN_HOMARR:-home}
read -p "Dockhand subdomain [manage]: " SUBDOMAIN_DOCKHAND
SUBDOMAIN_DOCKHAND=${SUBDOMAIN_DOCKHAND:-manage}
read -p "Uptime Kuma subdomain [uptime]: " SUBDOMAIN_UPTIME
SUBDOMAIN_UPTIME=${SUBDOMAIN_UPTIME:-uptime}
echo ""
# Database Configuration
echo -e "${GREEN}=== Database Configuration ===${NC}"
read -p "Database name [nextcloud]: " DB_NAME
DB_NAME=${DB_NAME:-nextcloud}
read -p "Database user [nextcloud]: " DB_USER
DB_USER=${DB_USER:-nextcloud}
echo "Generating secure passwords..."
DB_PASSWORD=$(generate_password)
REDIS_PASSWORD=$(generate_password)
HOMARR_SECRET=$(openssl rand -hex 32)
echo -e "${GREEN}✓ Passwords generated${NC}"
echo ""
# Tailscale Configuration
echo -e "${GREEN}=== Tailscale Configuration ===${NC}"
read -p "Install Tailscale? (y/n) [y]: " install_tailscale
install_tailscale=${install_tailscale:-y}
if [[ "$install_tailscale" == "y" ]]; then
read -p "Tailscale auth key (optional, press Enter to skip): " TAILSCALE_AUTH_KEY
if [[ -z "$TAILSCALE_AUTH_KEY" ]]; then
echo "Note: Tailscale will be installed but not activated."
echo " Activate manually with: sudo tailscale up"
fi
fi
echo ""
# Monitoring Configuration
echo -e "${GREEN}=== Monitoring Configuration ===${NC}"
read -p "Email for uptime alerts: " ALERT_EMAIL
while [[ -z "$ALERT_EMAIL" ]] || [[ ! "$ALERT_EMAIL" =~ ^[a-zA-Z0-9._%+-]+@[a-zA-Z0-9.-]+\.[a-zA-Z]{2,}$ ]]; do
echo -e "${RED}Valid email is required.${NC}"
read -p "Email for uptime alerts: " ALERT_EMAIL
done
read -p "Enable public status page? (y/n) [n]: " ENABLE_PUBLIC_STATUS
ENABLE_PUBLIC_STATUS=${ENABLE_PUBLIC_STATUS:-n}
echo ""
# Backup Configuration
echo -e "${GREEN}=== Backup Configuration ===${NC}"
echo "Backup retention: 30 days (default)"
read -p "Install rclone for future remote backups? (y/n) [y]: " INSTALL_RCLONE
INSTALL_RCLONE=${INSTALL_RCLONE:-y}
if [[ "$INSTALL_RCLONE" == "y" ]]; then
echo "Note: rclone will be installed but not configured."
echo " Configure later with: rclone config"
fi
echo ""
# Ansible Vault Password
echo -e "${GREEN}=== Security ===${NC}"
echo "Create Ansible Vault password (will encrypt all secrets):"
while true; do
read -sp "Vault password: " VAULT_PASSWORD
echo ""
read -sp "Confirm: " VAULT_PASSWORD_CONFIRM
echo ""
if [[ "$VAULT_PASSWORD" == "$VAULT_PASSWORD_CONFIRM" ]] && [[ ${#VAULT_PASSWORD} -ge 8 ]]; then
break
elif [[ ${#VAULT_PASSWORD} -lt 8 ]]; then
echo -e "${RED}Password must be at least 8 characters.${NC}"
else
echo -e "${RED}Passwords do not match. Please try again.${NC}"
fi
done
echo ""
# Configuration Summary
echo -e "${CYAN}╔════════════════════════════════════════════════════════════╗${NC}"
echo -e "${CYAN}║ CONFIGURATION SUMMARY ║${NC}"
echo -e "${CYAN}╚════════════════════════════════════════════════════════════╝${NC}"
echo ""
echo "Servers: ${#SERVER_IPS[@]}"
for i in "${!SERVER_IPS[@]}"; do
echo "${SERVER_IPS[$i]} (${SERVER_DOMAINS[$i]})"
done
echo ""
echo "Services (per server):"
echo " • Nextcloud: https://$SUBDOMAIN_NEXTCLOUD.<domain>"
echo " • OnlyOffice: https://$SUBDOMAIN_OFFICE.<domain>"
echo " • Excalidraw: https://$SUBDOMAIN_DRAW.<domain>"
echo " • Obsidian: https://$SUBDOMAIN_NOTES.<domain>"
echo " • Homarr: https://$SUBDOMAIN_HOMARR.<domain> (Tailscale)"
echo " • Dockhand: https://$SUBDOMAIN_DOCKHAND.<domain> (Tailscale)"
echo " • Uptime Kuma: https://$SUBDOMAIN_UPTIME.<domain> (Tailscale)"
echo ""
read -p "Proceed with these settings? (y/n): " confirm
if [[ "$confirm" != "y" ]]; then
echo "Setup cancelled."
exit 0
fi
echo ""
# Generate Configuration Files
echo "Generating configuration files..."
# Create inventory directory
mkdir -p inventory/group_vars/all
# Generate hosts.yml
cat >inventory/hosts.yml <<EOF
# Ansible Inventory - Generated by setup.sh
# Date: $(date)
all:
children:
nextcloud_servers:
hosts:
EOF
for i in "${!SERVER_IPS[@]}"; do
cat >>inventory/hosts.yml <<EOF
${SERVER_HOSTNAMES[$i]}:
ansible_host: ${SERVER_IPS[$i]}
ansible_user: ${SERVER_SSH_USERS[$i]}
ansible_ssh_private_key_file: ${SERVER_SSH_KEYS[$i]}
domain: ${SERVER_DOMAINS[$i]}
EOF
done
echo -e "${GREEN}✓ Created: inventory/hosts.yml${NC}"
# Generate vars.yml (public variables)
cat >inventory/group_vars/all/vars.yml <<EOF
# Public Variables - Generated by setup.sh
# Date: $(date)
# User Information
user_name: "$USER_NAME"
user_email: "$USER_EMAIL"
timezone: "$TIMEZONE"
# Admin Account
admin_user: "$ADMIN_USER"
# Subdomain Configuration
subdomain_nextcloud: "$SUBDOMAIN_NEXTCLOUD"
subdomain_office: "$SUBDOMAIN_OFFICE"
subdomain_draw: "$SUBDOMAIN_DRAW"
subdomain_notes: "$SUBDOMAIN_NOTES"
subdomain_homarr: "$SUBDOMAIN_HOMARR"
subdomain_dockhand: "$SUBDOMAIN_DOCKHAND"
subdomain_uptime: "$SUBDOMAIN_UPTIME"
# Database Configuration
db_name: "$DB_NAME"
db_user: "$DB_USER"
# Backup Configuration
backup_retention_days: 30
install_rclone: $INSTALL_RCLONE
# Monitoring
alert_email: "$ALERT_EMAIL"
enable_public_status: $ENABLE_PUBLIC_STATUS
# Deployment Settings
deployment_dir: "/opt/nextcloud-stack"
stack_name: "nextcloud"
# Docker Configuration
docker_compose_version: "v2"
EOF
echo -e "${GREEN}✓ Created: inventory/group_vars/all/vars.yml${NC}"
# Generate vault.yml (encrypted secrets)
VAULT_CONTENT=$(
cat <<EOF
# Encrypted Secrets - Generated by setup.sh
# Date: $(date)
# Admin Password
admin_password: "$ADMIN_PASSWORD"
# Database Credentials
db_password: "$DB_PASSWORD"
redis_password: "$REDIS_PASSWORD"
# Application Secrets
homarr_secret: "$HOMARR_SECRET"
# Tailscale
tailscale_auth_key: "$TAILSCALE_AUTH_KEY"
EOF
)
# Save vault password to temporary file
echo "$VAULT_PASSWORD" >.vault_pass_temp
# Create encrypted vault
echo "$VAULT_CONTENT" | ansible-vault encrypt --vault-password-file=.vault_pass_temp --output=inventory/group_vars/all/vault.yml
# Clean up temp file
rm .vault_pass_temp
echo -e "${GREEN}✓ Created: inventory/group_vars/all/vault.yml (encrypted)${NC}"
echo ""
# Save vault password hint
echo "IMPORTANT: Save your vault password!"
echo "You will need it to run the playbook."
echo ""
echo "Vault password: **************** (hidden)"
echo ""
# Final Instructions
echo -e "${CYAN}╔════════════════════════════════════════════════════════════╗${NC}"
echo -e "${CYAN}║ READY TO DEPLOY! ║${NC}"
echo -e "${CYAN}╚════════════════════════════════════════════════════════════╝${NC}"
echo ""
echo "Next steps:"
echo ""
echo "1. Review configuration (optional):"
echo " ansible-inventory --list"
echo ""
echo "2. Test connectivity:"
echo " ansible all -m ping --ask-vault-pass"
echo ""
echo "3. Deploy stack:"
echo " ansible-playbook playbooks/site.yml --ask-vault-pass"
echo ""
echo " OR use Makefile:"
echo " make deploy"
echo ""
echo "Estimated deployment time: 30-45 minutes per server"
echo ""
echo -e "${YELLOW}WARNING: Ensure DNS records are configured before deploying!${NC}"
echo " Let's Encrypt will fail if DNS is not pointing correctly."
echo ""
echo "Required DNS records for each server:"
for i in "${!SERVER_DOMAINS[@]}"; do
echo " ${SERVER_DOMAINS[$i]}:"
echo " $SUBDOMAIN_NEXTCLOUD.${SERVER_DOMAINS[$i]}${SERVER_IPS[$i]}"
echo " $SUBDOMAIN_OFFICE.${SERVER_DOMAINS[$i]}${SERVER_IPS[$i]}"
echo " $SUBDOMAIN_DRAW.${SERVER_DOMAINS[$i]}${SERVER_IPS[$i]}"
echo " $SUBDOMAIN_NOTES.${SERVER_DOMAINS[$i]}${SERVER_IPS[$i]}"
echo " $SUBDOMAIN_HOMARR.${SERVER_DOMAINS[$i]}${SERVER_IPS[$i]}"
echo " $SUBDOMAIN_DOCKHAND.${SERVER_DOMAINS[$i]}${SERVER_IPS[$i]}"
echo " $SUBDOMAIN_UPTIME.${SERVER_DOMAINS[$i]}${SERVER_IPS[$i]}"
echo ""
done
echo ""
echo "Setup complete! 🎉"