frappe_docker/production/scripts/deploy.sh

155 lines
No EOL
4.9 KiB
Bash
Executable file

#!/bin/bash
# ERPNext Production Deployment Script
# Usage: ./deploy.sh [--setup|--regenerate]
set -e
# Colors
RED='\033[0;31m'; GREEN='\033[0;32m'; YELLOW='\033[1;33m'; NC='\033[0m'
# Helpers
echo_info() { echo -e "${GREEN}[INFO]${NC} $1"; }
echo_warn() { echo -e "${YELLOW}[WARN]${NC} $1"; }
echo_error() { echo -e "${RED}[ERROR]${NC} $1"; }
# Directories
SCRIPT_DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)"
PRODUCTION_DIR="$(dirname "$SCRIPT_DIR")"
PROJECT_ROOT="$(dirname "$PRODUCTION_DIR")"
cd "$PRODUCTION_DIR"
# Parse arguments
case "${1:-}" in
--help|-h)
cat << EOF
Usage: $0 [OPTIONS]
Options:
--setup Setup environment files from templates
--regenerate Only regenerate production.yaml (don't deploy)
--help, -h Show this help
Examples:
$0 # Normal deployment
$0 --setup # Create env files first
$0 --regenerate # Regenerate production.yaml only
EOF
exit 0
;;
--setup) MODE="setup" ;;
--regenerate) MODE="regenerate" ;;
"") MODE="deploy" ;;
*) echo_error "Unknown: $1 (use --help)"; exit 1 ;;
esac
# Setup mode: create env files
if [[ "$MODE" == "setup" ]]; then
echo_info "Setting up environment files..."
[[ ! -f "production.env.example" ]] && { echo_error "Template files missing!"; exit 1; }
for template in production.env.example traefik.env.example mariadb.env.example; do
target="${template%.example}"
if [[ -f "$target" ]]; then
echo_warn "$target exists, skipping..."
else
cp "$template" "$target" && chmod 600 "$target"
echo_info "✓ Created $target"
fi
done
echo ""
echo_info "Edit these files before deploying:"
echo_info " 1. production.env - SITES, passwords, email"
echo_info " 2. mariadb.env - DB_PASSWORD"
echo_info " 3. traefik.env - domain, email, password"
exit 0
fi
# Validate prerequisites
[[ $EUID -eq 0 ]] && { echo_error "Don't run as root"; exit 1; }
command -v docker &> /dev/null || { echo_error "Docker not installed"; exit 1; }
docker compose version &> /dev/null || { echo_error "Docker Compose V2 not installed"; exit 1; }
echo_info "ERPNext Production Deployment"
# Check env files exist
for file in production.env traefik.env mariadb.env; do
[[ ! -f "$file" ]] && { echo_error "$file not found! Run: $0 --setup"; exit 1; }
done
# Validate configuration
echo_info "Validating configuration..."
./scripts/validate-env.sh || { echo_error "Validation failed!"; exit 1; }
# Warn about defaults
if grep -q "changeit" production.env mariadb.env traefik.env 2>/dev/null; then
echo_warn "Default passwords detected!"
read -p "Updated all passwords? (yes/no): " confirm
[[ "$confirm" != "yes" ]] && { echo_error "Update passwords first"; exit 1; }
fi
if grep -q "yourdomain.com\|CHANGEME_" production.env traefik.env 2>/dev/null; then
echo_warn "Default domains detected!"
read -p "Updated all domains? (yes/no): " confirm
[[ "$confirm" != "yes" ]] && { echo_error "Update domains first"; exit 1; }
fi
# Generate production.yaml helper
generate_yaml() {
[[ -f "production.yaml" ]] && cp production.yaml "production.yaml.backup.$(date +%Y%m%d_%H%M%S)"
docker compose --project-name erpnext-production \
--env-file production.env \
-f "$PROJECT_ROOT/compose.yaml" \
-f "$PROJECT_ROOT/overrides/compose.redis.yaml" \
-f "$PROJECT_ROOT/overrides/compose.multi-bench.yaml" \
-f "$PROJECT_ROOT/overrides/compose.multi-bench-ssl.yaml" \
config > production.yaml
}
# Regenerate mode: just regenerate yaml
if [[ "$MODE" == "regenerate" ]]; then
echo_info "Regenerating production.yaml..."
generate_yaml
echo_info "✓ Regenerated. Apply: docker compose -f production.yaml up -d"
exit 0
fi
# Deploy services
echo ""
echo_info "Step 1: Deploying Traefik..."
docker compose --project-name traefik \
--env-file traefik.env \
-f "$PROJECT_ROOT/overrides/compose.traefik.yaml" \
-f "$PROJECT_ROOT/overrides/compose.traefik-ssl.yaml" \
up -d
echo_info "✓ Traefik deployed"
echo_info "Step 2: Deploying MariaDB..."
docker compose --project-name mariadb \
--env-file mariadb.env \
-f "$PROJECT_ROOT/overrides/compose.mariadb-shared.yaml" \
up -d
echo_info "✓ MariaDB deployed. Waiting 30s for initialization..."
sleep 30
echo_info "Step 3: Generating production.yaml..."
generate_yaml
echo_info "✓ Generated"
echo_info "Step 4: Deploying ERPNext..."
docker compose --project-name erpnext-production -f production.yaml up -d
echo_info "✓ ERPNext deployed"
# Success message
TRAEFIK_DOMAIN=$(grep "^TRAEFIK_DOMAIN=" traefik.env | cut -d'=' -f2)
echo ""
echo_info "✓ Deployment complete!"
echo_info "Next steps:"
echo_info " 1. Check health: docker ps"
echo_info " 2. Create site: ./scripts/create-site.sh"
echo_info " 3. Traefik: https://$TRAEFIK_DOMAIN"
echo_warn "Note: SSL certificates may take a few minutes"