Files
ESP32_GDEY042T81_server/docker_deplay.sh
jeremygan2021 a1872a7a33 超级sh
2025-11-26 20:27:24 +08:00

293 lines
9.0 KiB
Bash
Executable File
Raw Permalink Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

#!/bin/bash
# =============================================================================
# Docker 镜像构建和部署自动化脚本
#
# 用法:
# ./docker_deplay.sh # 完整构建和部署流程 (默认AMD64架构)
# ./docker_deplay.sh -amd # 构建和部署AMD64架构
# ./docker_deplay.sh -arm # 构建和部署ARM64架构
# ./docker_deplay.sh -upload # 仅上传已存在的tar文件并部署
# ./docker_deplay.sh -upload -amd # 仅上传已存在的AMD64架构tar文件并部署
# ./docker_deplay.sh -upload -arm # 仅上传已存在的ARM64架构tar文件并部署
# =============================================================================
# 配置变量 - 请根据实际情况修改
SERVER_HOST="6.6.6.86" # 服务器IP地址
SERVER_USER="ubuntu" # 服务器用户名
SERVER_PASSWORD="qweasdzxc1" # 服务器密码
SERVER_PORT="22" # SSH端口默认22
IMAGE_NAME="epage_server" # Docker镜像名称
IMAGE_TAG="latest" # Docker镜像标签
CONTAINER_NAME="epage_server-container" # 容器名称
LOCAL_PORT="8199" # 本地端口
CONTAINER_PORT="8199" # 容器端口
TAR_FILE="${IMAGE_NAME}-${IMAGE_TAG}.tar" # 压缩包文件名
# 架构相关变量
PLATFORM="linux/amd64" # 默认架构
ARCH_SUFFIX="" # 架构后缀用于区分不同架构的tar文件
# 颜色输出
RED='\033[0;31m'
GREEN='\033[0;32m'
YELLOW='\033[1;33m'
BLUE='\033[0;34m'
NC='\033[0m' # No Color
# 日志函数
log_info() {
echo -e "${BLUE}[INFO]${NC} $1"
}
log_success() {
echo -e "${GREEN}[SUCCESS]${NC} $1"
}
log_warning() {
echo -e "${YELLOW}[WARNING]${NC} $1"
}
log_error() {
echo -e "${RED}[ERROR]${NC} $1"
}
# 检查依赖
check_dependencies() {
log_info "检查依赖..."
if ! command -v docker &> /dev/null; then
log_error "Docker 未安装,请先安装 Docker"
exit 1
fi
if ! command -v sshpass &> /dev/null; then
log_error "sshpass 未安装,请先安装 sshpass"
log_info "macOS: brew install sshpass"
log_info "Ubuntu: sudo apt-get install sshpass"
exit 1
fi
log_success "依赖检查完成"
}
# 解析命令行参数
parse_arguments() {
while [[ $# -gt 0 ]]; do
case $1 in
-amd)
PLATFORM="linux/amd64"
ARCH_SUFFIX="-amd64"
log_info "设置目标架构为 AMD64"
shift
;;
-arm)
PLATFORM="linux/arm64"
ARCH_SUFFIX="-arm64"
log_info "设置目标架构为 ARM64"
shift
;;
-upload)
UPLOAD_ONLY=true
log_info "设置为仅上传模式"
shift
;;
*)
log_error "未知参数: $1"
log_info "支持的参数: -amd, -arm, -upload"
exit 1
;;
esac
done
# 更新TAR_FILE名包含架构后缀
TAR_FILE="${IMAGE_NAME}-${IMAGE_TAG}${ARCH_SUFFIX}.tar"
log_info "镜像文件名: ${TAR_FILE}"
}
# 构建Docker镜像
build_image() {
log_info "开始构建 Docker 镜像..."
# 检查是否存在旧的tar文件
if [ -f "$TAR_FILE" ]; then
log_warning "发现旧的tar文件正在删除..."
rm -f "$TAR_FILE"
fi
# 构建镜像并导出为tar文件
docker buildx build --platform $PLATFORM -t "${IMAGE_NAME}:${IMAGE_TAG}" --output type=docker,dest="./${TAR_FILE}" .
if [ $? -eq 0 ]; then
log_success "Docker 镜像构建完成: ${TAR_FILE}"
else
log_error "Docker 镜像构建失败"
exit 1
fi
}
# 上传文件到服务器
upload_to_server() {
log_info "上传文件到服务器..."
sshpass -p "$SERVER_PASSWORD" scp -P "$SERVER_PORT" -o StrictHostKeyChecking=no "$TAR_FILE" "${SERVER_USER}@${SERVER_HOST}:/tmp/"
if [ $? -eq 0 ]; then
log_success "文件上传成功"
else
log_error "文件上传失败"
exit 1
fi
}
# 在服务器上部署
deploy_on_server() {
log_info "在服务器上部署..."
sshpass -p "$SERVER_PASSWORD" ssh -p "$SERVER_PORT" -o StrictHostKeyChecking=no "${SERVER_USER}@${SERVER_HOST}" << EOF
set -e
echo "[INFO] 开始服务器端部署..."
# 检查并停止现有容器
if sudo docker ps -a --format 'table {{.Names}}' | grep -q "^${CONTAINER_NAME}$"; then
echo "[INFO] 发现现有容器 ${CONTAINER_NAME},正在停止并删除..."
sudo docker stop ${CONTAINER_NAME} || true
sudo docker rm ${CONTAINER_NAME} || true
fi
# 检查并删除现有镜像
if sudo docker images --format 'table {{.Repository}}:{{.Tag}}' | grep -q "^${IMAGE_NAME}:${IMAGE_TAG}$"; then
echo "[INFO] 发现现有镜像 ${IMAGE_NAME}:${IMAGE_TAG},正在删除..."
sudo docker rmi ${IMAGE_NAME}:${IMAGE_TAG} || true
fi
# 加载新镜像
echo "[INFO] 加载新镜像..."
sudo docker load -i /tmp/${TAR_FILE}
# 验证镜像是否加载成功
if sudo docker images | grep -q "${IMAGE_NAME}"; then
echo "[SUCCESS] 镜像加载成功"
else
echo "[ERROR] 镜像加载失败"
exit 1
fi
# 运行新容器
echo "[INFO] 启动新容器..."
sudo docker run -d -p ${LOCAL_PORT}:${CONTAINER_PORT} --name ${CONTAINER_NAME} ${IMAGE_NAME}:${IMAGE_TAG}
# 验证容器是否启动成功
if sudo docker ps | grep -q "${CONTAINER_NAME}"; then
echo "[SUCCESS] 容器启动成功"
echo "[INFO] 容器状态:"
sudo docker ps | grep "${CONTAINER_NAME}"
else
echo "[ERROR] 容器启动失败"
echo "[INFO] 查看容器日志:"
sudo docker logs ${CONTAINER_NAME}
exit 1
fi
# 清理临时文件
echo "[INFO] 清理临时文件..."
rm -f /tmp/${TAR_FILE}
echo "[SUCCESS] 部署完成!"
echo "[INFO] 应用访问地址: http://${SERVER_HOST}:${LOCAL_PORT}"
EOF
if [ $? -eq 0 ]; then
log_success "服务器部署完成"
else
log_error "服务器部署失败"
exit 1
fi
}
# 清理本地文件
cleanup_local() {
log_info "清理本地临时文件..."
if [ -f "$TAR_FILE" ]; then
rm -f "$TAR_FILE"
log_success "本地临时文件已清理"
fi
}
# 显示部署信息
show_deployment_info() {
log_success "部署完成!"
echo ""
echo "=========================================="
echo "部署信息:"
echo "=========================================="
echo "服务器地址: ${SERVER_HOST}"
echo "应用端口: ${LOCAL_PORT}"
echo "访问地址: http://${SERVER_HOST}:${LOCAL_PORT}"
echo "容器名称: ${CONTAINER_NAME}"
echo "镜像名称: ${IMAGE_NAME}:${IMAGE_TAG}"
echo "目标架构: ${PLATFORM}"
echo "镜像文件: ${TAR_FILE}"
echo "=========================================="
echo ""
log_info "如需查看容器日志,请在服务器上运行: sudo docker logs ${CONTAINER_NAME}"
log_info "如需停止容器,请在服务器上运行: sudo docker stop ${CONTAINER_NAME}"
}
# 主函数
main() {
echo "=========================================="
echo "Docker 镜像构建和部署自动化脚本"
echo "=========================================="
echo ""
# 解析命令行参数
UPLOAD_ONLY=false
parse_arguments "$@"
# 检查配置
if [ "$SERVER_HOST" = "your-server-ip" ] || [ "$SERVER_PASSWORD" = "your-password" ]; then
log_error "请先配置脚本顶部的服务器信息"
log_info "需要修改的变量:"
log_info " - SERVER_HOST: 服务器IP地址"
log_info " - SERVER_USER: 服务器用户名"
log_info " - SERVER_PASSWORD: 服务器密码"
exit 1
fi
# 检查是否是上传模式
if [ "$UPLOAD_ONLY" = true ]; then
log_info "检测到 -upload 参数,跳过构建步骤"
# 检查tar文件是否存在
if [ ! -f "$TAR_FILE" ]; then
log_error "未找到tar文件: $TAR_FILE"
log_info "请先运行脚本构建镜像或确保tar文件存在"
exit 1
fi
log_success "找到tar文件: $TAR_FILE"
# 执行上传和部署流程
upload_to_server
deploy_on_server
cleanup_local
show_deployment_info
else
# 执行完整的部署流程
check_dependencies
build_image
upload_to_server
deploy_on_server
cleanup_local
show_deployment_info
fi
}
# 脚本入口
if [[ "${BASH_SOURCE[0]}" == "${0}" ]]; then
main "$@"
fi