初始提交

This commit is contained in:
jingrow 2025-08-07 21:42:25 +08:00
parent bdfc62ab9e
commit a53173e32e

519
install_jsite.sh Executable file
View File

@ -0,0 +1,519 @@
#!/bin/bash
# jsite前端自动化部署脚本
# 基于next.js + traefik开发
#
# 后端调用示例:
# 1. 基本部署: ./install_jsite.sh
# 2. 指定项目: ./install_jsite.sh -p myproject -r http://git.example.com/myproject
# 3. 跳过Docker: ./install_jsite.sh --skip-docker
# 4. 跳过Traefik: ./install_jsite.sh --skip-traefik
# 5. 强制更新: ./install_jsite.sh --force-update
# 6. 完整参数: ./install_jsite.sh -p myproject -r http://git.example.com/myproject -n 18 --skip-docker --force-update
#
# 返回码:
# 0 - 成功
# 1 - 参数错误
# 2 - 权限错误
# 3 - 其他错误
set -e # 遇到错误时退出
# 颜色定义
RED='\033[0;31m'
GREEN='\033[0;32m'
YELLOW='\033[1;33m'
BLUE='\033[0;34m'
NC='\033[0m' # No Color
# 默认参数
PROJECT_NAME="jingrow"
GIT_REPO="http://git.jingrow.com:3000/jsite/jingrow"
NODE_VERSION="22"
SKIP_DOCKER=false
SKIP_TRAEFIK=false
SKIP_DEPENDENCIES=false
FORCE_UPDATE=false
# .env文件参数
SITE_URL="http://192.168.2.200:3001"
REVALIDATE_TOKEN="535bc122f3e364c"
SITE_NAME="jingrow"
SERVER_URL="https://admin.jingrow.com"
API_KEY="535bc122f3e364c"
API_SECRET="8629a3b12fc1cc2"
# 显示帮助信息
show_help() {
echo "用法: $0 [选项]"
echo ""
echo "选项:"
echo " -p, --project-name NAME 项目名称 (默认: jingrow)"
echo " -r, --repo URL Git仓库地址"
echo " -n, --node-version VERSION Node.js版本 (默认: 22)"
echo " --skip-docker 跳过Docker安装"
echo " --skip-traefik 跳过Traefik安装和启动"
echo " --skip-dependencies 跳过项目依赖安装"
echo " --force-update 强制更新项目(如果已存在)"
echo ""
echo ".env文件配置:"
echo " --site-url URL 网站URL (默认: http://192.168.2.200:3001)"
echo " --revalidate-token TOKEN 重新验证令牌 (默认: 535bc122f3e364c)"
echo " --site-name NAME 站点名称 (默认: jingrow)"
echo " --server-url URL 服务器URL (默认: https://admin.jingrow.com)"
echo " --api-key KEY API密钥 (默认: 535bc122f3e364c)"
echo " --api-secret SECRET API密钥 (默认: 8629a3b12fc1cc2)"
echo ""
echo " -h, --help 显示此帮助信息"
echo ""
echo "示例:"
echo " $0 -p myproject -r http://git.example.com/myproject"
echo " $0 --skip-docker --skip-traefik"
echo " $0 --force-update"
echo " $0 --site-url http://example.com --site-name myproject"
}
# 解析命令行参数
parse_arguments() {
while [[ $# -gt 0 ]]; do
case $1 in
-p|--project-name)
PROJECT_NAME="$2"
shift 2
;;
-r|--repo)
GIT_REPO="$2"
shift 2
;;
-n|--node-version)
NODE_VERSION="$2"
shift 2
;;
--skip-docker)
SKIP_DOCKER=true
shift
;;
--skip-traefik)
SKIP_TRAEFIK=true
shift
;;
--skip-dependencies)
SKIP_DEPENDENCIES=true
shift
;;
--force-update)
FORCE_UPDATE=true
shift
;;
--site-url)
SITE_URL="$2"
shift 2
;;
--revalidate-token)
REVALIDATE_TOKEN="$2"
shift 2
;;
--site-name)
SITE_NAME="$2"
shift 2
;;
--server-url)
SERVER_URL="$2"
shift 2
;;
--api-key)
API_KEY="$2"
shift 2
;;
--api-secret)
API_SECRET="$2"
shift 2
;;
-h|--help)
show_help
exit 0
;;
*)
echo -e "${RED}[ERROR]${NC} 未知参数: $1"
show_help
exit 1
;;
esac
done
}
# 日志函数
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"
}
# 检查是否为root用户
check_root() {
if [[ $EUID -eq 0 ]]; then
log_info "以root用户身份运行脚本"
else
log_error "请以root用户身份运行此脚本"
exit 1
fi
}
# 1. 创建jingrow用户
create_jingrow_user() {
log_info "开始创建jingrow用户..."
if id "jingrow" &>/dev/null; then
log_warning "用户jingrow已存在"
else
useradd -m -s /bin/bash jingrow
log_success "用户jingrow创建成功"
fi
# 确保home目录存在
if [ ! -d "/home/jingrow" ]; then
mkdir -p /home/jingrow
chown jingrow:jingrow /home/jingrow
log_success "创建/home/jingrow目录"
fi
}
# 2. 安装nvm和node.js
install_nodejs() {
log_info "开始安装nvm和node.js..."
# 切换到jingrow用户目录
cd /home/jingrow
# 下载并安装nvm
if [ ! -d "/home/jingrow/.nvm" ]; then
log_info "下载并安装nvm..."
su - jingrow -c "curl -o- https://raw.githubusercontent.com/nvm-sh/nvm/v0.40.3/install.sh | bash"
log_success "nvm安装完成"
else
log_warning "nvm已存在"
fi
# 加载nvm并安装node.js
log_info "安装Node.js v$NODE_VERSION..."
su - jingrow -c "
export NVM_DIR=\"\$HOME/.nvm\"
[ -s \"\$NVM_DIR/nvm.sh\" ] && \. \"\$NVM_DIR/nvm.sh\"
nvm install $NODE_VERSION
nvm use $NODE_VERSION
nvm alias default $NODE_VERSION
"
# 验证安装
NODE_VERSION_OUTPUT=$(su - jingrow -c 'export NVM_DIR="$HOME/.nvm" && [ -s "$NVM_DIR/nvm.sh" ] && \. "$NVM_DIR/nvm.sh" && node -v')
NPM_VERSION=$(su - jingrow -c 'export NVM_DIR="$HOME/.nvm" && [ -s "$NVM_DIR/nvm.sh" ] && \. "$NVM_DIR/nvm.sh" && npm -v')
log_success "Node.js版本: $NODE_VERSION_OUTPUT"
log_success "npm版本: $NPM_VERSION"
}
# 3. 克隆jsite项目
clone_jsite_project() {
log_info "开始克隆jsite项目: $PROJECT_NAME..."
cd /home/jingrow
# 创建jsite目录如果不存在
if [ ! -d "/home/jingrow/jsite" ]; then
mkdir -p /home/jingrow/jsite
chown jingrow:jingrow /home/jingrow/jsite
log_success "创建jsite目录"
fi
# 检查项目子目录是否已存在
if [ -d "/home/jingrow/jsite/$PROJECT_NAME" ]; then
if [ "$FORCE_UPDATE" = true ]; then
log_warning "项目目录已存在,强制更新..."
rm -rf "/home/jingrow/jsite/$PROJECT_NAME"
cd /home/jingrow/jsite
su - jingrow -c "cd /home/jingrow/jsite && git clone $GIT_REPO $PROJECT_NAME"
log_success "jsite/$PROJECT_NAME项目更新完成"
else
log_warning "jsite/$PROJECT_NAME目录已存在,跳过克隆"
fi
else
cd /home/jingrow/jsite
su - jingrow -c "cd /home/jingrow/jsite && git clone $GIT_REPO $PROJECT_NAME"
log_success "jsite/$PROJECT_NAME项目克隆完成"
fi
}
# 4. 创建.env文件
create_env_file() {
log_info "创建.env文件..."
cd /home/jingrow/jsite/$PROJECT_NAME
# 检查.env文件是否已存在
if [ -f "/home/jingrow/jsite/$PROJECT_NAME/.env" ]; then
if [ "$FORCE_UPDATE" = true ]; then
log_warning ".env文件已存在强制更新..."
else
log_warning ".env文件已存在跳过创建"
return
fi
fi
# 创建.env文件
cat > "/home/jingrow/jsite/$PROJECT_NAME/.env" << EOF
PUBLIC_SITE_URL=$SITE_URL
REVALIDATE_TOKEN=$REVALIDATE_TOKEN
JINGROW_SITE_NAME=$SITE_NAME
JINGROW_SERVER_URL=$SERVER_URL
JINGROW_API_KEY=$API_KEY
JINGROW_API_SECRET=$API_SECRET
EOF
# 设置文件权限
chown jingrow:jingrow "/home/jingrow/jsite/$PROJECT_NAME/.env"
chmod 600 "/home/jingrow/jsite/$PROJECT_NAME/.env"
log_success ".env文件创建完成"
}
# 5. 安装traefik
install_traefik() {
log_info "开始安装traefik..."
cd /home/jingrow
# 创建traefik目录结构
if [ ! -d "/home/jingrow/traefik" ]; then
mkdir -p /home/jingrow/traefik/conf.d
log_success "创建traefik目录结构"
fi
# 创建acme.json文件
if [ ! -f "/home/jingrow/traefik/acme.json" ]; then
touch /home/jingrow/traefik/acme.json
chmod 600 /home/jingrow/traefik/acme.json
log_success "创建acme.json文件"
fi
# 创建traefik.yml配置文件
cat > /home/jingrow/traefik/traefik.yml << 'EOF'
entryPoints:
web:
address: ":80"
websecure:
address: ":443"
api:
dashboard: true
insecure: true # 生产环境建议关闭
providers:
docker:
exposedByDefault: false
file:
directory: /etc/traefik/conf.d
watch: true
certificatesResolvers:
myresolver:
acme:
email: support@jingrow.com
storage: acme.json
httpChallenge:
entryPoint: web
EOF
log_success "创建traefik.yml配置文件"
# 创建docker-compose.yml文件
cat > /home/jingrow/traefik/docker-compose.yml << 'EOF'
services:
traefik:
# The official v3 Traefik docker image
image: traefik:v3.4
container_name: traefik
restart: always
# Enables the web UI and tells Traefik to listen to docker
command: --api.insecure=true --providers.docker
ports:
# The HTTP port
- "80:80"
- "443:443"
# The Web UI (enabled by --api.insecure=true)
- "8080:8080"
volumes:
# So that Traefik can listen to the Docker events
- /var/run/docker.sock:/var/run/docker.sock
- ./traefik.yml:/etc/traefik/traefik.yml:ro
- ./conf.d:/etc/traefik/conf.d:ro
- ./acme.json:/etc/traefik/acme.json
EOF
log_success "创建docker-compose.yml文件"
# 设置目录权限
chown -R jingrow:jingrow /home/jingrow/traefik
log_success "设置traefik目录权限"
}
# 6. 安装Docker如果未安装
install_docker() {
log_info "检查Docker安装状态..."
if command -v docker &> /dev/null; then
log_warning "Docker已安装"
else
log_info "开始安装Docker..."
# 更新包索引
apt-get update
# 安装必要的包
apt-get install -y apt-transport-https ca-certificates curl gnupg lsb-release
# 添加Docker官方GPG密钥
curl -fsSL https://download.docker.com/linux/ubuntu/gpg | gpg --dearmor -o /usr/share/keyrings/docker-archive-keyring.gpg
# 设置稳定版仓库
echo "deb [arch=amd64 signed-by=/usr/share/keyrings/docker-archive-keyring.gpg] https://download.docker.com/linux/ubuntu $(lsb_release -cs) stable" | tee /etc/apt/sources.list.d/docker.list > /dev/null
# 更新包索引
apt-get update
# 安装Docker Engine
apt-get install -y docker-ce docker-ce-cli containerd.io docker-compose-plugin
# 启动Docker服务
systemctl start docker
systemctl enable docker
log_success "Docker安装完成"
fi
# 将jingrow用户添加到docker组
usermod -aG docker jingrow
log_success "将jingrow用户添加到docker组"
}
# 7. 启动traefik
start_traefik() {
log_info "启动traefik服务..."
cd /home/jingrow/traefik
# 使用jingrow用户启动traefik
su - jingrow -c "cd /home/jingrow/traefik && docker compose up -d"
log_success "traefik服务启动完成"
}
# 8. 安装项目依赖
install_project_dependencies() {
log_info "安装jsite/$PROJECT_NAME项目依赖..."
cd /home/jingrow/jsite/$PROJECT_NAME
su - jingrow -c "
export NVM_DIR=\"\$HOME/.nvm\"
[ -s \"\$NVM_DIR/nvm.sh\" ] && \. \"\$NVM_DIR/nvm.sh\"
cd /home/jingrow/jsite/$PROJECT_NAME
npm install
"
log_success "项目依赖安装完成"
}
# 9. 显示部署信息
show_deployment_info() {
log_success "=== 部署完成 ==="
echo ""
log_info "部署信息:"
echo " - 用户: jingrow"
echo " - jsite目录: /home/jingrow/jsite"
echo " - 项目目录: /home/jingrow/jsite/$PROJECT_NAME"
echo " - Traefik目录: /home/jingrow/traefik"
echo " - Traefik管理界面: http://localhost:8080"
echo ""
log_info ".env文件配置"
echo " - PUBLIC_SITE_URL: $SITE_URL"
echo " - JINGROW_SITE_NAME: $SITE_NAME"
echo " - JINGROW_SERVER_URL: $SERVER_URL"
echo " - REVALIDATE_TOKEN: $REVALIDATE_TOKEN"
echo " - JINGROW_API_KEY: $API_KEY"
echo " - JINGROW_API_SECRET: $API_SECRET"
echo ""
log_info "下一步操作:"
echo " 1. 进入项目目录: cd /home/jingrow/jsite/$PROJECT_NAME"
echo " 2. 启动开发服务器: npm run dev"
echo " 3. 访问Traefik管理界面: http://localhost:8080"
echo ""
log_warning "注意请确保防火墙允许80、443、8080端口访问"
}
# 主函数
main() {
log_info "开始jsite前端自动化部署..."
echo ""
log_info "部署参数:"
echo " - 项目名称: $PROJECT_NAME"
echo " - Git仓库: $GIT_REPO"
echo " - Node.js版本: $NODE_VERSION"
echo " - 跳过Docker: $SKIP_DOCKER"
echo " - 跳过Traefik: $SKIP_TRAEFIK"
echo " - 跳过依赖安装: $SKIP_DEPENDENCIES"
echo " - 强制更新: $FORCE_UPDATE"
echo ""
log_info ".env文件参数:"
echo " - 网站URL: $SITE_URL"
echo " - 站点名称: $SITE_NAME"
echo " - 服务器URL: $SERVER_URL"
echo " - 重新验证令牌: $REVALIDATE_TOKEN"
echo " - API密钥: $API_KEY"
echo " - API密钥: $API_SECRET"
echo ""
check_root
create_jingrow_user
if [ "$SKIP_DOCKER" = false ]; then
install_docker
else
log_warning "跳过Docker安装"
fi
install_nodejs
clone_jsite_project
create_env_file
if [ "$SKIP_TRAEFIK" = false ]; then
install_traefik
start_traefik
else
log_warning "跳过Traefik安装和启动"
fi
if [ "$SKIP_DEPENDENCIES" = false ]; then
install_project_dependencies
else
log_warning "跳过项目依赖安装"
fi
show_deployment_info
log_success "部署脚本执行完成!"
}
# 执行主函数
parse_arguments "$@"
main "$@"