Files
dock/OpenList
2025-11-18 10:22:48 +08:00

320 lines
9.1 KiB
Bash
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
# OpenList Docker 一键部署脚本(带自动密码检测)
# 版本1.3 - 在原有成功脚本基础上添加密码自动处理
set -e # 任何命令失败则立即退出脚本
# 全局变量
CONTAINER_NAME="openlist"
DATA_DIR="/data/openlist"
IMAGE_NAME="openlistteam/openlist:latest"
DEFAULT_PORT=5344
PORT_MAPPING=""
# 颜色输出函数
red() { echo -e "\033[31m$1\033[0m"; }
green() { echo -e "\033[32m$1\033[0m"; }
yellow() { echo -e "\033[33m$1\033[0m"; }
blue() { echo -e "\033[34m$1\033[0m"; }
# 错误退出函数
error_exit() {
red "❌ 错误:$1"
exit 1
}
# 检查 Docker 是否可用
check_docker() {
blue "🔍 检查 Docker 环境..."
if ! command -v docker &> /dev/null; then
error_exit "未检测到 Docker请先安装 Docker"
fi
if ! docker info &> /dev/null; then
error_exit "Docker 服务未运行,请启动 Docker 服务"
fi
green "✅ Docker 环境检查通过"
}
# 准备数据目录
prepare_directory() {
blue "📁 准备数据目录..."
# 创建 /data 目录(如果不存在)
if [ ! -d "/data" ]; then
yellow "创建 /data 目录..."
sudo mkdir -p /data || error_exit "创建 /data 目录失败"
sudo chmod 755 /data || error_exit "设置 /data 权限失败"
fi
# 创建 OpenList 数据目录
if [ ! -d "$DATA_DIR" ]; then
yellow "创建 OpenList 数据目录: $DATA_DIR"
sudo mkdir -p "$DATA_DIR" || error_exit "创建数据目录失败"
fi
# 设置正确的目录权限
blue "🔧 设置目录权限..."
sudo chown -R 1000:1000 "$DATA_DIR" || error_exit "设置目录所有权失败"
sudo chmod -R 755 "$DATA_DIR" || error_exit "设置目录权限失败"
# 验证权限设置
if [ -w "$DATA_DIR" ] && [ -x "$DATA_DIR" ]; then
green "✅ 目录权限验证通过"
else
error_exit "目录权限设置失败,请手动检查权限"
fi
green "✅ 数据目录准备完成"
}
# 清理现有容器
cleanup_existing_container() {
blue "🧹 检查现有容器..."
if docker ps -a --filter "name=$CONTAINER_NAME" --format "{{.Names}}" | grep -q "$CONTAINER_NAME"; then
yellow "发现已存在的 OpenList 容器,正在清理..."
docker stop "$CONTAINER_NAME" >/dev/null 2>&1 || true
docker rm "$CONTAINER_NAME" >/dev/null 2>&1 || true
green "✅ 旧容器清理完成"
else
green "✅ 无现有容器需要清理"
fi
}
# 检查端口占用
check_port() {
local port=$1
blue "🔍 检查端口 $port 占用情况..."
if command -v ss &> /dev/null; then
if ss -tuln | grep ":$port " > /dev/null; then
return 1
fi
else
if netstat -tuln | grep ":$port " > /dev/null; then
return 1
fi
fi
green "✅ 端口 $port 可用"
return 0
}
# 获取可用端口
get_available_port() {
local port=$DEFAULT_PORT
local max_port=6000
while [ $port -le $max_port ]; do
if check_port $port; then
echo $port
return 0
fi
port=$((port + 1))
done
error_exit "$DEFAULT_PORT-$max_port 范围内找不到可用端口"
}
# 拉取 OpenList 镜像
pull_openlist_image() {
blue "📦 拉取 OpenList 镜像..."
if docker pull "$IMAGE_NAME"; then
green "✅ OpenList 镜像拉取完成"
else
error_exit "拉取 OpenList 镜像失败,请检查网络连接"
fi
}
# 部署 OpenList 容器(使用特权模式解决权限问题)
deploy_openlist() {
blue "🚀 开始部署 OpenList 容器..."
# 确定使用的端口
if check_port $DEFAULT_PORT; then
PORT_MAPPING="$DEFAULT_PORT:5244"
green "✅ 使用默认端口:$DEFAULT_PORT"
else
local available_port=$(get_available_port)
PORT_MAPPING="$available_port:5244"
yellow "📊 使用端口:$available_port (原端口 $DEFAULT_PORT 被占用)"
fi
# 部署命令(使用特权模式解决权限问题)
blue "🐳 启动容器..."
if docker run -d \
--name "$CONTAINER_NAME" \
--restart=unless-stopped \
--privileged \
--user root \
-p "$PORT_MAPPING" \
-v "$DATA_DIR:/opt/openlist/data" \
-v /var/run/docker.sock:/var/run/docker.sock \
-e PUID=0 \
-e PGID=0 \
-e UMASK=000 \
-e TZ=Asia/Shanghai \
"$IMAGE_NAME"; then
green "✅ OpenList 容器部署成功"
else
error_exit "OpenList 容器启动失败"
fi
}
# === 新增功能:密码检测和自动重置 ===
# 生成随机密码
generate_random_password() {
tr -dc 'A-Za-z0-9' < /dev/urandom | head -c 12
echo
}
# 检测并获取密码
detect_and_get_password() {
blue "🔍 检测密码生成情况..."
local max_attempts=10
local attempt=1
local password=""
while [ $attempt -le $max_attempts ]; do
yellow "尝试检测密码 ($attempt/$max_attempts)..."
sleep 3
# 检查容器日志获取密码
local logs=$(docker logs "$CONTAINER_NAME" 2>&1 | tail -10)
# 尝试提取密码
password=$(echo "$logs" | grep -o "initial password is: [[:alnum:]]*" | awk '{print $4}' | tail -1)
if [ -n "$password" ]; then
green "✅ 检测到自动生成的密码"
echo "$password"
return 0
fi
# 检查是否启动成功但没有新密码(使用现有配置)
if echo "$logs" | grep -q "HTTP server"; then
yellow "⚠️ 使用现有配置,无新密码生成"
# 返回空字符串表示使用现有配置
echo ""
return 0
fi
attempt=$((attempt + 1))
done
# 如果检测不到密码,生成随机密码并重置
yellow "⚠️ 未检测到密码生成,执行自动重置..."
auto_reset_password
}
# 自动重置密码
auto_reset_password() {
blue "🔄 自动重置密码..."
# 停止容器
docker stop "$CONTAINER_NAME" 2>/dev/null || true
# 删除配置文件以触发新密码生成
yellow "删除现有配置..."
sudo rm -f "$DATA_DIR/config.json" 2>/dev/null || true
sudo rm -f "$DATA_DIR"/*.db 2>/dev/null || true
# 重启容器
yellow "重启容器生成新密码..."
docker start "$CONTAINER_NAME" 2>/dev/null || {
yellow "容器启动失败,重新部署..."
deploy_openlist
}
# 等待并再次检测密码
sleep 8
detect_and_get_password
}
# 验证部署状态
verify_deployment() {
blue "🔍 验证容器运行状态..."
local max_attempts=15
local attempt=1
while [ $attempt -le $max_attempts ]; do
yellow "⏳ 等待容器启动 ($attempt/$max_attempts)..."
sleep 3
# 检查容器状态
if docker ps --filter "name=$CONTAINER_NAME" --filter "status=running" --format "{{.Names}}" | grep -q "$CONTAINER_NAME"; then
green "✅ 容器正在运行"
# 检测并获取密码
PASSWORD=$(detect_and_get_password)
return 0
fi
attempt=$((attempt + 1))
done
red "❌ 容器启动超时"
blue "📋 容器日志:"
docker logs "$CONTAINER_NAME" | tail -20
error_exit "容器启动失败,请检查上方日志"
}
# 显示部署成功信息
show_success_info() {
local port=$(echo "$PORT_MAPPING" | cut -d':' -f1)
local ip_address=$(hostname -I | awk '{print $1}' | head -n1)
echo ""
green "🎉 OpenList 部署成功!"
echo "=========================================="
blue "📋 访问信息:"
echo " 🌐 访问地址http://$ip_address:$port"
echo " 🏠 本地访问http://localhost:$port"
echo " 📁 数据目录:$DATA_DIR"
echo ""
blue "🔐 登录信息:"
echo " 用户名admin"
if [ -n "$PASSWORD" ]; then
echo " 密码:$PASSWORD"
yellow "💡 首次登录后请立即修改密码!"
else
echo " 密码:使用之前设置的密码"
echo " 🔄 如需重置:删除 $DATA_DIR/config.json 并重启容器"
fi
echo ""
blue "⚡ 常用命令:"
echo " 📜 查看日志docker logs $CONTAINER_NAME"
echo " 🔄 重启容器docker restart $CONTAINER_NAME"
echo " ⏹️ 停止容器docker stop $CONTAINER_NAME"
echo " 🚀 启动容器docker start $CONTAINER_NAME"
}
# 主执行流程
main() {
echo "=========================================="
green " OpenList Docker 一键部署脚本"
yellow " (带自动密码检测功能)"
echo "=========================================="
check_docker
prepare_directory
cleanup_existing_container
pull_openlist_image
deploy_openlist
verify_deployment
show_success_info
echo ""
green "✅ 部署流程完成!"
}
# 执行主函数(捕获中断信号)
trap 'echo; red "⚠️ 操作被用户中断"; exit 1' INT
main "$@"