install.sh 9.5 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317
  1. #!/bin/bash
  2. # 颜色定义
  3. RED='\033[0;31m'
  4. GREEN='\033[0;32m'
  5. YELLOW='\033[1;33m'
  6. NC='\033[0m' # No Color
  7. # 打印带颜色的消息
  8. print_message() {
  9. echo -e "${GREEN}[INFO]${NC} $1"
  10. }
  11. print_warning() {
  12. echo -e "${YELLOW}[WARNING]${NC} $1"
  13. }
  14. print_error() {
  15. echo -e "${RED}[ERROR]${NC} $1"
  16. }
  17. # 检测操作系统类型
  18. detect_os() {
  19. if [ -f /etc/os-release ]; then
  20. . /etc/os-release
  21. OS=$NAME
  22. VER=$VERSION_ID
  23. elif type lsb_release >/dev/null 2>&1; then
  24. OS=$(lsb_release -si)
  25. VER=$(lsb_release -sr)
  26. elif [ -f /etc/lsb-release ]; then
  27. . /etc/lsb-release
  28. OS=$DISTRIB_ID
  29. VER=$DISTRIB_RELEASE
  30. elif [ -f /etc/debian_version ]; then
  31. OS=Debian
  32. VER=$(cat /etc/debian_version)
  33. elif [ -f /etc/SuSe-release ]; then
  34. OS=SuSE
  35. elif [ -f /etc/redhat-release ]; then
  36. OS=RedHat
  37. VER=$(cat /etc/redhat-release | sed 's/.*release \([0-9.]*\).*/\1/')
  38. else
  39. OS=$(uname -s)
  40. VER=$(uname -r)
  41. fi
  42. echo "检测到操作系统: $OS $VER"
  43. }
  44. # 更新包管理器
  45. update_package_manager() {
  46. print_message "更新包管理器..."
  47. if [[ "$OS" == *"Ubuntu"* ]] || [[ "$OS" == *"Debian"* ]]; then
  48. apt update && apt upgrade -y
  49. apt install -y curl wget
  50. elif [[ "$OS" == *"CentOS"* ]] || [[ "$OS" == *"Red Hat"* ]] || [[ "$OS" == *"Rocky"* ]] || [[ "$OS" == *"AlmaLinux"* ]]; then
  51. if command -v dnf &> /dev/null; then
  52. dnf update -y
  53. dnf install -y curl wget jq
  54. else
  55. yum update -y
  56. yum install -y curl wget jq
  57. fi
  58. else
  59. print_message "使用通用方式安装curl和wget..."
  60. # 尝试通用方式安装
  61. if command -v apt &> /dev/null; then
  62. apt update && apt install -y curl wget jq
  63. elif command -v dnf &> /dev/null; then
  64. dnf install -y curl wget jq
  65. elif command -v yum &> /dev/null; then
  66. yum install -y curl wget jq
  67. elif command -v zypper &> /dev/null; then
  68. zypper install -y curl wget jq
  69. else
  70. print_warning "无法自动安装curl和wget,请手动安装"
  71. fi
  72. fi
  73. }
  74. # 卸载旧版本Docker
  75. remove_old_docker() {
  76. print_message "检查并卸载旧版本Docker..."
  77. if [[ "$OS" == *"Ubuntu"* ]] || [[ "$OS" == *"Debian"* ]]; then
  78. apt-get remove -y docker docker-engine docker.io containerd runc 2>/dev/null || true
  79. elif [[ "$OS" == *"CentOS"* ]] || [[ "$OS" == *"Red Hat"* ]] || [[ "$OS" == *"Rocky"* ]] || [[ "$OS" == *"AlmaLinux"* ]]; then
  80. if command -v dnf &> /dev/null; then
  81. dnf remove -y docker docker-client docker-client-latest docker-common docker-latest docker-latest-logrotate docker-logrotate docker-engine 2>/dev/null || true
  82. else
  83. yum remove -y docker docker-client docker-client-latest docker-common docker-latest docker-latest-logrotate docker-logrotate docker-engine 2>/dev/null || true
  84. fi
  85. else
  86. print_message "使用通用方式卸载旧版本Docker..."
  87. # 通用卸载方式
  88. if command -v apt &> /dev/null; then
  89. apt-get remove -y docker docker-engine docker.io containerd runc 2>/dev/null || true
  90. elif command -v dnf &> /dev/null; then
  91. dnf remove -y docker docker-client docker-client-latest docker-common docker-latest docker-latest-logrotate docker-logrotate docker-engine 2>/dev/null || true
  92. elif command -v yum &> /dev/null; then
  93. yum remove -y docker docker-client docker-client-latest docker-common docker-latest docker-latest-logrotate docker-logrotate docker-engine 2>/dev/null || true
  94. fi
  95. fi
  96. }
  97. # 安装Docker
  98. install_docker() {
  99. print_message "安装Docker..."
  100. # 使用官方的get-docker.sh脚本,它已经做了跨平台兼容
  101. curl -fsSL https://get.docker.com -o get-docker.sh
  102. sh get-docker.sh
  103. rm -f get-docker.sh
  104. # 启动并启用Docker服务
  105. systemctl start docker
  106. systemctl enable docker
  107. }
  108. # 安装Docker Compose
  109. install_docker_compose() {
  110. print_message "安装Docker Compose..."
  111. # 检查是否已经安装了docker-compose-plugin
  112. if docker compose version &> /dev/null; then
  113. print_message "Docker Compose 插件已安装"
  114. return
  115. fi
  116. # 下载并安装独立版本的Docker Compose
  117. COMPOSE_VERSION=$(curl -s https://api.github.com/repos/docker/compose/releases/latest | grep 'tag_name' | cut -d\" -f4)
  118. # 下载适合当前系统的Docker Compose二进制文件
  119. curl -L "https://github.com/docker/compose/releases/download/${COMPOSE_VERSION}/docker-compose-$(uname -s)-$(uname -m)" -o /usr/local/bin/docker-compose
  120. chmod +x /usr/local/bin/docker-compose
  121. # 创建软链接
  122. ln -sf /usr/local/bin/docker-compose /usr/bin/docker-compose
  123. }
  124. # 写入JSON配置文件的函数(更安全)
  125. write_json_config() {
  126. local file_path="$1"
  127. local json_content="$2"
  128. mkdir -p "$(dirname "$file_path")"
  129. if command -v jq &> /dev/null; then
  130. if echo "$json_content" | jq . > /dev/null 2>&1; then
  131. print_message "JSON格式验证通过"
  132. else
  133. print_error "JSON格式无效"
  134. return 1
  135. fi
  136. fi
  137. echo "$json_content" | tee "$file_path" > /dev/null
  138. if [ $? -eq 0 ]; then
  139. print_message "成功写入JSON配置文件: $file_path"
  140. else
  141. print_error "写入JSON配置文件失败: $file_path"
  142. return 1
  143. fi
  144. }
  145. # 验证安装
  146. verify_installation() {
  147. # 修改国内的docker源
  148. local docker_daemon_config='{
  149. "registry-mirrors": [
  150. "https://docker.1panel.live",
  151. "https://docker.1ms.run",
  152. "https://docker.m.daocloud.io",
  153. "https://registry.cn-hangzhou.aliyuncs.com"
  154. ]
  155. }'
  156. write_json_config "/etc/docker/daemon.json" "$docker_daemon_config"
  157. systemctl daemon-reload
  158. systemctl restart docker
  159. print_message "验证安装..."
  160. if command -v docker &> /dev/null; then
  161. print_message "Docker 安装成功"
  162. docker --version
  163. else
  164. print_error "Docker 安装失败"
  165. exit 1
  166. fi
  167. if command -v docker-compose &> /dev/null || docker compose version &> /dev/null; then
  168. print_message "Docker Compose 安装成功"
  169. if command -v docker-compose &> /dev/null; then
  170. docker-compose --version
  171. else
  172. docker compose version
  173. fi
  174. else
  175. print_error "Docker Compose 安装失败"
  176. exit 1
  177. fi
  178. # 测试Docker服务
  179. if systemctl is-active --quiet docker; then
  180. print_message "Docker 服务运行正常"
  181. else
  182. print_error "Docker 服务未运行"
  183. exit 1
  184. fi
  185. }
  186. # 构建和启动Docker容器
  187. build_and_start_containers() {
  188. print_message "开始构建和启动Docker容器..."
  189. # 检查是否存在docker-compose.yml文件
  190. if [ ! -f "docker-compose.yml" ]; then
  191. print_error "未找到docker-compose.yml文件,请确保在正确的目录中运行此脚本"
  192. exit 1
  193. fi
  194. # 构建Docker镜像(不使用缓存)
  195. print_message "构建Docker镜像(不使用缓存)..."
  196. if command -v docker-compose &> /dev/null; then
  197. docker-compose build --no-cache
  198. else
  199. docker compose build --no-cache
  200. fi
  201. if [ $? -ne 0 ]; then
  202. print_error "Docker镜像构建失败"
  203. exit 1
  204. fi
  205. print_message "Docker镜像构建成功"
  206. # 运行steamcmd容器
  207. print_message "运行steamcmd容器..."
  208. if command -v docker-compose &> /dev/null; then
  209. docker-compose run --rm steamcmd
  210. else
  211. docker compose run --rm steamcmd
  212. fi
  213. if [ $? -ne 0 ]; then
  214. print_warning "steamcmd容器运行失败,但继续启动其他服务"
  215. else
  216. print_message "steamcmd容器运行完成"
  217. fi
  218. # 启动所有容器
  219. print_message "启动所有Docker容器..."
  220. if command -v docker-compose &> /dev/null; then
  221. docker-compose up -d
  222. else
  223. docker compose up -d
  224. fi
  225. if [ $? -eq 0 ]; then
  226. print_message "所有Docker容器启动成功"
  227. # 显示容器状态
  228. print_message "容器状态:"
  229. if command -v docker-compose &> /dev/null; then
  230. docker-compose ps
  231. else
  232. docker compose ps
  233. fi
  234. else
  235. print_error "Docker容器启动失败"
  236. exit 1
  237. fi
  238. }
  239. # 主函数
  240. main() {
  241. print_message "开始安装 Docker 和 Docker Compose..."
  242. # 检查是否为root用户
  243. if [[ $EUID -ne 0 ]]; then
  244. print_error "此脚本需要root权限运行"
  245. exit 1
  246. fi
  247. detect_os
  248. update_package_manager
  249. remove_old_docker
  250. install_docker
  251. install_docker_compose
  252. verify_installation
  253. print_message "Docker 和 Docker Compose 安装完成!"
  254. # 询问是否继续构建和启动容器
  255. echo
  256. read -p "是否现在构建和启动Docker容器?(y/n): " -n 1 -r
  257. echo
  258. if [[ $REPLY =~ ^[Yy]$ ]]; then
  259. build_and_start_containers
  260. print_message "所有操作完成!"
  261. else
  262. print_message "安装完成!您可以稍后手动运行以下命令:"
  263. print_message "1. docker-compose build --no-cache"
  264. print_message "2. docker-compose run --rm steamcmd"
  265. print_message "3. docker-compose up -d"
  266. print_message "运行第二步时,第一次运行会等待steam验证码,需要手动输入"
  267. fi
  268. }
  269. # 执行主函数
  270. main "$@"