small fix, don't worry about it

This commit is contained in:
Tomas Dvorak
2026-04-10 12:02:36 +02:00
parent 08bd0c6e5c
commit 08cb5754f3
638 changed files with 57332 additions and 34706 deletions
+600
View File
@@ -0,0 +1,600 @@
#!/bin/bash
# One-Click Docker Template Auto-Deployment
# Fully automated deployment with no user interaction required
set -e
# Colors for output
RED='\033[0;31m'
GREEN='\033[0;32m'
YELLOW='\033[1;33m'
BLUE='\033[0;34m'
PURPLE='\033[0;35m'
CYAN='\033[0;36m'
NC='\033[0m' # No Color
# Configuration
TEMPLATE_DIR="$(dirname "$0")/../templates"
DEPLOYMENT_BASE_DIR="$(dirname "$0")/../deployments"
LOG_FILE="/tmp/docker-auto-deploy.log"
# Auto-configuration
AUTO_GENERATE_SECRETS=true
AUTO_CREATE_DIRECTORIES=true
AUTO_PULL_IMAGES=true
AUTO_START_SERVICES=true
AUTO_OPEN_BROWSER=false
# Template configurations with auto-generated defaults
declare -A TEMPLATE_CONFIGS=(
["umami"]="port:3000,database:postgres,secrets:APP_SECRET"
["plex"]="port:32400,database:none,secrets:none"
["immich"]="port:2283,database:postgres,secrets:DATABASE_PASSWORD"
["n8n"]="port:5678,database:postgres,secrets:N8N_ENCRYPTION_KEY"
["supabase"]="port:8000,database:postgres,secrets:JWT_SECRET"
["home-assistant"]="port:8123,database:postgres,secrets:none"
["uptime-kuma"]="port:3001,database:none,secrets:none"
["grafana"]="port:3000,database:postgres,secrets:GF_SECURITY_ADMIN_PASSWORD"
["traefik"]="port:80,database:none,secrets:none"
["memos"]="port:5230,database:sqlite,secrets:none"
["meilisearch"]="port:7700,database:none,secrets:MEILI_MASTER_KEY"
["vaultwarden"]="port:8080,database:postgres,secrets:ADMIN_TOKEN"
["pihole"]="port:80,database:none,secrets:FTLCONF_webserver_api_password"
["appwrite"]="port:80,database:postgres,secrets:_APP_OPENSSL_KEY_V1"
["gitea"]="port:3000,database:postgres,secrets:SECRET_KEY"
["mastodon"]="port:3000,database:postgres,secrets:SECRET_KEY_BASE"
["jellyfin"]="port:8096,database:none,secrets:none"
["nextcloud"]="port:8080,database:postgres,secrets:NEXTCLOUD_ADMIN_PASSWORD"
["glance"]="port:8080,database:none,secrets:none"
["cloudreve"]="port:5212,database:postgres,secrets:CR_CONF_Database_Password"
)
print_header() {
echo -e "${PURPLE}========================================${NC}"
echo -e "${PURPLE}$1${NC}"
echo -e "${PURPLE}========================================${NC}"
}
print_success() {
echo -e "${GREEN}$1${NC}"
}
print_error() {
echo -e "${RED}$1${NC}"
}
print_warning() {
echo -e "${YELLOW}⚠️ $1${NC}"
}
print_info() {
echo -e "${BLUE}$1${NC}"
}
print_step() {
echo -e "${CYAN}🔄 $1${NC}"
}
log_message() {
echo "[$(date '+%Y-%m-%d %H:%M:%S')] $1" >> "$LOG_FILE"
}
check_dependencies() {
print_step "Checking dependencies..."
log_message "Starting dependency check"
# Check Docker
if ! command -v docker &> /dev/null; then
print_error "Docker is not installed"
print_info "Installing Docker automatically..."
curl -fsSL https://get.docker.com -o get-docker.sh
sudo sh get-docker.sh
sudo usermod -aG docker $USER
print_success "Docker installed"
else
print_success "Docker is installed"
fi
# Check Docker Compose
if ! command -v docker-compose &> /dev/null && ! docker compose version &> /dev/null; then
print_error "Docker Compose is not installed"
print_info "Installing Docker Compose automatically..."
sudo curl -L "https://github.com/docker/compose/releases/latest/download/docker-compose-$(uname -s)-$(uname -m)" -o /usr/local/bin/docker-compose
sudo chmod +x /usr/local/bin/docker-compose
print_success "Docker Compose installed"
else
print_success "Docker Compose is installed"
fi
log_message "Dependency check completed"
}
generate_secret() {
local length=${1:-32}
openssl rand -base64 $length | tr -d "=+/" | cut -c1-$length
}
generate_password() {
local length=${1:-16}
openssl rand -base64 $length | tr -d "=+/" | cut -c1-$length
}
auto_generate_secrets() {
local template="$1"
local env_file="$2"
print_step "Auto-generating secrets for $template..."
local config="${TEMPLATE_CONFIGS[$template]}"
local secrets=$(echo "$config" | cut -d',' -f3 | cut -d':' -f2)
if [[ "$secrets" == "none" ]]; then
return
fi
# Read existing .env file
local temp_env=$(mktemp)
cp "$env_file" "$temp_env"
# Generate secrets for each required variable
case "$template" in
"umami")
sed -i "s/APP_SECRET=change_me/APP_SECRET=$(generate_secret)/g" "$temp_env"
;;
"immich")
sed -i "s/DATABASE_PASSWORD=change_me/DATABASE_PASSWORD=$(generate_password)/g" "$temp_env"
;;
"n8n")
sed -i "s/N8N_ENCRYPTION_KEY=change_me/N8N_ENCRYPTION_KEY=$(generate_secret)/g" "$temp_env"
;;
"supabase")
sed -i "s/JWT_SECRET=change_me/JWT_SECRET=$(generate_secret)/g" "$temp_env"
;;
"grafana")
sed -i "s/GF_SECURITY_ADMIN_PASSWORD=change_me/GF_SECURITY_ADMIN_PASSWORD=$(generate_password)/g" "$temp_env"
;;
"vaultwarden")
sed -i "s/ADMIN_TOKEN=change_me/ADMIN_TOKEN=$(generate_secret)/g" "$temp_env"
;;
"pihole")
sed -i "s/FTLCONF_webserver_api_password=change_me/FTLCONF_webserver_api_password=$(generate_password)/g" "$temp_env"
;;
"appwrite")
sed -i "s/_APP_OPENSSL_KEY_V1=change_me/_APP_OPENSSL_KEY_V1=$(generate_secret)/g" "$temp_env"
;;
"gitea")
sed -i "s/SECRET_KEY=change_me/SECRET_KEY=$(generate_secret)/g" "$temp_env"
;;
"mastodon")
sed -i "s/SECRET_KEY_BASE=change_me/SECRET_KEY_BASE=$(generate_secret)/g" "$temp_env"
sed -i "s/OTP_SECRET=change_me/OTP_SECRET=$(generate_secret)/g" "$temp_env"
sed -i "s/VAPID_PRIVATE_KEY=change_me/VAPID_PRIVATE_KEY=$(openssl ecparam -name prime256v1 -genkey -noout | openssl ec -outform DER | tail -c +8 | head -c 32 | base64)/g" "$temp_env"
sed -i "s/VAPID_PUBLIC_KEY=change_me/VAPID_PUBLIC_KEY=$(openssl ecparam -name prime256v1 -genkey -noout | openssl ec -outform DER -pubout -outform DER | tail -c +8 | head -c 32 | base64)/g" "$temp_env"
;;
"nextcloud")
sed -i "s/NEXTCLOUD_ADMIN_PASSWORD=change_me/NEXTCLOUD_ADMIN_PASSWORD=$(generate_password)/g" "$temp_env"
;;
"cloudreve")
sed -i "s/CR_CONF_Database_Password=change_me/CR_CONF_Database_Password=$(generate_password)/g" "$temp_env"
;;
esac
mv "$temp_env" "$env_file"
print_success "Secrets auto-generated"
log_message "Secrets generated for $template"
}
auto_create_directories() {
local template="$1"
local project_dir="$2"
print_step "Auto-creating directories for $template..."
# Create common directories
local dirs=("data" "logs" "config" "uploads")
case "$template" in
"plex")
dirs+=("movies" "tvshows" "music" "photos")
;;
"immich")
dirs+=("uploads" "library")
;;
"jellyfin")
dirs+=("media" "movies" "tvshows" "music" "photos")
;;
"nextcloud")
dirs+=("nextcloud-data" "nextcloud-config")
;;
"pihole")
dirs+=("pihole-config" "pihole-dnsmasq" "pihole-logs")
;;
"vaultwarden")
dirs+=("vaultwarden-data")
;;
"gitea")
dirs+=("gitea-data" "gitea-db")
;;
"mastodon")
dirs+=("mastodon-data" "postgres-data" "redis-data")
;;
esac
for dir in "${dirs[@]}"; do
mkdir -p "$project_dir/$dir"
print_success "Created directory: $dir"
done
log_message "Directories created for $template"
}
extract_docker_compose() {
local template_file="$1"
local project_dir="$2"
print_step "Extracting docker-compose.yml..."
# Extract docker-compose.yml from markdown file
sed -n '/```yaml/,/```/p' "$template_file" | sed '1d;$d' > "$project_dir/docker-compose.yml"
if [[ ! -s "$project_dir/docker-compose.yml" ]]; then
print_error "Failed to extract docker-compose.yml"
exit 1
fi
# Auto-fix common issues
fix_docker_compose "$project_dir/docker-compose.yml" "$template"
print_success "docker-compose.yml extracted and optimized"
log_message "docker-compose.yml extracted for $template"
}
fix_docker_compose() {
local compose_file="$1"
local template="$2"
# Fix volume paths to use auto-created directories
case "$template" in
"plex")
sed -i 's|/path/to/media|./media|g' "$compose_file"
sed -i 's|/path/to/tvseries|./tvshows|g' "$compose_file"
sed -i 's|/path/to/movies|./movies|g' "$compose_file"
;;
"immich")
sed -i 's|/path/to/local-storage|./uploads|g' "$compose_file"
;;
"jellyfin")
sed -i 's|/path/to/media|./media|g' "$compose_file"
;;
"nextcloud")
sed -i 's|/path/to/nextcloud-data|./nextcloud-data|g' "$compose_file"
;;
"vaultwarden")
sed -i 's|vaultwarden-data|./data|g' "$compose_file"
;;
esac
# Fix port conflicts by auto-assigning available ports
auto_assign_ports "$compose_file" "$template"
}
auto_assign_ports() {
local compose_file="$1"
local template="$2"
local config="${TEMPLATE_CONFIGS[$template]}"
local default_port=$(echo "$config" | cut -d',' -f1 | cut -d':' -f2)
# Check if default port is available
if ! netstat -tuln 2>/dev/null | grep -q ":$default_port "; then
print_info "Port $default_port is available"
return
fi
# Find next available port
local new_port=$default_port
while netstat -tuln 2>/dev/null | grep -q ":$new_port "; do
new_port=$((new_port + 1))
done
if [[ $new_port -ne $default_port ]]; then
print_warning "Port $default_port is busy, using $new_port"
sed -i "s/- \"$default_port:/- \"$new_port:/g" "$compose_file"
sed -i "s/- $default_port:/- $new_port:/g" "$compose_file"
log_message "Port changed from $default_port to $new_port for $template"
fi
}
create_env_file() {
local template="$1"
local project_dir="$2"
local env_file="$project_dir/.env"
print_step "Creating .env file..."
# Extract environment variables from template
local env_vars=$(sed -n '/## Environment Variables/,/##/p' "$TEMPLATE_DIR/$template.md" | grep -E '^- `[^`]+`')
if [[ -n "$env_vars" ]]; then
echo "# Auto-generated environment variables for $template" > "$env_file"
echo "# Generated on $(date)" >> "$env_file"
echo "" >> "$env_file"
echo "$env_vars" | while read -r line; do
if [[ $line =~ -\s*\`([^`]+)\`.* ]]; then
local var_name="${BASH_REMATCH[1]}"
echo "$var_name=change_me" >> "$env_file"
fi
done
# Auto-generate secrets
if [[ "$AUTO_GENERATE_SECRETS" == "true" ]]; then
auto_generate_secrets "$template" "$env_file"
fi
print_success ".env file created with $(wc -l < "$env_file") variables"
else
# Create minimal .env file
echo "# Auto-generated environment variables for $template" > "$env_file"
echo "# Generated on $(date)" >> "$env_file"
echo "" >> "$env_file"
echo "# No environment variables required" >> "$env_file"
print_success ".env file created (no variables required)"
fi
log_message ".env file created for $template"
}
auto_deploy() {
local template="$1"
local project_dir="$2"
print_step "Auto-deploying $template..."
cd "$project_dir"
# Pull images
if [[ "$AUTO_PULL_IMAGES" == "true" ]]; then
print_info "Pulling Docker images..."
docker-compose pull > /dev/null 2>&1
print_success "Images pulled"
fi
# Start services
if [[ "$AUTO_START_SERVICES" == "true" ]]; then
print_info "Starting services..."
docker-compose up -d > /dev/null 2>&1
# Wait for services to be ready
print_info "Waiting for services to start..."
sleep 10
# Check service status
if docker-compose ps | grep -q "Up"; then
print_success "Services started successfully"
else
print_error "Some services failed to start"
docker-compose ps
return 1
fi
fi
log_message "$template deployed successfully"
}
show_access_info() {
local template="$1"
local project_dir="$2"
print_header "🎉 Deployment Complete!"
cd "$project_dir"
# Extract ports from docker-compose.yml
local ports=$(grep -E "^\s*-\s*\"[0-9]+:[0-9]+\"" "$project_dir/docker-compose.yml")
if [[ -n "$ports" ]]; then
print_success "Access URLs:"
echo "$ports" | while read -r line; do
if [[ $line =~ -\s*\"([0-9]+):([0-9]+)\" ]]; then
local host_port="${BASH_REMATCH[1]}"
local container_port="${BASH_REMATCH[2]}"
echo " 🌐 http://localhost:$host_port (port: $container_port)"
fi
done
echo ""
fi
print_success "Management Commands:"
echo " 📋 View logs: docker-compose logs -f"
echo " 🛑 Stop services: docker-compose down"
echo " 🔄 Restart: docker-compose restart"
echo " 📊 Status: docker-compose ps"
echo " 🗑️ Cleanup: docker-compose down -v"
echo ""
print_info "Deployment directory: $project_dir"
print_info "Log file: $LOG_FILE"
# Auto-open browser if enabled
if [[ "$AUTO_OPEN_BROWSER" == "true" ]]; then
local first_port=$(echo "$ports" | head -1 | grep -o -E '[0-9]+' | head -1)
if [[ -n "$first_port" ]]; then
print_info "Opening browser..."
xdg-open "http://localhost:$first_port" 2>/dev/null || open "http://localhost:$first_port" 2>/dev/null || echo "Could not open browser automatically"
fi
fi
}
auto_deploy_template() {
local template="$1"
local template_file="$TEMPLATE_DIR/$template.md"
local project_dir="$DEPLOYMENT_BASE_DIR/$template"
print_header "🚀 Auto-Deploying $template"
# Validate template
if [[ ! -f "$template_file" ]]; then
print_error "Template not found: $template"
print_info "Available templates:"
ls -1 "$TEMPLATE_DIR" | sed 's/.md$//' | head -10
exit 1
fi
# Create deployment directory
mkdir -p "$DEPLOYMENT_BASE_DIR"
if [[ -d "$project_dir" ]]; then
print_warning "Deployment directory exists: $project_dir"
print_info "Cleaning up previous deployment..."
cd "$project_dir"
docker-compose down -v 2>/dev/null || true
cd ..
rm -rf "$project_dir"
fi
mkdir -p "$project_dir"
print_success "Created deployment directory: $project_dir"
# Setup deployment
extract_docker_compose "$template_file" "$project_dir"
create_env_file "$template" "$project_dir"
if [[ "$AUTO_CREATE_DIRECTORIES" == "true" ]]; then
auto_create_directories "$template" "$project_dir"
fi
# Deploy
if auto_deploy "$template" "$project_dir"; then
show_access_info "$template" "$project_dir"
print_success "🎉 $template deployed successfully!"
else
print_error "$template deployment failed"
exit 1
fi
}
deploy_all_templates() {
print_header "🚀 Auto-Deploying All Templates"
local failed=()
local success=0
for template in "${!TEMPLATE_CONFIGS[@]}"; do
echo ""
print_step "Deploying $template..."
if auto_deploy_template "$template"; then
((success++))
else
failed+=("$template")
fi
done
echo ""
print_header "📊 Deployment Summary"
print_success "Successfully deployed: $success templates"
if [[ ${#failed[@]} -gt 0 ]]; then
print_error "Failed deployments: ${#failed[@]} templates"
print_info "Failed templates: ${failed[*]}"
fi
}
show_help() {
echo "🚀 Docker Template Auto-Deployment"
echo ""
echo "Usage: $0 [OPTIONS] [TEMPLATE]"
echo ""
echo "Options:"
echo " -h, --help Show this help message"
echo " -l, --list List available templates"
echo " -a, --all Deploy all templates"
echo " --no-secrets Don't auto-generate secrets"
echo " --no-dirs Don't auto-create directories"
echo " --no-pull Don't auto-pull images"
echo " --no-start Don't auto-start services"
echo " --open-browser Auto-open browser after deployment"
echo ""
echo "Templates:"
for template in "${!TEMPLATE_CONFIGS[@]}"; do
echo "$template"
done
echo ""
echo "Examples:"
echo " $0 # Interactive mode"
echo " $0 umami # Auto-deploy umami"
echo " $0 --all # Auto-deploy all templates"
echo " $0 --open-browser umami # Deploy and open browser"
}
# Main execution
main() {
# Create deployment directory
mkdir -p "$DEPLOYMENT_BASE_DIR"
# Parse command line arguments
while [[ $# -gt 0 ]]; do
case $1 in
-h|--help)
show_help
exit 0
;;
-l|--list)
print_header "Available Templates"
for template in "${!TEMPLATE_CONFIGS[@]}"; do
echo "$template - ${TEMPLATE_CONFIGS[$template]}"
done
exit 0
;;
-a|--all)
check_dependencies
deploy_all_templates
exit 0
;;
--no-secrets)
AUTO_GENERATE_SECRETS=false
shift
;;
--no-dirs)
AUTO_CREATE_DIRECTORIES=false
shift
;;
--no-pull)
AUTO_PULL_IMAGES=false
shift
;;
--no-start)
AUTO_START_SERVICES=false
shift
;;
--open-browser)
AUTO_OPEN_BROWSER=true
shift
;;
-*)
print_error "Unknown option: $1"
show_help
exit 1
;;
*)
SELECTED_TEMPLATE="$1"
shift
;;
esac
done
# Check dependencies
check_dependencies
# Execute deployment
if [[ -n "$SELECTED_TEMPLATE" ]]; then
auto_deploy_template "$SELECTED_TEMPLATE"
else
# Interactive mode - deploy a simple template by default
print_info "No template specified, deploying Glance (simple dashboard)..."
auto_deploy_template "glance"
fi
}
# Run main function
main "$@"
+76
View File
@@ -0,0 +1,76 @@
#!/bin/bash
# Quick Test Script - Try out the setup system
# This script demonstrates the auto-setup with a simple template
set -e
echo "🚀 Docker Template Auto-Setup Demo"
echo "=================================="
echo ""
# Check if we're in the right directory
if [[ ! -f "scripts/setup-template.sh" ]]; then
echo "❌ Error: Please run this script from the project root directory"
echo " Current directory: $(pwd)"
echo " Expected: scripts/setup-template.sh"
exit 1
fi
echo "✅ Found setup script"
echo ""
# Make script executable
chmod +x scripts/setup-template.sh
echo "📋 Available Templates:"
./scripts/setup-template.sh --list
echo ""
echo "🎯 Let's try setting up a simple template (Glance Dashboard)..."
echo ""
# Create a test deployment
echo "Setting up Glance template..."
./scripts/setup-template.sh --setup glance
echo ""
echo "📁 Created files:"
ls -la glance-deployment/
echo ""
echo "📄 Generated docker-compose.yml:"
echo "---"
head -20 glance-deployment/docker-compose.yml
echo "---"
echo ""
echo "🔧 Generated .env file:"
if [[ -f "glance-deployment/.env" ]]; then
echo "---"
cat glance-deployment/.env
echo "---"
else
echo "No .env file generated (Glance doesn't require environment variables)"
fi
echo ""
echo "✅ Setup completed successfully!"
echo ""
echo "🎯 Next steps:"
echo "1. cd glance-deployment"
echo "2. Review the configuration"
echo "3. Run: docker-compose up -d"
echo "4. Access: http://localhost:8080"
echo ""
echo "🧹 Cleanup (when done):"
echo " cd glance-deployment && docker-compose down"
echo " cd .. && rm -rf glance-deployment"
echo ""
echo "🚀 Try other templates:"
echo " ./scripts/setup-template.sh umami # Analytics"
echo " ./scripts/setup-template.sh memos # Notes"
echo " ./scripts/setup-template.sh uptime-kuma # Monitoring"
echo ""
echo "📖 Full guide: SETUP_GUIDE.md"
+264
View File
@@ -0,0 +1,264 @@
#!/bin/bash
# Production Readiness Check Script
# This script validates that all production requirements are met
set -e
echo "🔍 Containr Production Readiness Check"
echo "========================================"
echo ""
ERRORS=0
WARNINGS=0
# Color codes
RED='\033[0;31m'
YELLOW='\033[1;33m'
GREEN='\033[0;32m'
NC='\033[0m' # No Color
error() {
echo -e "${RED}❌ ERROR: $1${NC}"
((ERRORS++))
}
warning() {
echo -e "${YELLOW}⚠️ WARNING: $1${NC}"
((WARNINGS++))
}
success() {
echo -e "${GREEN}$1${NC}"
}
info() {
echo "$1"
}
# Check if production env file exists
ENV_FILE=".env.prod"
if [ ! -f "$ENV_FILE" ] && [ -f ".env" ]; then
ENV_FILE=".env"
fi
if [ ! -f "$ENV_FILE" ]; then
error "No production env file found. Copy .env.production.example to .env.prod"
else
success "$ENV_FILE exists"
fi
# Load environment variables
if [ -f "$ENV_FILE" ]; then
set -a
# shellcheck disable=SC1090
source "$ENV_FILE"
set +a
fi
echo ""
echo "1. Environment Configuration"
echo "----------------------------"
# Check ENVIRONMENT
if [ "$ENVIRONMENT" != "production" ]; then
warning "ENVIRONMENT is not set to 'production' (current: ${ENVIRONMENT:-not set})"
else
success "ENVIRONMENT is set to production"
fi
# Check JWT_SECRET
if [ -z "$JWT_SECRET" ] || [ "$JWT_SECRET" = "your-secret-key-change-in-production" ]; then
error "JWT_SECRET is not set or using default value"
elif [ ${#JWT_SECRET} -lt 32 ]; then
error "JWT_SECRET must be at least 32 characters (current: ${#JWT_SECRET})"
else
success "JWT_SECRET is properly configured"
fi
# Check BETTER_AUTH_SECRET
if [ -z "$BETTER_AUTH_SECRET" ] || [ "$BETTER_AUTH_SECRET" = "PLACEHOLDER_BETTER_AUTH_SECRET_CHANGE_ME_32CHARS_MIN" ]; then
error "BETTER_AUTH_SECRET is not set or using placeholder"
elif [ ${#BETTER_AUTH_SECRET} -lt 32 ]; then
error "BETTER_AUTH_SECRET must be at least 32 characters"
else
success "BETTER_AUTH_SECRET is properly configured"
fi
# Check COOKIE_SECURE
if [ "$COOKIE_SECURE" != "true" ]; then
error "COOKIE_SECURE must be 'true' in production (current: ${COOKIE_SECURE:-not set})"
else
success "COOKIE_SECURE is enabled"
fi
# Check CORS_ORIGINS
if [ -z "$CORS_ORIGINS" ] || [ "$CORS_ORIGINS" = "*" ]; then
error "CORS_ORIGINS must be set to specific domains in production"
elif [[ "$CORS_ORIGINS" == *"*"* ]]; then
error "CORS_ORIGINS cannot contain wildcards in production"
else
success "CORS_ORIGINS is properly configured"
fi
echo ""
echo "2. Database Configuration"
echo "-------------------------"
# Check database password
if [ -z "$POSTGRES_PASSWORD" ] || [ "$POSTGRES_PASSWORD" = "dev_password_123" ]; then
error "POSTGRES_PASSWORD is not set or using default value"
else
success "POSTGRES_PASSWORD is configured"
fi
# Check Redis password
if [ -z "$REDIS_PASSWORD" ] || [ "$REDIS_PASSWORD" = "dev_redis_123" ]; then
error "REDIS_PASSWORD is not set or using default value"
else
success "REDIS_PASSWORD is configured"
fi
# Check AUTO_MIGRATE
if [ "$AUTO_MIGRATE" = "true" ]; then
success "AUTO_MIGRATE is enabled"
else
warning "AUTO_MIGRATE is disabled - ensure migrations are run manually"
fi
# Check SEED_DATA_ON_START
if [ "$SEED_DATA_ON_START" = "true" ]; then
error "SEED_DATA_ON_START must be false in production"
else
success "SEED_DATA_ON_START is disabled"
fi
echo ""
echo "3. Security Configuration"
echo "-------------------------"
# Check CONTAINR_AGENT_AUTH_TOKEN
if [ -z "$CONTAINR_AGENT_AUTH_TOKEN" ] || [ "$CONTAINR_AGENT_AUTH_TOKEN" = "replace_with_strong_agent_secret" ]; then
error "CONTAINR_AGENT_AUTH_TOKEN is not set or using placeholder"
else
success "CONTAINR_AGENT_AUTH_TOKEN is configured"
fi
# Check BCRYPT_COST
if [ -z "$BCRYPT_COST" ]; then
warning "BCRYPT_COST not set, using default"
elif [ "$BCRYPT_COST" -lt 12 ]; then
warning "BCRYPT_COST should be at least 12 for production (current: $BCRYPT_COST)"
else
success "BCRYPT_COST is properly configured"
fi
echo ""
echo "4. Domain Configuration"
echo "-----------------------"
# Check DOMAIN
if [ -z "$DOMAIN" ] || [ "$DOMAIN" = "localhost" ]; then
error "DOMAIN must be set to your actual domain"
else
success "DOMAIN is configured: $DOMAIN"
fi
# Check ACME_EMAIL
if [ -z "$ACME_EMAIL" ] || [ "$ACME_EMAIL" = "admin@localhost" ]; then
warning "ACME_EMAIL should be set to a valid email for SSL certificates"
else
success "ACME_EMAIL is configured"
fi
echo ""
echo "5. File Structure"
echo "-----------------"
# Check critical files
CRITICAL_FILES=(
"docker-compose.yml"
"infra/docker-compose.yml"
"app/backend/Dockerfile"
"app/frontend/Dockerfile"
"app/backend/go.mod"
"app/frontend/package.json"
)
for file in "${CRITICAL_FILES[@]}"; do
if [ -f "$file" ]; then
success "$file exists"
else
error "$file is missing"
fi
done
echo ""
echo "6. Docker Configuration"
echo "-----------------------"
# Check if Docker is installed
if command -v docker &> /dev/null; then
success "Docker is installed"
docker --version
else
error "Docker is not installed"
fi
# Check if Docker Compose is available
if docker compose version &> /dev/null; then
success "Docker Compose is available"
docker compose version
else
error "Docker Compose is not available"
fi
# Validate docker-compose.yml
if [ -f "infra/docker-compose.yml" ]; then
if docker compose -f infra/docker-compose.yml config -q 2>/dev/null; then
success "docker-compose.yml is valid"
else
error "docker-compose.yml has syntax errors"
fi
fi
echo ""
echo "7. Build Checks"
echo "---------------"
# Check backend build
if [ -f "app/backend/go.mod" ]; then
cd app/backend
if go mod verify &> /dev/null; then
success "Backend Go modules are valid"
else
warning "Backend Go modules verification failed"
fi
cd ../..
fi
# Check frontend build
if [ -f "app/frontend/package.json" ]; then
if [ -d "app/frontend/node_modules" ]; then
success "Frontend dependencies are installed"
else
warning "Frontend dependencies not installed - run 'npm install'"
fi
fi
echo ""
echo "========================================"
echo "Summary"
echo "========================================"
if [ $ERRORS -eq 0 ] && [ $WARNINGS -eq 0 ]; then
echo -e "${GREEN}✅ All checks passed! Ready for production deployment.${NC}"
exit 0
elif [ $ERRORS -eq 0 ]; then
echo -e "${YELLOW}⚠️ $WARNINGS warning(s) found. Review before deploying.${NC}"
exit 0
else
echo -e "${RED}$ERRORS error(s) and $WARNINGS warning(s) found.${NC}"
echo -e "${RED}Please fix all errors before deploying to production.${NC}"
exit 1
fi
+83
View File
@@ -0,0 +1,83 @@
#!/bin/bash
# One-Click Docker Deployment - Quick Start Script
# This script provides the simplest possible deployment experience
set -e
echo "🚀 One-Click Docker Deployment"
echo "============================"
echo ""
# Check if we're in the right directory
if [[ ! -f "scripts/auto-deploy.sh" ]]; then
echo "❌ Error: Please run this script from the project root directory"
exit 1
fi
# Make script executable
chmod +x scripts/auto-deploy.sh
echo "🎯 Choose your deployment:"
echo ""
echo "1. 🌐 Deploy Glance Dashboard (Recommended - Simple & Fast)"
echo "2. 📊 Deploy Umami Analytics (Web Analytics)"
echo "3. 📝 Deploy Memos (Note-taking)"
echo "4. 🔍 Deploy MeiliSearch (Search Engine)"
echo "5. 📈 Deploy Uptime Kuma (Monitoring)"
echo "6. 🚀 Deploy ALL Templates (Advanced)"
echo ""
read -p "Enter your choice (1-6): " choice
case $choice in
1)
echo ""
echo "🌐 Deploying Glance Dashboard..."
./scripts/auto-deploy.sh glance
;;
2)
echo ""
echo "📊 Deploying Umami Analytics..."
./scripts/auto-deploy.sh umami
;;
3)
echo ""
echo "📝 Deploying Memos..."
./scripts/auto-deploy.sh memos
;;
4)
echo ""
echo "🔍 Deploying MeiliSearch..."
./scripts/auto-deploy.sh meilisearch
;;
5)
echo ""
echo "📈 Deploying Uptime Kuma..."
./scripts/auto-deploy.sh uptime-kuma
;;
6)
echo ""
echo "🚀 Deploying ALL Templates (this will take a while)..."
./scripts/auto-deploy.sh --all
;;
*)
echo "❌ Invalid choice. Defaulting to Glance Dashboard..."
./scripts/auto-deploy.sh glance
;;
esac
echo ""
echo "✅ Deployment process started!"
echo ""
echo "📋 What's happening automatically:"
echo " 🔍 Checking dependencies (Docker, Docker Compose)"
echo " 📁 Creating deployment directories"
echo " 🔧 Extracting docker-compose.yml"
echo " 🔐 Generating secrets and passwords"
echo " 🐳 Pulling Docker images"
echo " 🚀 Starting all services"
echo " 🌐 Showing access URLs"
echo ""
echo "📊 Watch the progress above. When complete, you'll see access URLs!"
echo ""
echo "🛑 To stop services: cd deployments/template-name && docker-compose down"
+430
View File
@@ -0,0 +1,430 @@
#!/bin/bash
# Docker Template Auto-Setup Script
# This script provides a guided walkthrough for deploying any template
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
# Template directory
TEMPLATE_DIR="$(dirname "$0")/../templates"
# Available templates
declare -A TEMPLATES=(
["umami"]="Umami Analytics - Privacy-focused web analytics"
["plex"]="Plex Media Server - Media streaming and organization"
["immich"]="Immich - Photo and video backup solution"
["n8n"]="n8n - Workflow automation platform"
["supabase"]="Supabase - Open source Firebase alternative"
["home-assistant"]="Home Assistant - Smart home automation"
["uptime-kuma"]="Uptime Kuma - Monitoring dashboard"
["grafana"]="Grafana - Metrics visualization and monitoring"
["traefik"]="Traefik - Reverse proxy and load balancer"
["memos"]="Memos - Note-taking and knowledge management"
["meilisearch"]="MeiliSearch - Fast search engine"
["vaultwarden"]="Vaultwarden - Password manager (Bitwarden alternative)"
["pihole"]="Pi-hole - DNS ad blocker"
["appwrite"]="Appwrite - Backend-as-a-Service platform"
["gitea"]="Gitea - Git hosting service"
["mastodon"]="Mastodon - Decentralized social network"
["jellyfin"]="Jellyfin - Media server (Plex alternative)"
["nextcloud"]="Nextcloud - Cloud storage and collaboration"
["glance"]="Glance - Personal dashboard"
["cloudreve"]="Cloudreve - File manager with multiple backends"
)
print_header() {
echo -e "${BLUE}========================================${NC}"
echo -e "${BLUE}$1${NC}"
echo -e "${BLUE}========================================${NC}"
}
print_success() {
echo -e "${GREEN}$1${NC}"
}
print_error() {
echo -e "${RED}$1${NC}"
}
print_warning() {
echo -e "${YELLOW}⚠️ $1${NC}"
}
print_info() {
echo -e "${BLUE}$1${NC}"
}
check_dependencies() {
print_header "Checking Dependencies"
# Check Docker
if command -v docker &> /dev/null; then
print_success "Docker is installed"
docker_version=$(docker --version | cut -d' ' -f3 | cut -d',' -f1)
print_info "Docker version: $docker_version"
else
print_error "Docker is not installed"
print_info "Please install Docker: https://docs.docker.com/get-docker/"
exit 1
fi
# Check Docker Compose
if command -v docker-compose &> /dev/null; then
print_success "Docker Compose is installed"
compose_version=$(docker-compose --version | cut -d' ' -f3 | cut -d',' -f1)
print_info "Docker Compose version: $compose_version"
elif docker compose version &> /dev/null; then
print_success "Docker Compose (plugin) is installed"
compose_version=$(docker compose version | cut -d' ' -f3 | cut -d',' -f1)
print_info "Docker Compose version: $compose_version"
DOCKER_COMPOSE_CMD="docker compose"
else
print_error "Docker Compose is not installed"
print_info "Please install Docker Compose: https://docs.docker.com/compose/install/"
exit 1
fi
# Check if template directory exists
if [[ ! -d "$TEMPLATE_DIR" ]]; then
print_error "Template directory not found: $TEMPLATE_DIR"
exit 1
fi
print_success "All dependencies are met"
}
list_templates() {
print_header "Available Templates"
echo "Available templates:"
for template in "${!TEMPLATES[@]}"; do
echo "$template - ${TEMPLATES[$template]}"
done
echo ""
}
select_template() {
if [[ -n "$SELECTED_TEMPLATE" ]]; then
if [[ -z "${TEMPLATES[$SELECTED_TEMPLATE]}" ]]; then
print_error "Unknown template: $SELECTED_TEMPLATE"
list_templates
exit 1
fi
return
fi
print_header "Select Template"
local i=1
local template_array=()
for template in "${!TEMPLATES[@]}"; do
echo " $i) $template - ${TEMPLATES[$template]}"
template_array+=("$template")
((i++))
done
echo ""
read -p "Select a template (1-${#template_array[@]}): " choice
if [[ $choice =~ ^[0-9]+$ ]] && [ $choice -ge 1 ] && [ $choice -le ${#template_array[@]} ]; then
SELECTED_TEMPLATE="${template_array[$((choice-1))]}"
else
print_error "Invalid selection"
exit 1
fi
print_success "Selected template: $SELECTED_TEMPLATE"
}
setup_template() {
local template="$1"
local template_file="$TEMPLATE_DIR/$template.md"
if [[ ! -f "$template_file" ]]; then
print_error "Template file not found: $template_file"
exit 1
fi
print_header "Setting up $template"
# Create project directory
local project_dir="$PWD/$template-deployment"
if [[ -d "$project_dir" ]]; then
print_warning "Directory $project_dir already exists"
read -p "Do you want to remove it and continue? (y/N): " -n 1 -r
echo
if [[ $REPLY =~ ^[Yy]$ ]]; then
rm -rf "$project_dir"
else
print_info "Please choose a different location or remove the existing directory"
exit 1
fi
fi
mkdir -p "$project_dir"
print_success "Created project directory: $project_dir"
# Extract docker-compose.yml from template
extract_docker_compose "$template_file" "$project_dir"
# Check for environment variables
check_environment_variables "$template_file" "$project_dir"
# Check for additional setup steps
check_setup_requirements "$template_file" "$project_dir"
print_success "Template setup completed"
print_info "Project directory: $project_dir"
print_info "Next steps:"
echo " 1. cd $project_dir"
echo " 2. Review and modify configuration if needed"
echo " 3. Run: ${DOCKER_COMPOSE_CMD:-docker-compose} up -d"
}
extract_docker_compose() {
local template_file="$1"
local project_dir="$2"
print_info "Extracting docker-compose.yml..."
# Extract docker-compose.yml from markdown file
sed -n '/```yaml/,/```/p' "$template_file" | sed '1d;$d' > "$project_dir/docker-compose.yml"
if [[ ! -s "$project_dir/docker-compose.yml" ]]; then
print_error "Failed to extract docker-compose.yml"
exit 1
fi
print_success "docker-compose.yml extracted"
}
check_environment_variables() {
local template_file="$1"
local project_dir="$2"
print_info "Checking for required environment variables..."
# Extract environment variables section
local env_vars=$(sed -n '/## Environment Variables/,/##/p' "$template_file" | grep -E '^- `[^`]+`')
if [[ -n "$env_vars" ]]; then
print_warning "This template requires environment variables:"
echo "$env_vars"
echo ""
# Create .env file template
local env_file="$project_dir/.env"
echo "# Environment variables for $template" > "$env_file"
echo "# Please update these values before starting the services" >> "$env_file"
echo "" >> "$env_file"
# Add common environment variables
echo "$env_vars" | while read -r line; do
if [[ $line =~ -\s*\`([^`]+)\`.* ]]; then
local var_name="${BASH_REMATCH[1]}"
echo "$var_name=change_me" >> "$env_file"
fi
done
print_success "Created .env template file"
print_warning "Please edit $env_file with your values before starting"
fi
}
check_setup_requirements() {
local template_file="$1"
local project_dir="$2"
print_info "Checking setup requirements..."
# Extract setup guide section
local setup_guide=$(sed -n '/## Setup Guide/,/##/p' "$template_file")
if [[ -n "$setup_guide" ]]; then
print_warning "This template has specific setup requirements:"
echo "$setup_guide" | head -20
echo ""
print_info "Please review the full setup guide in $template_file"
fi
# Check for volume requirements
local volumes=$(grep -E "^\s*-\s+.*:/" "$project_dir/docker-compose.yml" | grep -v "./")
if [[ -n "$volumes" ]]; then
print_warning "This template requires host directories:"
echo "$volumes"
echo ""
print_info "Please create these directories or update the paths in docker-compose.yml"
fi
}
deploy_template() {
local project_dir="$PWD/$SELECTED_TEMPLATE-deployment"
print_header "Deploying $SELECTED_TEMPLATE"
if [[ ! -d "$project_dir" ]]; then
print_error "Project directory not found: $project_dir"
print_info "Please run setup first"
exit 1
fi
cd "$project_dir"
# Check if .env exists and has default values
if [[ -f ".env" ]]; then
if grep -q "change_me" .env; then
print_warning "Please update the environment variables in .env file"
print_info "Current values that need updating:"
grep "change_me" .env
echo ""
read -p "Continue anyway? (y/N): " -n 1 -r
echo
if [[ ! $REPLY =~ ^[Yy]$ ]]; then
exit 1
fi
fi
fi
print_info "Starting deployment..."
# Pull images
print_info "Pulling Docker images..."
${DOCKER_COMPOSE_CMD:-docker-compose} pull
# Start services
print_info "Starting services..."
${DOCKER_COMPOSE_CMD:-docker-compose} up -d
# Show status
print_success "Deployment completed!"
${DOCKER_COMPOSE_CMD:-docker-compose} ps
# Show access information
show_access_info "$project_dir"
}
show_access_info() {
local project_dir="$1"
print_header "Access Information"
# Extract ports from docker-compose.yml
local ports=$(grep -E "^\s*-\s*\"[0-9]+:[0-9]+\"" "$project_dir/docker-compose.yml")
if [[ -n "$ports" ]]; then
print_info "Service access URLs:"
echo "$ports" | while read -r line; do
if [[ $line =~ -\s*\"([0-9]+):([0-9]+)\" ]]; then
local host_port="${BASH_REMATCH[1]}"
local container_port="${BASH_REMATCH[2]}"
echo " • http://localhost:$host_port (container port: $container_port)"
fi
done
fi
print_info "Useful commands:"
echo " • View logs: ${DOCKER_COMPOSE_CMD:-docker-compose} logs -f"
echo " • Stop services: ${DOCKER_COMPOSE_CMD:-docker-compose} down"
echo " • Restart services: ${DOCKER_COMPOSE_CMD:-docker-compose} restart"
echo " • Update services: ${DOCKER_COMPOSE_CMD:-docker-compose} pull && ${DOCKER_COMPOSE_CMD:-docker-compose} up -d"
}
show_help() {
echo "Docker Template Setup Script"
echo ""
echo "Usage: $0 [OPTIONS] [TEMPLATE]"
echo ""
echo "Options:"
echo " -h, --help Show this help message"
echo " -l, --list List available templates"
echo " -s, --setup Setup template only (don't deploy)"
echo " -d, --deploy Deploy template (requires setup first)"
echo ""
echo "Templates:"
list_templates
echo ""
echo "Examples:"
echo " $0 # Interactive mode"
echo " $0 umami # Setup umami template"
echo " $0 --list # List all templates"
echo " $0 --setup umami # Setup umami only"
echo " $0 --deploy umami # Deploy umami (must be setup first)"
}
# Main script logic
main() {
local action="interactive"
local setup_only=false
local deploy_only=false
# Parse command line arguments
while [[ $# -gt 0 ]]; do
case $1 in
-h|--help)
show_help
exit 0
;;
-l|--list)
list_templates
exit 0
;;
-s|--setup)
setup_only=true
shift
;;
-d|--deploy)
deploy_only=true
shift
;;
-*)
print_error "Unknown option: $1"
show_help
exit 1
;;
*)
SELECTED_TEMPLATE="$1"
shift
;;
esac
done
# Check dependencies
check_dependencies
# Execute based on action
if [[ "$deploy_only" == true ]]; then
if [[ -z "$SELECTED_TEMPLATE" ]]; then
print_error "Template name required for deployment"
exit 1
fi
deploy_template
elif [[ "$setup_only" == true ]]; then
select_template
setup_template "$SELECTED_TEMPLATE"
else
# Interactive mode
select_template
setup_template "$SELECTED_TEMPLATE"
echo ""
read -p "Do you want to deploy the template now? (y/N): " -n 1 -r
echo
if [[ $REPLY =~ ^[Yy]$ ]]; then
deploy_template
else
print_info "Setup completed. You can deploy later by running:"
echo " $0 --deploy $SELECTED_TEMPLATE"
fi
fi
}
# Run main function
main "$@"
+47
View File
@@ -0,0 +1,47 @@
#!/bin/bash
# Test the auto-deployment system with a simple template
echo "🧪 Testing Auto-Deployment System"
echo "================================"
echo ""
# Check if we're in the right directory
if [[ ! -f "scripts/auto-deploy.sh" ]]; then
echo "❌ Error: Please run this script from the project root directory"
exit 1
fi
echo "🔍 Checking dependencies..."
if command -v docker &> /dev/null; then
echo "✅ Docker is available"
else
echo "❌ Docker is not available - this test requires Docker"
exit 1
fi
echo ""
echo "🎯 Testing auto-deployment with Glance (simplest template)..."
echo ""
# Make scripts executable
chmod +x scripts/auto-deploy.sh
chmod +x scripts/quick-deploy.sh
echo "📋 Available deployment options:"
echo "1. Quick Deploy: ./scripts/quick-deploy.sh"
echo "2. Direct Deploy: ./scripts/auto-deploy.sh glance"
echo "3. List Templates: ./scripts/auto-deploy.sh --list"
echo "4. Deploy All: ./scripts/auto-deploy.sh --all"
echo ""
echo "🚀 Let's test the system by listing available templates:"
./scripts/auto-deploy.sh --list
echo ""
echo "✅ Auto-deployment system is ready!"
echo ""
echo "🎯 To use it:"
echo " ./scripts/quick-deploy.sh # Interactive menu"
echo " ./scripts/auto-deploy.sh glance # Direct deployment"
echo ""
echo "📖 Full guide: AUTO_DEPLOY_GUIDE.md"
+111
View File
@@ -0,0 +1,111 @@
#!/bin/bash
set -euo pipefail
ROOT_DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")/.." && pwd)"
SCRIPT="$ROOT_DIR/start-unified.sh"
ENV_FILE="$ROOT_DIR/.env.prod"
if ! command -v docker >/dev/null 2>&1; then
echo "SKIP: docker command not found, skipping preflight tests"
exit 0
fi
backup_file=""
if [ -f "$ENV_FILE" ]; then
backup_file="$(mktemp)"
cp "$ENV_FILE" "$backup_file"
fi
cleanup() {
if [ -n "$backup_file" ] && [ -f "$backup_file" ]; then
mv "$backup_file" "$ENV_FILE"
else
rm -f "$ENV_FILE"
fi
}
trap cleanup EXIT
write_env() {
cat > "$ENV_FILE" <<EOT
$1
EOT
}
expect_fail() {
local name="$1"
local expected="$2"
shift 2
set +e
local output
output="$($SCRIPT "$@" 2>&1)"
local code=$?
set -e
if [ "$code" -eq 0 ]; then
echo "FAIL [$name]: command unexpectedly succeeded"
echo "$output"
exit 1
fi
if ! grep -Fq "$expected" <<<"$output"; then
echo "FAIL [$name]: expected error message not found"
echo "Expected: $expected"
echo "Output:"
echo "$output"
exit 1
fi
echo "PASS [$name]"
}
write_env "DOMAIN=localhost
JWT_SECRET=this-is-a-very-strong-production-secret-123
BETTER_AUTH_SECRET=this-is-a-very-strong-better-auth-secret-123
BETTER_AUTH_INTERNAL_TOKEN=internal-auth-token
COOKIE_SECURE=true
TRAEFIK_AUTH=admin:\$\$apr1\$\$hash\$\$hashvalue"
expect_fail "prod-domain" "DOMAIN must be set to a real domain for production." prod
write_env "DOMAIN=example.com
JWT_SECRET=dev_jwt_secret_key_change_in_production
BETTER_AUTH_SECRET=this-is-a-very-strong-better-auth-secret-123
BETTER_AUTH_INTERNAL_TOKEN=internal-auth-token
COOKIE_SECURE=true
TRAEFIK_AUTH=admin:\$\$apr1\$\$hash\$\$hashvalue"
expect_fail "prod-jwt" "JWT_SECRET must be set to a strong non-default value in production." prod
write_env "DOMAIN=example.com
JWT_SECRET=strong-secret
BETTER_AUTH_SECRET=this-is-a-very-strong-better-auth-secret-123
BETTER_AUTH_INTERNAL_TOKEN=internal-auth-token
COOKIE_SECURE=true
TRAEFIK_AUTH=admin:\$\$apr1\$\$hash\$\$hashvalue"
expect_fail "prod-jwt-length" "JWT_SECRET must be at least 32 characters in production." prod
write_env "DOMAIN=example.com
JWT_SECRET=this-is-a-very-strong-production-secret-123
BETTER_AUTH_SECRET=this-is-a-very-strong-better-auth-secret-123
BETTER_AUTH_INTERNAL_TOKEN=internal-auth-token
COOKIE_SECURE=true"
expect_fail "prod-traefik-auth" "TRAEFIK_AUTH must be set (basic auth hash) for dashboard protection in production." prod
write_env "DOMAIN=example.com
JWT_SECRET=this-is-a-very-strong-production-secret-123
BETTER_AUTH_SECRET=this-is-a-very-strong-better-auth-secret-123
BETTER_AUTH_INTERNAL_TOKEN=internal-auth-token
COOKIE_SECURE=true
TRAEFIK_AUTH=admin:\$\$apr1\$\$hash\$\$hashvalue"
expect_fail "prod-agent-auth" "CONTAINR_AGENT_AUTH_TOKEN or CONTAINR_AGENT_AUTH_TOKENS must be set in production." prod
write_env "DOMAIN=example.com
JWT_SECRET=this-is-a-very-strong-production-secret-123
BETTER_AUTH_SECRET=this-is-a-very-strong-better-auth-secret-123
BETTER_AUTH_INTERNAL_TOKEN=internal-auth-token
COOKIE_SECURE=true
TRAEFIK_AUTH=admin:\$\$apr1\$\$hash\$\$hashvalue
CONTAINR_AGENT_AUTH_TOKEN=agent-secret"
expect_fail "cloudflare-token" "CLOUDFLARED_TOKEN must be set." cloudflare
echo "All start-unified preflight tests passed"