Assist_Design/scripts/plesk-deploy.sh
barsa ce7c7773cd Refactor Dockerfiles and enhance Next.js configuration for improved build and security
- Updated Dockerfiles for BFF and Portal to optimize dependency installation and build processes, focusing on specific package filters.
- Enhanced Next.js configuration to improve security headers and Content Security Policy for development environments.
- Adjusted Docker Compose files to support dynamic image tagging for better version control.
- Cleaned up deployment scripts to include environment variable management for image tagging.
2025-12-10 18:42:33 +09:00

310 lines
9.2 KiB
Bash
Executable File

#!/bin/bash
# =============================================================================
# 🐳 Plesk Docker Deployment Script
# =============================================================================
# Deploys pre-built Docker images to a Plesk server
# For building images locally, use: pnpm plesk:images
# =============================================================================
set -euo pipefail
# =============================================================================
# Configuration
# =============================================================================
SCRIPT_DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)"
PROJECT_ROOT="$(cd "$SCRIPT_DIR/.." && pwd)"
# Default paths (override via env vars)
REPO_PATH="${REPO_PATH:-/var/www/vhosts/yourdomain.com/git/customer-portal}"
COMPOSE_FILE="${COMPOSE_FILE:-$PROJECT_ROOT/docker/portainer/docker-compose.yml}"
ENV_FILE="${ENV_FILE:-$PROJECT_ROOT/.env}"
# Image settings
IMAGE_FRONTEND="${IMAGE_FRONTEND:-portal-frontend}"
IMAGE_BACKEND="${IMAGE_BACKEND:-portal-backend}"
IMAGE_TAG="${IMAGE_TAG:-latest}"
# =============================================================================
# Colors and Logging
# =============================================================================
if [[ -t 1 ]]; then
GREEN='\033[0;32m'
YELLOW='\033[1;33m'
RED='\033[0;31m'
BLUE='\033[0;34m'
NC='\033[0m'
else
GREEN='' YELLOW='' RED='' BLUE='' NC=''
fi
log() { echo -e "${GREEN}[PLESK]${NC} $*"; }
warn() { echo -e "${YELLOW}[PLESK]${NC} WARNING: $*"; }
error() { echo -e "${RED}[PLESK]${NC} ERROR: $*"; exit 1; }
info() { echo -e "${BLUE}[PLESK]${NC} $*"; }
# =============================================================================
# Usage
# =============================================================================
usage() {
cat <<EOF
Deploy Docker images to Plesk server.
Usage: $0 [COMMAND] [OPTIONS]
Commands:
deploy Full deployment (load images, run migrations, start services)
start Start services
stop Stop services
restart Restart services
status Show service status
logs Show service logs
load Load Docker images from tarballs
help Show this help
Options:
--env-file <path> Path to environment file (default: .env)
--compose <path> Path to docker-compose file
--tag <tag> Image tag to use (default: latest)
Examples:
$0 deploy # Full deployment
$0 load # Load images from tarballs
$0 status # Check service status
$0 logs backend # Show backend logs
EOF
exit 0
}
# =============================================================================
# Pre-flight Checks
# =============================================================================
preflight_checks() {
log "🔍 Running pre-flight checks..."
# Check Docker
if ! command -v docker &> /dev/null; then
error "Docker is not installed. Please install Docker first."
fi
# Check Docker daemon
if ! docker info >/dev/null 2>&1; then
error "Docker daemon is not running."
fi
# Check docker compose
if ! docker compose version >/dev/null 2>&1; then
error "Docker Compose V2 is required. Please upgrade Docker."
fi
# Check environment file
if [[ ! -f "$ENV_FILE" ]]; then
if [[ -f "$PROJECT_ROOT/.env.production.example" ]]; then
log "Creating environment file from template..."
cp "$PROJECT_ROOT/.env.production.example" "$ENV_FILE"
warn "Please edit $ENV_FILE with your production values!"
error "Production environment not configured. Please set up .env"
else
error "Environment file not found: $ENV_FILE"
fi
fi
# Check compose file
if [[ ! -f "$COMPOSE_FILE" ]]; then
error "Docker Compose file not found: $COMPOSE_FILE"
fi
log "✅ Pre-flight checks passed"
}
# =============================================================================
# Load Images from Tarballs
# =============================================================================
load_images() {
log "📦 Loading Docker images..."
local search_dir="${1:-$PROJECT_ROOT}"
local loaded=0
for img in "$IMAGE_FRONTEND" "$IMAGE_BACKEND"; do
local tarball
# Try compressed first, then uncompressed
if [[ -f "$search_dir/${img}.latest.tar.gz" ]]; then
tarball="$search_dir/${img}.latest.tar.gz"
log "Loading $tarball..."
gunzip -c "$tarball" | docker load
loaded=$((loaded + 1))
elif [[ -f "$search_dir/${img}.${IMAGE_TAG}.tar.gz" ]]; then
tarball="$search_dir/${img}.${IMAGE_TAG}.tar.gz"
log "Loading $tarball..."
gunzip -c "$tarball" | docker load
loaded=$((loaded + 1))
elif [[ -f "$search_dir/${img}.latest.tar" ]]; then
tarball="$search_dir/${img}.latest.tar"
log "Loading $tarball..."
docker load -i "$tarball"
loaded=$((loaded + 1))
elif [[ -f "$search_dir/${img}.${IMAGE_TAG}.tar" ]]; then
tarball="$search_dir/${img}.${IMAGE_TAG}.tar"
log "Loading $tarball..."
docker load -i "$tarball"
loaded=$((loaded + 1))
else
warn "No tarball found for $img"
fi
done
if [[ $loaded -eq 0 ]]; then
error "No image tarballs found in $search_dir"
fi
log "✅ Loaded $loaded images"
}
# =============================================================================
# Docker Compose Helpers
# =============================================================================
dc() {
docker compose -f "$COMPOSE_FILE" --env-file "$ENV_FILE" "$@"
}
# =============================================================================
# Deployment
# =============================================================================
deploy() {
log "🚀 Starting Plesk Docker deployment..."
preflight_checks
# Check if images exist, if not try to load from tarballs
if ! docker image inspect "${IMAGE_FRONTEND}:latest" >/dev/null 2>&1 || \
! docker image inspect "${IMAGE_BACKEND}:latest" >/dev/null 2>&1; then
log "Images not found, attempting to load from tarballs..."
load_images "$PROJECT_ROOT" || true
fi
# Verify images exist
for img in "${IMAGE_FRONTEND}:latest" "${IMAGE_BACKEND}:latest"; do
if ! docker image inspect "$img" >/dev/null 2>&1; then
error "Required image not found: $img. Build images first with: pnpm plesk:images"
fi
done
# Start infrastructure first
log "🗄️ Starting database and cache..."
dc up -d database cache
# Wait for database
log "⏳ Waiting for database..."
local timeout=60
while [[ $timeout -gt 0 ]]; do
if dc exec -T database pg_isready -U portal -d portal_prod 2>/dev/null; then
log "✅ Database is ready"
break
fi
sleep 2
timeout=$((timeout - 2))
done
if [[ $timeout -eq 0 ]]; then
error "Database failed to start within 60 seconds"
fi
# Start application services
log "🚀 Starting application services..."
dc up -d frontend backend
# Health check
log "🏥 Waiting for services to be healthy..."
sleep 15
if dc ps | grep -q "unhealthy"; then
warn "Some services may not be healthy - check logs with: $0 logs"
else
log "✅ All services healthy"
fi
log "🎉 Plesk Docker deployment completed!"
echo ""
info "📝 Next steps:"
echo " 1. Configure Plesk reverse proxy to point to port 3000 (frontend)"
echo " 2. Set up SSL certificates in Plesk"
echo " 3. Test your application at your domain"
echo ""
info "📋 Useful commands:"
echo " $0 status - Check service status"
echo " $0 logs - View logs"
echo " $0 restart - Restart services"
}
# =============================================================================
# Service Management
# =============================================================================
start_services() {
preflight_checks
log "▶️ Starting services..."
dc up -d
log "✅ Services started"
}
stop_services() {
log "⏹️ Stopping services..."
dc down
log "✅ Services stopped"
}
restart_services() {
log "🔄 Restarting services..."
dc restart
log "✅ Services restarted"
}
show_status() {
log "📊 Service Status:"
dc ps
echo ""
log "🏥 Health Status:"
dc ps --format "table {{.Name}}\t{{.Status}}\t{{.Ports}}"
}
show_logs() {
local service="${1:-}"
if [[ -n "$service" ]]; then
dc logs -f "$service"
else
dc logs -f
fi
}
# =============================================================================
# Argument Parsing
# =============================================================================
COMMAND="${1:-help}"
shift || true
while [[ $# -gt 0 ]]; do
case "$1" in
--env-file) ENV_FILE="$2"; shift 2 ;;
--compose) COMPOSE_FILE="$2"; shift 2 ;;
--tag) IMAGE_TAG="$2"; shift 2 ;;
-h|--help) usage ;;
*) break ;;
esac
done
export IMAGE_TAG
# =============================================================================
# Main
# =============================================================================
case "$COMMAND" in
deploy) deploy ;;
start) start_services ;;
stop) stop_services ;;
restart) restart_services ;;
status) show_status ;;
logs) show_logs "$@" ;;
load) preflight_checks; load_images "${1:-$PROJECT_ROOT}" ;;
help|*) usage ;;
esac