#!/usr/bin/env bash set -euo pipefail # ============================================================ # 部署上传脚本 # 将前端/后端/docker-compose 文件上传至正式服务器 # # 用法: # ./scripts/upload.sh # 上传所有 # ./scripts/upload.sh frontend # 仅上传前端 # ./scripts/upload.sh backend # 仅上传后端 # ./scripts/upload.sh compose # 仅上传 docker-compose # ./scripts/upload.sh ./frontend/dist/assets # 上传指定路径 # ============================================================ SERVER="ubuntu@ec2-3-71-153-45.eu-central-1.compute.amazonaws.com" REMOTE_ROOT="/data/project/dashboard" PROJECT_ROOT="$(cd "$(dirname "$0")/.." && pwd)" SSH_KEY="$HOME/.ssh/aws_eafon.pem" # SSH / SCP 通用选项 SSH_OPTS="-i $SSH_KEY -o StrictHostKeyChecking=no" SCP_OPTS="-i $SSH_KEY -o StrictHostKeyChecking=no" # 颜色输出 GREEN='\033[0;32m' YELLOW='\033[1;33m' CYAN='\033[0;36m' NC='\033[0m' info() { echo -e "${CYAN}[INFO]${NC} $1"; } ok() { echo -e "${GREEN}[OK]${NC} $1"; } warn() { echo -e "${YELLOW}[WARN]${NC} $1"; } # ---- 上传函数 ---- upload_frontend() { info "上传前端 dist/ 和 nginx.conf ..." ssh $SSH_OPTS "$SERVER" "mkdir -p ${REMOTE_ROOT}/frontend" scp $SCP_OPTS -r "${PROJECT_ROOT}/frontend/dist" "${SERVER}:${REMOTE_ROOT}/frontend/" scp $SCP_OPTS "${PROJECT_ROOT}/frontend/nginx.conf" "${SERVER}:${REMOTE_ROOT}/frontend/" ok "前端上传完成" } upload_backend() { info "上传后端 src/ 和 Dockerfile ..." ssh $SSH_OPTS "$SERVER" "mkdir -p ${REMOTE_ROOT}/backend" scp $SCP_OPTS -r "${PROJECT_ROOT}/backend/src" "${SERVER}:${REMOTE_ROOT}/backend/" scp $SCP_OPTS "${PROJECT_ROOT}/backend/Dockerfile" "${SERVER}:${REMOTE_ROOT}/backend/" ok "后端上传完成" } upload_compose() { info "上传 docker-compose.yml ..." scp $SCP_OPTS "${PROJECT_ROOT}/docker-compose.yml" "${SERVER}:${REMOTE_ROOT}/" ok "docker-compose.yml 上传完成" } upload_all() { upload_frontend upload_backend upload_compose } # ---- 上传指定路径 ---- # 根据传入的相对/绝对路径,映射到服务器对应位置 # 例如: ./frontend/dist/assets → ${REMOTE_ROOT}/frontend/dist/assets upload_path() { local input_path="$1" # 转为项目根目录下的相对路径 local rel_path rel_path="$(cd "$(dirname "$input_path")" 2>/dev/null && realpath --relative-to="$PROJECT_ROOT" "$(pwd)/$(basename "$input_path")")" \ || rel_path="${input_path#"$PROJECT_ROOT"/}" if [[ -z "$rel_path" || "$rel_path" == /* ]]; then # 如果去掉项目根前缀失败,尝试直接去掉 ./ 前缀 rel_path="${input_path#./}" fi local local_full="${PROJECT_ROOT}/${rel_path}" local remote_path="${REMOTE_ROOT}/${rel_path}" if [[ ! -e "$local_full" ]]; then warn "路径不存在: ${local_full}" return 1 fi # 确保远程父目录存在 ssh $SSH_OPTS "$SERVER" "mkdir -p $(dirname "$remote_path")" if [[ -d "$local_full" ]]; then info "上传目录: ${rel_path}/ → ${SERVER}:${remote_path}/" scp $SCP_OPTS -r "$local_full" "${SERVER}:${remote_path}" else info "上传文件: ${rel_path} → ${SERVER}:${remote_path}" scp $SCP_OPTS "$local_full" "${SERVER}:${remote_path}" fi ok "上传完成: ${rel_path}" } # ---- 主逻辑 ---- if [[ $# -eq 0 ]]; then info "上传全部文件至 ${SERVER}:${REMOTE_ROOT}/" upload_all else for arg in "$@"; do case "$arg" in frontend|f) upload_frontend ;; backend|b) upload_backend ;; compose|c) upload_compose ;; all|a) upload_all ;; *) upload_path "$arg" ;; esac done fi echo "" info "完成!"