- 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.
310 lines
9.2 KiB
Bash
Executable File
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
|