#!/usr/bin/env bash set -euo pipefail REMOTE_DIR="/data/project/app-api" show_help() { cat <<'EOF' 用法: deploy.sh [选项] [服务器] 本地交叉编译后上传二进制到服务器。 选项: -a 同时上传 Dockerfile 和 docker-compose.yml -r 上传后 SSH 到服务器执行 docker compose up -d --build 重启容器 -s 跳过编译,直接使用已编译好的 bin/server-linux -n 虚拟执行,不实际传输文件 -h, --help 显示此帮助信息 服务器: api1 仅部署到 api1 (luxsin-api1) api2 仅部署到 api2 (luxsin-api2) (省略) 同时部署到 api1 和 api2 默认行为: 1. 本地执行 make build-linux 交叉编译 2. 上传编译好的二进制到服务器 示例: deploy.sh 编译并上传二进制到 api1 和 api2 deploy.sh api1 编译并上传二进制到 api1 deploy.sh -s api1 跳过编译,直接上传已有二进制到 api1 deploy.sh -a api1 同时上传 Dockerfile + docker-compose.yml 到 api1 deploy.sh -r 编译、上传二进制并重启容器 deploy.sh -s -r api1 跳过编译,上传已有二进制并重启 deploy.sh -a -r api1 全量部署到 api1(含 Docker 文件 + 重启) deploy.sh -n api1 虚拟执行,预览部署到 api1 EOF } remote_host_for() { case "$1" in api1) echo "luxsin-api1" ;; api2) echo "luxsin-api2" ;; *) echo "未知服务器: $1(可选: api1, api2)" >&2 exit 1 ;; esac } UPLOAD_ALL=false RESTART=false SKIP_BUILD=false DRY_RUN=false ARGS=() for arg in "$@"; do case "$arg" in -a) UPLOAD_ALL=true ;; -r) RESTART=true ;; -s) SKIP_BUILD=true ;; -n) DRY_RUN=true ;; -h|--help) show_help exit 0 ;; *) ARGS+=("$arg") ;; esac done SERVERS=() if [ ${#ARGS[@]} -gt 0 ] && { [ "${ARGS[0]}" = "api1" ] || [ "${ARGS[0]}" = "api2" ]; }; then SERVERS=("${ARGS[0]}") else SERVERS=(api1 api2) fi if [ "$SKIP_BUILD" = true ]; then echo "=== 跳过编译,使用已有二进制 ===" if [ ! -f bin/server-linux ]; then echo "错误: bin/server-linux 不存在,请先编译" >&2 exit 1 fi echo " 文件: bin/server-linux ($(du -h bin/server-linux | cut -f1))" else echo "=== 本地编译 ===" if [ "$DRY_RUN" = true ]; then echo "(虚拟) make build-linux" else make build-linux fi fi echo rsync_opts=(-avz --progress) if [ "$DRY_RUN" = true ]; then rsync_opts+=(-n) fi for server in "${SERVERS[@]}"; do remote_host="$(remote_host_for "$server")" if [ "$DRY_RUN" = true ]; then echo "=== 虚拟部署到 ${server} (${remote_host}) ===" else echo "=== 部署到 ${server} (${remote_host}) ===" fi echo " 上传二进制: bin/server-linux -> ${remote_host}:${REMOTE_DIR}/server" rsync "${rsync_opts[@]}" bin/server-linux "${remote_host}:${REMOTE_DIR}/server" if [ "$UPLOAD_ALL" = true ]; then echo " 上传 Dockerfile -> ${remote_host}:${REMOTE_DIR}/Dockerfile" rsync "${rsync_opts[@]}" Dockerfile "${remote_host}:${REMOTE_DIR}/Dockerfile" echo " 上传 docker-compose.yml -> ${remote_host}:${REMOTE_DIR}/docker-compose.yml" rsync "${rsync_opts[@]}" docker-compose.yml "${remote_host}:${REMOTE_DIR}/docker-compose.yml" fi if [ "$RESTART" = true ]; then if [ "$DRY_RUN" = true ]; then echo " (虚拟) SSH 重启容器: docker compose up -d --build" else echo " SSH 重启容器 ..." ssh "$remote_host" "cd ${REMOTE_DIR} && docker compose up -d --build" fi fi echo done echo "完成。"