初始化离线安装docker、1panel

This commit is contained in:
yuejiajun 2025-09-16 11:54:39 +08:00
commit 9de26dbb2e
53 changed files with 465 additions and 0 deletions

97
Readme.md Normal file
View File

@ -0,0 +1,97 @@
# Linux一键安装工具
## 项目介绍
这是一个用于在 Linux 系统上一键安装和部署多种常用容器化应用的工具。通过运行单个脚本,用户可以快速搭建完整的开发或生产环境,包括 Docker、1Panel 控制面板以及各种常用服务(如 MySQL、Redis、MinIO、RocketMQ 等)。
## 系统要求
- 操作系统:支持 x86_64 架构的 Linux 系统
- 权限要求:必须以 root 用户权限运行
- 磁盘空间:至少需要 10GB 可用空间
- 内存:建议 4GB 以上内存
## 项目结构
```
├── Readme.md # 项目说明文档
├── install.sh # 主安装脚本
├── busicess_resources/ # 业务资源目录
│ ├── containers/ # 容器镜像 tar 文件
│ └── dataset/ # 应用数据集和配置文件
└── offline_resources/ # 离线资源目录
├── 1panel/ # 1Panel 控制面板安装包
├── debs/ # Debian 系统依赖包
└── docker-compose/ # Docker Compose 工具
```
## 包含的组件
### 基础组件
- **Docker**:容器化运行环境
- **Docker Compose**:多容器管理工具
- **1Panel**Linux 服务器管理面板
### 应用容器
- **MySQL 8.4.3**:关系型数据库
- **Redis 7.4.1**:高性能缓存数据库
- **MinIO**:对象存储服务
- **Nginx**Web 服务器和反向代理
- **RocketMQ 5.3.1**:分布式消息中间件
- **Portainer CE 2.28.1**Docker 容器管理界面
- **phpMyAdmin 5.2.2**MySQL 数据库管理工具
- **Amazon Corretto 21**Java 运行环境
- **实验系统**simulation-manager-mysql v2.0.184 和 simulation-ui v2.0.145
## 使用方法
### 1. 准备工作
确保已下载完整的项目文件,包括所有资源目录和安装脚本。
### 2. 赋予执行权限
打开终端,进入项目目录,执行以下命令:
```bash
# 如果被压缩成一个 .tar.gz 包
# tar zxvf install.tar.gz
# 赋权
chmod u+x install.sh
```
### 3. 运行安装脚本
以 root 用户身份运行安装脚本:
```bash
sudo ./install.sh
```
### 4. 安装过程
安装脚本会自动执行以下步骤:
- 检查系统环境和权限
- 安装 Docker 和 Docker Compose
- 安装 1Panel 控制面板
- 加载所有容器镜像
- 创建 Docker 网络
- 安装和配置各个应用容器
### 5. 验证安装
安装完成后,脚本会显示各组件的版本信息和状态。可以通过以下方式验证安装结果:
- **访问 1Panel**:打开浏览器,输入服务器 IP 地址和 1Panel 端口(默认 10086
- **查看 Docker 容器**:执行 `docker ps` 命令查看正在运行的容器
## 注意事项
1. 脚本必须以 root 权限运行
2. 目前仅支持 x86_64 架构的 Linux 系统
3. 确保 `offline_resources` 目录与脚本在同一位置,且包含所有必需的安装包
4. 安装过程可能需要一定时间,取决于系统性能(离线安装,不考虑网络状况)
5. 如果已安装 Docker 或 1Panel脚本会跳过相应的安装步骤
## 更新日志
- **v1.0.0**:初始版本,支持一键安装 Docker、1Panel 和多种常用容器应用
## 免责声明
本工具仅供学习和测试使用,在生产环境中使用前请**进行充分测试**。对于使用本工具可能导致的任何损失,作者不承担任何责任。

368
install.sh Normal file
View File

@ -0,0 +1,368 @@
#!/bin/bash
set -e
# =========================================== 基础检查与更新 ===========================================
SCRIPT_PATH=`pwd`
function check() {
if [ "$(id -u)" -ne 0 ]; then
echo "请以root权限运行此脚本" >&2
exit 1
fi
osCheck=`uname -a`
if [[ $osCheck =~ 'x86_64' ]];then
architecture="amd64"
else
echo "暂不支持的系统架构,选择受支持的系统。"
exit 1
fi
if [ ! -d "offline_resources" ]; then
echo "未找到资源目录请确保offline_resources目录与脚本在同一位置" >&2
exit 1
fi
}
function upgrade() {
echo "更新系统源"
sudo apt update -y
sudo apt upgrade -y
}
# =========================================== Docker与1Panel ===========================================
function check_docker_installed() {
if command -v docker &> /dev/null; then
echo "Docker 已安装,版本: $(docker --version)"
return 0
else
echo "Docker 未安装"
return 1
fi
}
function check_1panel_installed() {
if systemctl status 1panel-core &> /dev/null; then
echo "1Panel 已安装,状态: $(systemctl is-active 1panel-core)"
return 0
else
echo "1Panel 未安装"
return 1
fi
}
function install_docker() {
if check_docker_installed; then
echo "Docker 已经安装,跳过安装步骤"
return 0
fi
echo && echo "正在安装依赖包和Docker..." && echo
dpkg -i debs/*.deb || apt-get -f install -y
echo && echo "启动Docker服务..." && echo
systemctl start docker
systemctl enable docker
echo && echo "安装Docker Compose..." && echo
cp docker-compose/`ls docker-compose/ | grep docker-compose | head -n 1` /usr/local/bin/docker-compose
chmod +x /usr/local/bin/docker-compose
if check_docker_installed; then
echo "Docker 安装成功!"
else
echo "Docker 安装失败!" >&2
exit 1
fi
}
function install_1panel() {
if check_1panel_installed; then
echo "1Panel 已经安装,跳过安装步骤"
return 0
fi
echo && echo "安装1Panel..." && echo
panel_package=$(ls 1panel | grep -G '1panel-v.*\.tar\.gz' | head -n 1)
if [ -z "${panel_package}" ]; then
echo "未找到1Panel安装包" >&2
exit 1
fi
tar -zxvf "1panel/${panel_package}" -C 1panel
panel_dir=$(ls -l 1panel | grep '^d' | grep 1panel | awk '{print $NF}' | head -n 1)
if [ -z "$panel_dir" ]; then
echo "未找到1Panel解压目录" >&2
exit 1
fi
chmod u+x "./1panel/$panel_dir/install.sh"
sudo "./1panel/$panel_dir/install.sh"
sleep 3
if check_1panel_installed; then
echo "1Panel 安装成功!"
else
echo "1Panel 安装失败!" >&2
exit 1
fi
}
# =========================================== 通用函数处理 ===========================================
# 主函数:空处理
function process_empty() {
return 0
}
# 主函数处理tar文件并执行指定函数
function process_tar_files() {
local resource_dir="$1"
local process_function="$2"
local file_patterns=("${@:3}")
if [ ${#file_patterns[@]} -eq 0 ]; then
file_patterns=("*.tar")
fi
if [ ! -d "$resource_dir" ]; then
echo "错误: 目录 $resource_dir 不存在"
return 1
fi
if ! declare -f "$process_function" > /dev/null; then
echo "错误: 函数 $process_function 未定义"
return 1
fi
local file_count=0
local success_count=0
local fail_count=0
echo "开始在目录 $resource_dir 中查找文件..."
for pattern in "${file_patterns[@]}"; do
echo "搜索模式: $pattern"
for tar_file in "$resource_dir"/$pattern; do
filename=$(basename "$tar_file")
"$process_function" "$tar_file" "${filename}"
file_count=$((file_count + 1))
done
done
echo "=== 处理完成 ==="
echo "总共找到: $file_count 个文件"
echo "成功: $success_count"
echo "失败: $fail_count"
if [ $file_count -eq 0 ]; then
echo "在目录 $resource_dir 中未找到以下模式的文件: ${file_patterns[*]}"
echo "目录内容:"
ls -la "$resource_dir/" 2>/dev/null || echo "无法列出目录内容"
fi
return $fail_count
}
# 处理关联数组的函数
function process_associative_array() {
# arg1: 默认路径
# arg2: 执行数组
# arg3: 自定义初始化函数
local path="$1"
local array_name="$2"
local func_name="$3"
eval "local keys=(\"\${!${array_name}[@]}\")"
for key in "${keys[@]}"; do
eval "local value=\"\${${array_name}[\$key]}\""
name=$(echo "${key}" | awk -F. '{if (NF>1) {for(i=1;i<NF;i++) printf "%s%s", $i, (i<NF-1?".":"")}}')
"${func_name}" "${path}/${name}" "${key}" "${value}"
done
}
# =========================================== 部署容器 ===========================================
function docker_load_tar() {
# arg1 加载的镜像文件名称
# arg2 镜像描述
SOURCE_FILE=$1
SOURCE_DESCRIPTION=$2
echo "加载 ${SOURCE_DESCRIPTION} 镜像"
docker load -i ${SOURCE_FILE} || { echo "加载 ${SOURCE_DESCRIPTION} 镜像失败"; exit 1; }
}
function docker_installer() {
# arg1: 安装到 1panel 的程序目录
# arg2: 迁移到 1panel 程序目录的压缩文件
# arg3: 自定义初始化函数(可选)
local TARGET_DIR="${1}"
local SOURCE_FILE="${2}"
local CUSTOM_INIT_FUNC="${3}"
local SOURCE_PATH=$(pwd)
local DEFAULT_DOCKER_COMPOSE="docker-compose.yml"
local TIMESTAMP=$(date +%Y%m%d_%H%M%S)
local BACKUP_DIR="${TARGET_DIR}_backup_${TIMESTAMP}"
if [ $# -lt 2 ]; then
echo "错误:缺少必要参数"
echo "用法: docker_installer <目标目录> <源压缩文件> [自定义初始化函数]"
return 1
fi
if [ ! -f "${SOURCE_FILE}" ] || [ ! -r "${SOURCE_FILE}" ]; then
echo "错误:源文件 ${SOURCE_FILE} 不存在或不可读"
return 1
fi
if [ ! -d "${TARGET_DIR}" ]; then
echo "目录 ${TARGET_DIR} 不存在,尝试创建..."
mkdir -p "${TARGET_DIR}" || {
echo "无法创建目录 ${TARGET_DIR}"
return 1
}
fi
echo "复制文件到 ${TARGET_DIR}"
cp "${SOURCE_FILE}" "${TARGET_DIR}/" || {
echo "复制文件失败"
return 1
}
cd "${TARGET_DIR}" || {
echo "无法进入目录 ${TARGET_DIR}"
return 1
}
local FILENAME=$(basename "${SOURCE_FILE}")
echo "开始解压 ${FILENAME}"
case "${FILENAME##*.}" in
zip)
unzip -q "${FILENAME}" || {
echo "解压 ${FILENAME} 失败"
return 1
}
;;
tar|gz|tgz|bz2)
tar -xf "${FILENAME}" || {
echo "解压 ${FILENAME} 失败"
return 1
}
;;
*)
echo "不支持的压缩格式: ${FILENAME##*.}"
return 1
;;
esac
rm -f "${FILENAME}"
if [ -n "${CUSTOM_INIT_FUNC}" ]; then
if type "${CUSTOM_INIT_FUNC}" &>/dev/null; then
echo "执行自定义初始化函数 ${CUSTOM_INIT_FUNC}"
${CUSTOM_INIT_FUNC} || {
echo "自定义初始化函数执行失败"
return 1
}
else
echo "警告:初始化函数 ${CUSTOM_INIT_FUNC} 不存在,跳过"
fi
fi
local COMPOSE_FILE="${DEFAULT_DOCKER_COMPOSE}"
if [ -f "${COMPOSE_FILE}" ]; then
echo "${TARGET_DIR} 下启动 Docker Compose"
if ! command -v docker-compose &>/dev/null; then
echo "错误docker-compose 未安装"
return 1
fi
if ! docker info &>/dev/null; then
echo "错误Docker 守护进程未运行"
return 1
fi
docker-compose up -d || {
echo "Docker Compose 启动失败"
return 1
}
echo "Docker Compose 启动成功"
else
echo "${TARGET_DIR} 下未找到 ${COMPOSE_FILE}"
echo "可用文件:"
ls -la
return 1
fi
cd "${SOURCE_PATH}" >/dev/null
echo && echo "操作完成" && echo
echo "目标目录: ${TARGET_DIR}"
if [ -d "${BACKUP_DIR}" ]; then
echo "备份位置: ${BACKUP_DIR}"
fi
}
# =========================================== 特殊初始化 ===========================================
function init_rocketmq() {
cd rocketmq
sh scripts/init.sh || { echo "初始化 init.sh 失败"; exit 1; }
}
# =========================================== 主流程 ===========================================
function main() {
check
# upgrade
cd ${SCRIPT_PATH}/offline_resources
install_docker
install_1panel
echo && echo "验证安装结果..."
echo && echo "Docker版本: $(docker --version)"
echo && echo "Docker Compose版本: $(docker-compose --version)"
echo && echo "1Panel状态: $(systemctl status 1panel-core | grep Active)"
echo && echo
echo && echo "所有组件安装完成!" && echo && echo
cd ${SCRIPT_PATH}/busicess_resources
process_tar_files "`pwd`/containers" "docker_load_tar"
echo && echo "所有镜像安装完成!" && echo && echo
NETWORK_NAME="1panel-network"
if ! docker network ls | grep -q "$NETWORK_NAME"; then
echo "网络 $NETWORK_NAME 不存在,正在创建..."
docker network create "$NETWORK_NAME"
echo "网络 $NETWORK_NAME 创建成功!"
fi
cd ${SCRIPT_PATH}/busicess_resources/dataset
declare -A my_assoc_array=(
["minio.zip"]="process_empty"
["mysql.zip"]="process_empty"
["redis.zip"]="process_empty"
["rocketmq.zip"]="init_rocketmq"
["portainer-ce.zip"]="process_empty"
["phpmyadmin.zip"]="process_empty"
["simulation.zip"]="process_empty"
)
process_associative_array "/opt/1panel/apps" my_assoc_array "docker_installer" || { echo "初始化 init.sh 失败"; exit 1; }
echo && echo "所有容器安装完成!" && echo && echo
}
main

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.