docker-compose-nas/update-setup.sh
2025-04-26 00:51:17 +08:00

656 lines
26 KiB
Bash

#!/bin/bash
# Combined update script for docker-compose-nas
# - Updates .env file from .env.example while preserving values
# - Updates Authelia configuration from example file
# - Configures services with correct paths and API keys
# Created: April 26, 2025
set -e
# Color definitions
RED='\033[0;31m'
GREEN='\033[0;32m'
YELLOW='\033[0;33m'
BLUE='\033[0;34m'
MAGENTA='\033[0;35m'
CYAN='\033[0;36m'
BOLD='\033[1m'
NC='\033[0m' # No Color
# Files
ENV_FILE=".env"
ENV_EXAMPLE=".env.example"
TIMESTAMP=$(date +"%Y%m%d-%H%M%S")
ENV_BACKUP=".env.${TIMESTAMP}.bak"
AUTHELIA_CONFIG="authelia/configuration.yml"
AUTHELIA_CONFIG_EXAMPLE="authelia/configuration.example.yml"
AUTHELIA_CONFIG_BACKUP="authelia/configuration.${TIMESTAMP}.bak"
# Print section header
print_header() {
echo -e "\n${CYAN}${BOLD}$1${NC}"
echo -e "${CYAN}$(printf '=%.0s' $(seq 1 ${#1}))${NC}"
}
# Check if a file exists
check_file() {
if [ ! -f "$1" ]; then
echo -e "${RED}Error: $1 doesn't exist${NC}"
return 1
fi
return 0
}
# Function to create a backup
create_backup() {
echo -e "${BLUE}Creating backup of $1 as $2...${NC}"
cp "$1" "$2"
}
##################################################
# PART 1: Update .env file from .env.example
##################################################
update_env_file() {
print_header "Environment File Update Tool"
# Check if files exist
if [ ! -f "$ENV_FILE" ]; then
echo -e "${RED}Error: $ENV_FILE doesn't exist${NC}"
echo -e "Creating a new $ENV_FILE from $ENV_EXAMPLE"
cp "$ENV_EXAMPLE" "$ENV_FILE"
echo -e "${GREEN}Done! Please review and fill in required values in $ENV_FILE${NC}"
return 0
fi
if ! check_file "$ENV_EXAMPLE"; then
return 1
fi
echo -e "${BLUE}This will update your $ENV_FILE based on the structure in $ENV_EXAMPLE${NC}"
echo -e "${BLUE}Your existing values will be preserved where possible${NC}"
echo -e "${BLUE}Backup will be created as: $ENV_BACKUP${NC}"
echo -e "${YELLOW}Continue? [y/N]:${NC}"
read -r answer
if [[ ! "$answer" =~ ^[Yy]$ ]]; then
echo -e "${RED}Environment update cancelled.${NC}"
return 0
fi
# Create backup of current .env
create_backup "$ENV_FILE" "$ENV_BACKUP"
# Store current env values
echo -e "${BLUE}Reading current environment values...${NC}"
declare -A current_values
declare -A current_keys_present
while IFS='=' read -r key value; do
# Skip comments and empty lines
if [[ ! "$key" =~ ^#.*$ ]] && [[ ! -z "$key" ]]; then
# Clean up any comments after the value
value=$(echo "$value" | sed 's/[[:space:]]*#.*$//')
# Trim leading/trailing whitespace
key=$(echo "$key" | xargs)
value=$(echo "$value" | xargs)
# Store in associative array if key is not empty
if [[ ! -z "$key" ]]; then
current_values["$key"]="$value"
# Track that this key existed in original file, regardless of value
current_keys_present["$key"]=1
fi
fi
done < "$ENV_FILE"
# Create new env file from example
echo -e "${BLUE}Creating new $ENV_FILE from $ENV_EXAMPLE...${NC}"
cp "$ENV_EXAMPLE" "$ENV_FILE.new"
# Track which keys from the current env have been used
declare -A used_keys
# Track new keys that need attention
new_keys=()
# Track keys with special warnings
special_keys=()
# Process the template and fill in values from current env
while IFS= read -r line; do
if [[ "$line" =~ ^([A-Za-z0-9_]+)=(.*)$ ]]; then
key="${BASH_REMATCH[1]}"
default_value="${BASH_REMATCH[2]}"
# Mark the key as used if it exists in the original file
if [[ -n "${current_keys_present[$key]}" ]]; then
used_keys["$key"]=1
# Replace the line with the current value if one exists
if [[ -n "${current_values[$key]}" ]]; then
sed -i "s|^$key=.*$|$key=${current_values[$key]}|" "$ENV_FILE.new"
fi
# If key doesn't exist in original file and has empty/placeholder value
elif [[ -z "$default_value" ]] || [[ "$default_value" == '""' ]] || [[ "$default_value" == "''" ]]; then
new_keys+=("$key")
# Special attention for Authelia keys
if [[ "$key" == AUTHELIA_*_SECRET* ]] || [[ "$key" == AUTHELIA_*_KEY* ]]; then
special_keys+=("$key")
fi
fi
fi
done < "$ENV_FILE.new"
# Create section for unused/deprecated keys at the bottom of the file
echo -e "\n\n# --- DEPRECATED OR UNUSED KEYS (Kept for Reference) ---" >> "$ENV_FILE.new"
echo -e "# Keys below were in your original .env but aren't in the current .env.example" >> "$ENV_FILE.new"
echo -e "# They may be deprecated or renamed. Review and remove if no longer needed\n" >> "$ENV_FILE.new"
unused_keys_count=0
for key in "${!current_values[@]}"; do
if [[ -z "${used_keys[$key]}" ]]; then
echo "$key=${current_values[$key]} # DEPRECATED/UNUSED - Review" >> "$ENV_FILE.new"
unused_keys_count=$((unused_keys_count + 1))
fi
done
# Replace the old file with the new one
mv "$ENV_FILE.new" "$ENV_FILE"
# Generate summary
echo -e "\n${GREEN}${BOLD}Environment Update Complete!${NC}"
echo -e "${BLUE}Summary:${NC}"
echo -e " - ${CYAN}Original config backed up to: $ENV_BACKUP${NC}"
echo -e " - ${CYAN}Updated .env structure to match .env.example${NC}"
echo -e " - ${CYAN}Preserved ${#used_keys[@]} existing values${NC}"
if [[ $unused_keys_count -gt 0 ]]; then
echo -e " - ${YELLOW}Found $unused_keys_count deprecated/unused keys${NC}"
echo -e " ${YELLOW}These have been moved to the bottom of the file with warnings${NC}"
fi
if [[ ${#new_keys[@]} -gt 0 ]]; then
echo -e "\n${YELLOW}${BOLD}NEW KEYS NEEDING ATTENTION:${NC}"
echo -e "${YELLOW}The following keys are new and may need values set:${NC}"
for key in "${new_keys[@]}"; do
echo -e " - ${MAGENTA}$key${NC}"
done
fi
if [[ ${#special_keys[@]} -gt 0 ]]; then
echo -e "\n${RED}${BOLD}IMPORTANT SECURITY KEYS:${NC}"
echo -e "${RED}The following keys require secure values:${NC}"
for key in "${special_keys[@]}"; do
echo -e " - ${MAGENTA}$key${NC}"
# Specific advice for Authelia keys
if [[ "$key" == AUTHELIA_*_SECRET* ]] || [[ "$key" == AUTHELIA_*_KEY* ]]; then
echo -e " ${CYAN}Generate with: ${GREEN}openssl rand -hex 32${NC}"
fi
done
fi
echo -e "\n${BLUE}Review your updated $ENV_FILE file and adjust any values as needed.${NC}"
}
##################################################
# PART 2: Update Authelia configuration
##################################################
update_authelia_config() {
print_header "Authelia Configuration Update Tool"
# Check if files exist
if ! check_file "$AUTHELIA_CONFIG_EXAMPLE"; then
echo -e "${RED}Error: Example configuration file doesn't exist${NC}"
return 1
fi
# If config file doesn't exist, create it from example
if [ ! -f "$AUTHELIA_CONFIG" ]; then
echo -e "${YELLOW}Authelia configuration file doesn't exist, creating from example...${NC}"
cp "$AUTHELIA_CONFIG_EXAMPLE" "$AUTHELIA_CONFIG"
echo -e "${GREEN}Created new Authelia configuration file.${NC}"
return 0
fi
echo -e "${BLUE}This will update your Authelia configuration based on the example file${NC}"
echo -e "${BLUE}Backup will be created as: $AUTHELIA_CONFIG_BACKUP${NC}"
echo -e "${YELLOW}Continue? [y/N]:${NC}"
read -r answer
if [[ ! "$answer" =~ ^[Yy]$ ]]; then
echo -e "${RED}Authelia config update cancelled.${NC}"
return 0
fi
# Create backup of current config
create_backup "$AUTHELIA_CONFIG" "$AUTHELIA_CONFIG_BACKUP"
# Copy the example file over the current one
cp "$AUTHELIA_CONFIG_EXAMPLE" "$AUTHELIA_CONFIG"
# Get the tailnet domain from .env for proper configuration
if [ -f "$ENV_FILE" ]; then
TAILNET_DOMAIN=$(grep -o "TAILSCALE_TAILNET_DOMAIN=.*" "$ENV_FILE" | cut -d'=' -f2 | tr -d '"' | tr -d "'")
TAILSCALE_HOSTNAME=$(grep -o "TAILSCALE_HOSTNAME=.*" "$ENV_FILE" | cut -d'=' -f2 | tr -d '"' | tr -d "'")
REDIS_PASSWORD=$(grep -o "AUTHELIA_REDIS_PASSWORD=.*" "$ENV_FILE" | cut -d'=' -f2 | tr -d '"' | tr -d "'")
if [ -n "$TAILNET_DOMAIN" ] && [ -n "$TAILSCALE_HOSTNAME" ]; then
# Use the full Tailnet domain (e.g., "example.ts.net") for cookies
# not just "ts.net" which is a public suffix and not allowed
# Replace domain placeholder with actual Tailnet domain
sed -i "s/domain: 'your-tailnet.ts.net'/domain: '$TAILNET_DOMAIN'/g" "$AUTHELIA_CONFIG"
# For access control rules, update both wildcards and direct domain
sed -i "s/domain: '\*.your-tailnet.ts.net'/domain: '\*.$TAILNET_DOMAIN'/g" "$AUTHELIA_CONFIG"
sed -i "s/domain: 'your-tailnet.ts.net'/domain: '$TAILNET_DOMAIN'/g" "$AUTHELIA_CONFIG"
# For URLs, use the full hostname
sed -i "s/https:\/\/tailscale-nas.your-tailnet.ts.net/https:\/\/$TAILSCALE_HOSTNAME.$TAILNET_DOMAIN/g" "$AUTHELIA_CONFIG"
# Ensure Redis password is set correctly
if [ -n "$REDIS_PASSWORD" ]; then
# Check if redis connection string exists in the config
if grep -q "redis:" "$AUTHELIA_CONFIG"; then
echo -e "${CYAN}Setting Redis password in Authelia configuration...${NC}"
# Make sure the Redis password in configuration matches the one in .env
sed -i "s/password: \${AUTHELIA_SESSION_REDIS_PASSWORD}/password: $REDIS_PASSWORD/g" "$AUTHELIA_CONFIG"
fi
fi
echo -e "${GREEN}Configured Authelia with your Tailscale domain:${NC}"
echo -e "${CYAN} - Cookie domain: ${GREEN}$TAILNET_DOMAIN${NC}"
echo -e "${CYAN} - Access control for: ${GREEN}*.$TAILNET_DOMAIN and $TAILNET_DOMAIN${NC}"
echo -e "${CYAN} - Authelia URL: ${GREEN}https://$TAILSCALE_HOSTNAME.$TAILNET_DOMAIN${NC}"
echo -e "${CYAN} - Redis password: ${GREEN}Configured${NC}"
else
echo -e "${YELLOW}Warning: Could not find both TAILSCALE_HOSTNAME and TAILSCALE_TAILNET_DOMAIN in .env${NC}"
echo -e "${YELLOW}You may need to manually edit $AUTHELIA_CONFIG to set your domains correctly${NC}"
fi
fi
echo -e "${GREEN}${BOLD}Authelia Configuration Update Complete!${NC}"
echo -e "${BLUE}${BOLD}Note:${NC} Original config backed up to: $AUTHELIA_CONFIG_BACKUP"
}
##################################################
# PART 3: Update Service Configurations
##################################################
update_arr_config() {
local container=$1
local path=$2
echo -e "${BLUE}Configuring $container URL base and extracting API key...${NC}"
# Check if config file exists
config_file="${CONFIG_ROOT:-.}/$container/config.xml"
timeout=10
count=0
while [ ! -f "$config_file" ] && [ $count -lt $timeout ]; do
echo -e "${YELLOW}Waiting for $container config file to be available... ($(($timeout-$count)) seconds remaining)${NC}"
sleep 1
count=$((count+1))
done
if [ ! -f "$config_file" ]; then
echo -e "${RED}Error: Config file for $container not found after $timeout seconds${NC}"
echo -e "${YELLOW}Is $container configured properly? Check the container logs${NC}"
return 1
fi
# Update URL base
if ! grep -q "<UrlBase>/$path</UrlBase>" "$config_file"; then
echo -e "${BLUE}Setting URL base to /$path${NC}"
sed -i.bak "s|<UrlBase>.*</UrlBase>|<UrlBase>/$path</UrlBase>|" "$config_file" 2>/dev/null || sed -i.bak "s|<UrlBase />|<UrlBase>/$path</UrlBase>|" "$config_file" 2>/dev/null
if [ $? -ne 0 ]; then
echo -e "${RED}Failed to update URL base in $config_file${NC}"
return 1
fi
rm -f "${config_file}.bak"
else
echo -e "${GREEN}URL base already set to /$path${NC}"
fi
# Extract API key
api_key=$(sed -n 's/.*<ApiKey>\(.*\)<\/ApiKey>.*/\1/p' "$config_file")
if [ -z "$api_key" ]; then
echo -e "${YELLOW}Could not find API key in $container configuration${NC}"
else
CONTAINER_NAME_UPPER=$(echo "$container" | tr '[:lower:]' '[:upper:]')
current_key=$(grep "^${CONTAINER_NAME_UPPER}_API_KEY=" .env | cut -d'=' -f2)
if [ "$current_key" != "$api_key" ]; then
echo -e "${BLUE}Updating ${CONTAINER_NAME_UPPER}_API_KEY in .env file${NC}"
sed -i.bak "s|^${CONTAINER_NAME_UPPER}_API_KEY=.*|${CONTAINER_NAME_UPPER}_API_KEY=$api_key|" .env
rm -f .env.bak
else
echo -e "${GREEN}${CONTAINER_NAME_UPPER}_API_KEY already up to date in .env file${NC}"
fi
fi
echo -e "${GREEN}Restarting $container to apply changes...${NC}"
if ! docker compose restart "$container"; then
echo -e "${RED}Failed to restart $container${NC}"
return 1
fi
echo -e "${GREEN}Successfully configured $container${NC}"
return 0
}
update_qbittorrent_config() {
local container=$1
echo -e "${BLUE}Configuring $container WebUI password...${NC}"
# Stop the container to ensure we can modify the config
echo -e "${BLUE}Stopping $container to update configuration...${NC}"
if ! docker compose stop "$container"; then
echo -e "${RED}Failed to stop $container${NC}"
return 1
fi
# Check if config file exists
config_file="${CONFIG_ROOT:-.}/$container/qBittorrent/qBittorrent.conf"
timeout=10
count=0
while [ ! -f "$config_file" ] && [ $count -lt $timeout ]; do
echo -e "${YELLOW}Waiting for $container config file to be available... ($(($timeout-$count)) seconds remaining)${NC}"
sleep 1
count=$((count+1))
done
if [ ! -f "$config_file" ]; then
echo -e "${RED}Error: Config file for $container not found after $timeout seconds${NC}"
echo -e "${YELLOW}Is $container configured properly? Check the container logs${NC}"
# Restart the container anyway
docker compose start "$container"
return 1
fi
# Check if password is already set
if grep -q "WebUI\\\\Password_PBKDF2=" "$config_file"; then
echo -e "${GREEN}Password already configured in $container${NC}"
else
echo -e "${BLUE}Setting default password for $container WebUI${NC}"
sed -i.bak '/WebUI\\\\ServerDomains=*/a WebUI\\\\Password_PBKDF2="@ByteArray(ARQ77eY1NUZaQsuDHbIMCA==:0WMRkYTUWVT9wVvdDtHAjU9b3b7uB8NR1Gur2hmQCvCDpm39Q+PsJRJPaCU51dEiz+dTzh8qbPsL8WkFljQYFQ==)"' "$config_file"
if [ $? -ne 0 ]; then
echo -e "${RED}Failed to update password in $config_file${NC}"
docker compose start "$container"
return 1
fi
rm -f "${config_file}.bak"
echo -e "${GREEN}Default password set. Username: admin / Password: adminadmin${NC}"
echo -e "${YELLOW}You should change this password in the WebUI settings${NC}"
fi
echo -e "${GREEN}Starting $container with updated configuration...${NC}"
if ! docker compose start "$container"; then
echo -e "${RED}Failed to start $container${NC}"
return 1
fi
echo -e "${GREEN}Successfully configured $container${NC}"
return 0
}
update_bazarr_config() {
local container=$1
echo -e "${BLUE}Configuring $container URL base and service connections...${NC}"
# Check if config file exists
config_file="${CONFIG_ROOT:-.}/$container/config/config/config.yaml"
timeout=15
count=0
while [ ! -f "$config_file" ] && [ $count -lt $timeout ]; do
echo -e "${YELLOW}Waiting for $container config file to be available... ($(($timeout-$count)) seconds remaining)${NC}"
sleep 1
count=$((count+1))
done
if [ ! -f "$config_file" ]; then
echo -e "${RED}Error: Config file for $container not found after $timeout seconds${NC}"
echo -e "${YELLOW}Is $container configured properly? Check the container logs${NC}"
return 1
fi
# Update URL base
if grep -q "base_url: '/$container'" "$config_file"; then
echo -e "${GREEN}URL base already set to /$container${NC}"
else
echo -e "${BLUE}Setting URL base to /$container${NC}"
sed -i.bak "s|base_url: .*|base_url: '/$container'|" "$config_file"
if [ $? -ne 0 ]; then
echo -e "${RED}Failed to update URL base in $config_file${NC}"
return 1
fi
rm -f "${config_file}.bak"
fi
# Configure Radarr integration
updates_needed=false
if grep -q "use_radarr: false" "$config_file"; then
echo -e "${BLUE}Enabling Radarr integration${NC}"
sed -i.bak "s/use_radarr: false/use_radarr: true/" "$config_file"
rm -f "${config_file}.bak"
updates_needed=true
else
echo -e "${GREEN}Radarr integration already enabled${NC}"
fi
# Configure Sonarr integration
if grep -q "use_sonarr: false" "$config_file"; then
echo -e "${BLUE}Enabling Sonarr integration${NC}"
sed -i.bak "s/use_sonarr: false/use_sonarr: true/" "$config_file"
rm -f "${config_file}.bak"
updates_needed=true
else
echo -e "${GREEN}Sonarr integration already enabled${NC}"
fi
# Get Sonarr API key if needed
sonarr_config="${CONFIG_ROOT:-.}/sonarr/config.xml"
if [ -f "$sonarr_config" ]; then
sonarr_api_key=$(sed -n 's/.*<ApiKey>\(.*\)<\/ApiKey>.*/\1/p' "$sonarr_config")
if [ -n "$sonarr_api_key" ]; then
echo -e "${BLUE}Setting Sonarr API key and URL in Bazarr config${NC}"
sed -i.bak "/sonarr:/,/^radarr:/ { s/apikey: .*/apikey: $sonarr_api_key/; s|base_url: .*|base_url: /sonarr|; s/ip: .*/ip: sonarr/ }" "$config_file"
rm -f "${config_file}.bak"
updates_needed=true
else
echo -e "${YELLOW}Could not find Sonarr API key${NC}"
fi
else
echo -e "${YELLOW}Sonarr config not found, skipping Sonarr API configuration${NC}"
fi
# Get Radarr API key if needed
radarr_config="${CONFIG_ROOT:-.}/radarr/config.xml"
if [ -f "$radarr_config" ]; then
radarr_api_key=$(sed -n 's/.*<ApiKey>\(.*\)<\/ApiKey>.*/\1/p' "$radarr_config")
if [ -n "$radarr_api_key" ]; then
echo -e "${BLUE}Setting Radarr API key and URL in Bazarr config${NC}"
sed -i.bak "/radarr:/,/^sonarr:/ { s/apikey: .*/apikey: $radarr_api_key/; s|base_url: .*|base_url: /radarr|; s/ip: .*/ip: radarr/ }" "$config_file"
rm -f "${config_file}.bak"
updates_needed=true
else
echo -e "${YELLOW}Could not find Radarr API key${NC}"
fi
else
echo -e "${YELLOW}Radarr config not found, skipping Radarr API configuration${NC}"
fi
# Extract Bazarr API key for .env
bazarr_api_key=$(sed -n 's/.*apikey: \(.*\)*/\1/p' "$config_file" | head -n 1)
if [ -n "$bazarr_api_key" ]; then
current_key=$(grep "^BAZARR_API_KEY=" .env | cut -d'=' -f2)
if [ "$current_key" != "$bazarr_api_key" ]; then
echo -e "${BLUE}Updating BAZARR_API_KEY in .env file${NC}"
sed -i.bak "s|^BAZARR_API_KEY=.*|BAZARR_API_KEY=$bazarr_api_key|" .env
rm -f .env.bak
else
echo -e "${GREEN}BAZARR_API_KEY already up to date in .env file${NC}"
fi
else
echo -e "${YELLOW}Could not find Bazarr API key${NC}"
fi
if [ "$updates_needed" = true ]; then
echo -e "${GREEN}Restarting $container to apply changes...${NC}"
if ! docker compose restart "$container"; then
echo -e "${RED}Failed to restart $container${NC}"
return 1
fi
else
echo -e "${GREEN}No configuration changes needed for $container${NC}"
fi
echo -e "${GREEN}Successfully configured $container${NC}"
return 0
}
update_service_configs() {
print_header "Service Configuration Update Tool"
echo -e "${BLUE}This will update service configurations for running containers${NC}"
echo -e "${BLUE}It will set proper URL bases and extract API keys${NC}"
echo -e "${YELLOW}Continue? [y/N]:${NC}"
read -r answer
if [[ ! "$answer" =~ ^[Yy]$ ]]; then
echo -e "${RED}Service configuration update cancelled.${NC}"
return 0
fi
# Check if Docker is running
if ! docker ps > /dev/null 2>&1; then
echo -e "${RED}Error: Docker is not running or you don't have permission to use it.${NC}"
echo -e "${YELLOW}Make sure Docker is running and you have proper permissions.${NC}"
return 1
fi
# Keep track of what we updated
updated_containers=()
not_running_containers=()
skipped_containers=()
echo -e "${BLUE}Checking for containers to update...${NC}"
# Define the list of containers we can update
declare -a configurable_containers=("radarr" "sonarr" "lidarr" "prowlarr" "bazarr" "qbittorrent")
# First check which containers we should be able to update
for container in "${configurable_containers[@]}"; do
if ! docker ps --format '{{.Names}}' | grep -q "^${container}$"; then
not_running_containers+=("$container")
fi
done
# Now update the running containers
for container in $(docker ps --format '{{.Names}}'); do
if [[ "$container" =~ ^(radarr|sonarr|lidarr|prowlarr)$ ]]; then
echo -e "\n${CYAN}Updating ${BOLD}$container${NC} configuration..."
if update_arr_config "$container" "$container"; then
updated_containers+=("$container")
else
skipped_containers+=("$container (error during update)")
fi
elif [[ "$container" =~ ^(bazarr)$ ]]; then
echo -e "\n${CYAN}Updating ${BOLD}$container${NC} configuration..."
if update_bazarr_config "$container"; then
updated_containers+=("$container")
else
skipped_containers+=("$container (error during update)")
fi
elif [[ "$container" =~ ^(qbittorrent)$ ]]; then
echo -e "\n${CYAN}Updating ${BOLD}$container${NC} configuration..."
if update_qbittorrent_config "$container"; then
updated_containers+=("$container")
else
skipped_containers+=("$container (error during update)")
fi
fi
done
# Print summary
echo -e "\n${GREEN}${BOLD}Service Configuration Update Complete!${NC}"
echo -e "${BLUE}Summary:${NC}"
if [[ ${#updated_containers[@]} -gt 0 ]]; then
echo -e " ${GREEN}Successfully updated configurations for:${NC}"
for container in "${updated_containers[@]}"; do
echo -e " - ${CYAN}$container${NC}"
done
else
echo -e " ${YELLOW}No container configurations were updated${NC}"
fi
if [[ ${#not_running_containers[@]} -gt 0 ]]; then
echo -e " ${YELLOW}The following containers were not running (skipped):${NC}"
for container in "${not_running_containers[@]}"; do
echo -e " - ${YELLOW}$container${NC}"
done
echo -e " ${BLUE}Start these containers and run the script again to configure them${NC}"
fi
if [[ ${#skipped_containers[@]} -gt 0 ]]; then
echo -e " ${RED}Failed to update configurations for:${NC}"
for container in "${skipped_containers[@]}"; do
echo -e " - ${RED}$container${NC}"
done
fi
# If we've extracted any API keys, show them
if grep -q "_API_KEY=" .env; then
echo -e "\n${BLUE}${BOLD}API Keys:${NC}"
echo -e "${BLUE}The following API keys were extracted and updated in your .env file:${NC}"
grep "_API_KEY=" .env | sort | while read -r line; do
key=$(echo "$line" | cut -d'=' -f1)
echo -e " - ${CYAN}$key${NC}"
done
fi
}
##################################################
# MAIN SCRIPT
##################################################
# Display main menu
print_header "Docker Compose NAS - Setup Tool"
echo -e "${BLUE}This tool will help you configure your Docker Compose NAS setup${NC}"
echo -e "${BLUE}Choose one or more options to run:${NC}"
echo -e " ${CYAN}1. ${NC}Update .env file from .env.example"
echo -e " ${CYAN}2. ${NC}Update Authelia configuration"
echo -e " ${CYAN}3. ${NC}Update service configurations"
echo -e " ${CYAN}4. ${NC}Run ALL updates"
echo -e " ${CYAN}q. ${NC}Quit"
echo
CHOICE="0"
while [[ "$CHOICE" != "q" ]]; do
echo -e "${YELLOW}Enter your choice [1-4 or q to quit]: ${NC}"
read -r CHOICE
case "$CHOICE" in
1) update_env_file ;;
2) update_authelia_config ;;
3) update_service_configs ;;
4)
update_env_file
update_authelia_config
update_service_configs
CHOICE="q" # Exit after running all
;;
q|Q)
echo -e "${GREEN}Exiting setup tool.${NC}"
exit 0
;;
*) echo -e "${RED}Invalid choice. Please try again.${NC}" ;;
esac
done
echo -e "\n${GREEN}${BOLD}All updates completed!${NC}"
echo -e "${BLUE}Be sure to restart any services that were updated:${NC}"
echo -e " ${CYAN}docker compose restart${NC}"
echo -e "\n${BLUE}If you updated the Authelia configuration, restart Authelia:${NC}"
echo -e " ${CYAN}docker compose restart authelia${NC}"