Bläddra i källkod

feat: add beta version install shell

delong.wang 1 år sedan
förälder
incheckning
24e55faeb8

+ 12 - 3
documents/docs/02-guide/01-install.md

@@ -17,10 +17,21 @@ title: "安装雷池"
 
 复制以下命令执行,即可完成安装
 
-```shell
+```sh
 bash -c "$(curl -fsSLk https://waf-ce.chaitin.cn/release/latest/setup.sh)"
 ```
 
+## 在线安装 Beta 版
+
+**注意**:
+
+1. 建议在生产环境中使用稳定版
+2. beta 版仅支持在线安装和更新
+
+```sh
+bash -c "$(curl -fsSLk https://waf-ce.chaitin.cn/release/beta/setup.sh)"
+```
+
 **若安装失败,请参考 [安装问题](/faq/install)**
 
 ### 在线安装演示
@@ -30,8 +41,6 @@ style={{ width: '100%', height: '350px' }}
 > 
 </iframe>
 
-
-
 ## 离线安装
 
 **_如果服务器不可以访问互联网环境,推荐使用该方式_**

+ 8 - 2
documents/docs/02-guide/06-upgrade.md

@@ -12,18 +12,24 @@ title: "升级雷池"
 
 执行以下命令进行升级,升级不会清除历史数据。
 
-```
+```sh
 bash -c "$(curl -fsSLk https://waf-ce.chaitin.cn/release/latest/upgrade.sh)"
 ```
 
 [可选] 执行以下命令删除旧版本 Docker 镜像,释放磁盘空间。
 
-```
+```sh
 docker rmi $(docker images | grep "safeline" | grep "none" | awk '{print $3}')
 ```
 
 > 有部分环境的默认 SafeLine 安装路径是在 `/data/safeline-ce`,安装之后可能会发现需要重新绑定 OTP、配置丢失等情况,可以修改 .env 的 `SAFELINE_DIR` 变量,指向 `/data/safeline-ce`
 
+## 在线升级 Beta 版
+
+```sh
+bash -c "$(curl -fsSLk https://waf-ce.chaitin.cn/release/beta/upgrade.sh)"
+```
+
 ## 离线镜像
 
 适用于 docker hub 拉取镜像失败的场景,手动更新镜像。

Filskillnaden har hållts tillbaka eftersom den är för stor
+ 235 - 236
documents/yarn.lock


+ 114 - 0
release/beta/compose.yaml

@@ -0,0 +1,114 @@
+networks:
+  safeline-ce:
+    name: safeline-ce
+    driver: bridge
+    ipam:
+      driver: default
+      config:
+        - gateway: ${SUBNET_PREFIX:?SUBNET_PREFIX required}.1
+          subnet: ${SUBNET_PREFIX}.0/24
+    driver_opts:
+      com.docker.network.bridge.name: safeline-ce
+
+services:
+  postgres:
+    container_name: safeline-pg
+    restart: always
+    image: postgres:15-alpine
+    volumes:
+      - ${SAFELINE_DIR}/resources/postgres/data:/var/lib/postgresql/data
+      - /etc/localtime:/etc/localtime:ro
+    environment:
+      - POSTGRES_USER=safeline-ce
+      - POSTGRES_PASSWORD=${POSTGRES_PASSWORD:?postgres password required}
+    networks:
+      safeline-ce:
+        ipv4_address: ${SUBNET_PREFIX}.2
+    command: [postgres, -c, max_connections=200]
+  mgt:
+    container_name: safeline-mgt
+    restart: always
+    image: chaitin/safeline-mgt:${IMAGE_TAG:?image tag required}
+    volumes:
+      - /etc/localtime:/etc/localtime:ro
+      - ${SAFELINE_DIR}/resources/mgt:/app/data
+    ports:
+      - ${MGT_PORT:-9443}:1443
+    environment:
+      - MGT_PG=postgres://safeline-ce:${POSTGRES_PASSWORD}@safeline-postgres/safeline-ce
+    dns:
+      - 119.29.29.29
+      - 223.5.5.5
+      - 180.76.76.76
+      - 1.2.4.8
+      - 114.114.114.114
+      - 8.8.8.8
+    networks:
+      safeline-ce:
+        ipv4_address: ${SUBNET_PREFIX}.4
+  detector:
+    container_name: safeline-detector
+    restart: always
+    image: chaitin/safeline-detector:${IMAGE_TAG}
+    volumes:
+      - ${SAFELINE_DIR}/resources/detector:/resources/detector
+      - ${SAFELINE_DIR}/logs/detector:/logs/detector
+      - /etc/localtime:/etc/localtime:ro
+    environment:
+      - LOG_DIR=/logs/detector
+    networks:
+      safeline-ce:
+        ipv4_address: ${SUBNET_PREFIX}.5
+  mario:
+    container_name: safeline-mario
+    restart: always
+    image: chaitin/safeline-mario:${IMAGE_TAG}
+    volumes:
+      - ${SAFELINE_DIR}/resources/mario:/resources/mario
+      - ${SAFELINE_DIR}/logs/mario:/logs/mario
+      - /etc/localtime:/etc/localtime:ro
+    environment:
+      - LOG_DIR=/logs/mario
+      - GOGC=100
+      - DATABASE_URL=postgres://safeline-ce:${POSTGRES_PASSWORD}@safeline-postgres/safeline-ce
+    networks:
+      safeline-ce:
+        ipv4_address: ${SUBNET_PREFIX}.6
+  tengine:
+    container_name: safeline-tengine
+    restart: always
+    image: chaitin/safeline-tengine:${IMAGE_TAG}
+    volumes:
+      - ${SAFELINE_DIR}/resources/nginx:/etc/nginx
+      - ${SAFELINE_DIR}/resources/management:/resources/management
+      - ${SAFELINE_DIR}/resources/detector:/resources/detector
+      - ${SAFELINE_DIR}/logs/nginx:/var/log/nginx
+      - /etc/localtime:/etc/localtime:ro
+      - ${SAFELINE_DIR}/resources/cache:/usr/local/nginx/cache
+      - /etc/resolv.conf:/etc/resolv.conf
+    environment:
+      - TCD_MGT_API=https://${SUBNET_PREFIX}.4:1443/api/publish/server
+      - SNSERVER_ADDR=${SUBNET_PREFIX}.5:8000
+    ulimits:
+      nofile: 131072
+    network_mode: host
+  luigi:
+    container_name: safeline-luigi
+    restart: always
+    image: chaitin/safeline-luigi:${IMAGE_TAG}
+    volumes:
+      - /etc/localtime:/etc/localtime:ro
+      - ${SAFELINE_DIR}/resources/luigi:/app/data
+    networks:
+      safeline-ce:
+        ipv4_address: ${SUBNET_PREFIX}.7
+  fvm:
+    container_name: safeline-fvm
+    restart: always
+    image: chaitin/safeline-fvm:${IMAGE_TAG}
+    volumes:
+      - /etc/localtime:/etc/localtime:ro
+      - ${SAFELINE_DIR}/logs:/logs
+    networks:
+      safeline-ce:
+        ipv4_address: ${SUBNET_PREFIX}.8

+ 223 - 0
release/beta/setup.sh

@@ -0,0 +1,223 @@
+#!/bin/bash
+
+echo "
+  ____             __          _       _                
+ / ___|    __ _   / _|   ___  | |     (_)  _ __     ___ 
+ \___ \   / _\` | | |_   / _ \ | |     | | | '_ \   / _ \\
+  ___) | | (_| | |  _| |  __/ | |___  | | | | | | |  __/
+ |____/   \__,_| |_|    \___| |_____| |_| |_| |_|  \___|
+"
+
+qrcode() {
+    echo "█████████████████████████████████████████"
+    echo "█████████████████████████████████████████"
+    echo "████ ▄▄▄▄▄ █▀ █▀▀██▀▄▀▀▄▀▄▀▄██ ▄▄▄▄▄ ████"
+    echo "████ █   █ █▀ ▄ █▀▄▄▀▀ ▄█▄  ▀█ █   █ ████"
+    echo "████ █▄▄▄█ █▀█ █▄█▄▀▀▄▀▄ ▀▀▄▄█ █▄▄▄█ ████"
+    echo "████▄▄▄▄▄▄▄█▄█▄█ █▄▀ █ ▀▄▀ █▄█▄▄▄▄▄▄▄████"
+    echo "████▄ ▄▄ █▄▄  ▄█▄▄▄▄▀▄▀▀▄██ ▄▄▀▄█▄▀ ▀████"
+    echo "████▄ ▄▀▄ ▄▀▄ ▀ ▄█▀ ▀▄ █▀▀ ▀█▀▄██▄▀▄█████"
+    echo "█████ ▀▄█ ▄ ▄▄▀▄▀▀█▄▀▄▄▀▄▀▄ ▄ ▀▄▄▄█▀▀████"
+    echo "████ █▀▄▀ ▄▀▄▄▀█▀ ▄▄ █▄█▀▀▄▀▀█▄█▄█▀▄█████"
+    echo "████ █ ▀  ▄▀▀ ██▄█▄▄▄▄▄▀▄▀▀▀▄▄▀█▄▀█ ▀████"
+    echo "████ █ ▀▄ ▄██▀▀ ▄█▀ ▀███▄  ▀▄▀▄▄ ▄▀▄█████"
+    echo "████▀▄▄█  ▄▀▄▀ ▄▀▀▀▄▀▄▀ ▄▀▄  ▄▀ ▄▀█ ▀████"
+    echo "████ █ █ █▄▀ █▄█▀ ▄▄███▀▀▀▄█▀▄ ▀  ▀▄█████"
+    echo "████▄███▄█▄▄▀▄ █▄█▄▄▄▄▀▀▄█▀▀ ▄▄▄  ▀█ ████"
+    echo "████ ▄▄▄▄▄ █▄▀█ ▄█▀▄ █▀█▄ ▀  █▄█  ▀▄▀████"
+    echo "████ █   █ █  █▄▀▀▀▄▄▄▀▀▀▀▀▀ ▄▄  ▀█  ████"
+    echo "████ █▄▄▄█ █  ▀█▀ ▄▄▄▄ ▀█ ▀▀▄▀ ▀▀ ▀██████"
+    echo "████▄▄▄▄▄▄▄█▄▄██▄█▄▄█▄██▄██▄▄█▄▄█▄█▄█████"
+    echo "█████████████████████████████████████████"
+    echo "█████████████████████████████████████████"
+
+    echo
+    echo "微信扫描上方二维码加入雷池项目讨论组"
+}
+
+command_exists() {
+	command -v "$1" 2>&1
+}
+
+space_left() {
+    dir="$1"
+    while [ ! -d "$dir" ]; do
+        dir=`dirname "$dir"`;
+    done
+    echo `df -h "$dir" --output='avail' | tail -n 1`
+}
+
+start_docker() {
+    systemctl start docker && systemctl enable docker
+}
+
+confirm() {
+    echo -e -n "\033[34m[SafeLine] $* \033[1;36m(Y/n)\033[0m"
+    read -n 1 -s opt
+
+    [[ "$opt" == $'\n' ]] || echo
+
+    case "$opt" in
+        'y' | 'Y' ) return 0;;
+        'n' | 'N' ) return 1;;
+        *) confirm "$1";;
+    esac
+}
+
+info() {
+    echo -e "\033[37m[SafeLine] $*\033[0m"
+}
+
+warning() {
+    echo -e "\033[33m[SafeLine] $*\033[0m"
+}
+
+abort() {
+    qrcode
+    echo -e "\033[31m[SafeLine] $*\033[0m"
+    exit 1
+}
+
+trap 'onexit' INT
+onexit() {
+    echo
+    abort "用户手动结束安装"
+}
+
+# CPU ssse3 指令集检查
+support_ssse3=1
+lscpu | grep ssse3 > /dev/null 2>&1
+if [ $? -ne "0" ]; then
+    echo "not found info in lscpu"
+    support_ssse3=0
+fi
+
+cat /proc/cpuinfo | grep ssse3 > /dev/null 2>&1
+if [ $support_ssse3 -eq "0" -a $? -ne "0" ]; then
+    abort "雷池需要运行在支持 ssse3 指令集的 CPU 上,虚拟机请自行配置开启 CPU ssse3 指令集支持"
+fi
+
+safeline_path='/data/safeline'
+
+if [ -z "$BASH" ]; then
+    abort "请用 bash 执行本脚本,请参考最新的官方技术文档 https://waf-ce.chaitin.cn/"
+fi
+
+if [ ! -t 0 ]; then
+    abort "STDIN 不是标准的输入设备,请参考最新的官方技术文档 https://waf-ce.chaitin.cn/"
+fi
+
+if [ "$#" -ne "0" ]; then
+    abort "当前脚本无需任何参数,请参考最新的官方技术文档 https://waf-ce.chaitin.cn/"
+fi
+
+if [ "$EUID" -ne "0" ]; then
+    abort "请以 root 权限运行"
+fi
+info "脚本调用方式确认正常"
+
+if [ -z `command_exists docker` ]; then
+    warning "缺少 Docker 环境"
+    if confirm "是否需要自动安装 Docker"; then
+        curl -sSLk https://get.docker.com/ | bash
+        if [ $? -ne "0" ]; then
+            abort "Docker 安装失败"
+        fi
+        info "Docker 安装完成"
+    else
+        abort "中止安装"
+    fi
+fi
+info "发现 Docker 环境: '`command -v docker`'"
+
+start_docker
+docker version > /dev/null 2>&1
+if [ $? -ne "0" ]; then
+    abort "Docker 服务工作异常"
+fi
+info "Docker 工作状态正常"
+
+compose_command="docker compose"
+if $compose_command version; then
+    info "发现 Docker Compose Plugin"
+else
+    warning "未发现 Docker Compose Plugin"
+    compose_command="docker-compose"
+    if [ -z `command_exists "docker-compose"` ]; then
+        warning "未发现 docker-compose 组件"
+        if confirm "是否需要自动安装 Docker Compose Plugin"; then
+            curl -sSLk https://get.docker.com/ | bash
+            if [ $? -ne "0" ]; then
+                abort "Docker Compose Plugin 安装失败"
+            fi
+            info "Docker Compose Plugin 安装完成"
+            compose_command="docker compose"
+        else
+            abort "中止安装"
+        fi
+    else
+        info "发现 docker-compose 组件: '`command -v docker-compose`'"
+    fi
+fi
+
+while true; do
+    echo -e -n "\033[34m[SafeLine] 雷池安装目录 (留空则为 '$safeline_path'): \033[0m"
+    read input_path
+    [[ -z "$input_path" ]] && input_path=$safeline_path
+
+    if [[ ! $input_path == /* ]]; then
+        warning "'$input_path' 不是合法的绝对路径"
+        continue
+    fi
+
+    if [ -f "$input_path" ] || [ -d "$input_path" ]; then
+        warning "'$input_path' 路径已经存在,请换一个"
+        continue
+    fi
+
+    safeline_path=$input_path
+
+    if confirm "目录 '$safeline_path' 当前剩余存储空间为 `space_left \"$safeline_path\"` ,雷池至少需要 5G,是否确定"; then
+        break
+    fi
+done
+
+mkdir -p "$safeline_path"
+if [ $? -ne "0" ]; then
+    abort "创建安装目录 '$safeline_path' 失败"
+fi
+info "创建安装目录 '$safeline_path' 成功"
+cd "$safeline_path"
+
+curl -sS -k "https://waf-ce.chaitin.cn/release/beta/compose.yaml" -o compose.yaml
+if [ $? -ne "0" ]; then
+    abort "下载 compose.yaml 脚本失败"
+fi
+info "下载 compose.yaml 脚本成功"
+
+touch ".env"
+if [ $? -ne "0" ]; then
+    abort "创建 .env 脚本失败"
+fi
+info "创建 .env 脚本成功"
+
+echo "SAFELINE_DIR=$safeline_path" >> .env
+echo "IMAGE_TAG=beta" >> .env
+echo "MGT_PORT=9443" >> .env
+echo "POSTGRES_PASSWORD=$(LC_ALL=C tr -dc A-Za-z0-9 </dev/urandom | head -c 32)" >> .env
+echo "REDIS_PASSWORD=$(LC_ALL=C tr -dc A-Za-z0-9 </dev/urandom | head -c 32)" >> .env
+echo "SUBNET_PREFIX=172.22.222" >> .env
+
+info "即将开始下载 Docker 镜像"
+
+$compose_command up -d
+
+if [ $? -ne "0" ]; then
+    abort "启动 Docker 容器失败"
+fi
+
+qrcode
+
+warning "雷池 WAF 社区版安装成功,请访问以下地址访问控制台"
+warning "https://0.0.0.0:9443/"
+

+ 234 - 0
release/beta/upgrade.sh

@@ -0,0 +1,234 @@
+#! /bin/bash
+
+echo "
+  ____             __          _       _                
+ / ___|    __ _   / _|   ___  | |     (_)  _ __     ___ 
+ \___ \   / _\` | | |_   / _ \ | |     | | | '_ \   / _ \\
+  ___) | | (_| | |  _| |  __/ | |___  | | | | | | |  __/
+ |____/   \__,_| |_|    \___| |_____| |_| |_| |_|  \___|
+"
+
+echo $1
+
+qrcode() {
+    echo
+
+    echo "█████████████████████████████████████████"
+    echo "█████████████████████████████████████████"
+    echo "████ ▄▄▄▄▄ █▀ █▀▀██▀▄▀▀▄▀▄▀▄██ ▄▄▄▄▄ ████"
+    echo "████ █   █ █▀ ▄ █▀▄▄▀▀ ▄█▄  ▀█ █   █ ████"
+    echo "████ █▄▄▄█ █▀█ █▄█▄▀▀▄▀▄ ▀▀▄▄█ █▄▄▄█ ████"
+    echo "████▄▄▄▄▄▄▄█▄█▄█ █▄▀ █ ▀▄▀ █▄█▄▄▄▄▄▄▄████"
+    echo "████▄ ▄▄ █▄▄  ▄█▄▄▄▄▀▄▀▀▄██ ▄▄▀▄█▄▀ ▀████"
+    echo "████▄ ▄▀▄ ▄▀▄ ▀ ▄█▀ ▀▄ █▀▀ ▀█▀▄██▄▀▄█████"
+    echo "█████ ▀▄█ ▄ ▄▄▀▄▀▀█▄▀▄▄▀▄▀▄ ▄ ▀▄▄▄█▀▀████"
+    echo "████ █▀▄▀ ▄▀▄▄▀█▀ ▄▄ █▄█▀▀▄▀▀█▄█▄█▀▄█████"
+    echo "████ █ ▀  ▄▀▀ ██▄█▄▄▄▄▄▀▄▀▀▀▄▄▀█▄▀█ ▀████"
+    echo "████ █ ▀▄ ▄██▀▀ ▄█▀ ▀███▄  ▀▄▀▄▄ ▄▀▄█████"
+    echo "████▀▄▄█  ▄▀▄▀ ▄▀▀▀▄▀▄▀ ▄▀▄  ▄▀ ▄▀█ ▀████"
+    echo "████ █ █ █▄▀ █▄█▀ ▄▄███▀▀▀▄█▀▄ ▀  ▀▄█████"
+    echo "████▄███▄█▄▄▀▄ █▄█▄▄▄▄▀▀▄█▀▀ ▄▄▄  ▀█ ████"
+    echo "████ ▄▄▄▄▄ █▄▀█ ▄█▀▄ █▀█▄ ▀  █▄█  ▀▄▀████"
+    echo "████ █   █ █  █▄▀▀▀▄▄▄▀▀▀▀▀▀ ▄▄  ▀█  ████"
+    echo "████ █▄▄▄█ █  ▀█▀ ▄▄▄▄ ▀█ ▀▀▄▀ ▀▀ ▀██████"
+    echo "████▄▄▄▄▄▄▄█▄▄██▄█▄▄█▄██▄██▄▄█▄▄█▄█▄█████"
+    echo "█████████████████████████████████████████"
+    echo "█████████████████████████████████████████"
+
+    echo
+    echo "微信扫描上方二维码加入雷池项目讨论组"
+}
+
+command_exists() {
+    command -v "$1" 2>&1
+}
+
+space_left() {
+    dir="$1"
+    while [ ! -d "$dir" ]; do
+        dir=$(dirname "$dir")
+    done
+    echo $(df -h "$dir" --output='avail' | tail -n 1)
+}
+
+confirm() {
+    echo -e -n "\033[34m[SafeLine] $* \033[1;36m(Y/n)\033[0m"
+    read -n 1 -s opt
+
+    [[ "$opt" == $'\n' ]] || echo
+
+    case "$opt" in
+    'y' | 'Y') return 0 ;;
+    'n' | 'N') return 1 ;;
+    *) confirm "$1" ;;
+    esac
+}
+
+info() {
+    echo -e "\033[37m[SafeLine] $*\033[0m"
+}
+
+warning() {
+    echo -e "\033[33m[SafeLine] $*\033[0m"
+}
+
+abort() {
+    qrcode
+    echo -e "\033[31m[SafeLine] $*\033[0m"
+    exit 1
+}
+
+trap 'onexit' INT
+onexit() {
+    echo
+    abort "用户手动结束升级"
+}
+
+# CPU ssse3 指令集检查
+support_ssse3=1
+lscpu | grep ssse3 >/dev/null 2>&1
+if [ $? -ne "0" ]; then
+    echo "not found info in lscpu"
+    support_ssse3=0
+fi
+
+cat /proc/cpuinfo | grep ssse3 >/dev/null 2>&1
+if [ $support_ssse3 -eq "0" -a $? -ne "0" ]; then
+    abort "雷池需要运行在支持 ssse3 指令集的 CPU 上,虚拟机请自行配置开启 CPU ssse3 指令集支持"
+fi
+
+if [ -z "$BASH" ]; then
+    abort "请用 bash 执行本脚本, 请参考最新的官方技术文档 https://waf-ce.chaitin.cn/"
+fi
+
+if [ ! -t 0 ]; then
+    abort "STDIN 不是标准的输入设备, 请参考最新的官方技术文档 https://waf-ce.chaitin.cn/"
+fi
+
+if [ "$#" -ne "0" ]; then
+    abort "当前脚本无需任何参数, 请参考最新的官方技术文档 https://waf-ce.chaitin.cn/"
+fi
+
+if [ "$EUID" -ne "0" ]; then
+    abort "请以 root 权限运行"
+fi
+info "脚本调用方式确认正常"
+
+if [ -z $(command_exists docker) ]; then
+    warning "缺少 Docker 环境"
+    if confirm "是否需要自动安装 Docker"; then
+        curl -sSLk https://get.docker.com/ | bash
+        if [ $? -ne "0" ]; then
+            abort "Docker 安装失败"
+        fi
+        info "Docker 安装完成"
+    else
+        abort "中止安装"
+    fi
+fi
+info "发现 Docker 环境: '$(command -v docker)'"
+
+docker version >/dev/null 2>&1
+if [ $? -ne "0" ]; then
+    abort "Docker 服务工作异常"
+fi
+info "Docker 工作状态正常"
+
+compose_command="docker compose"
+if $compose_command version; then
+    info "发现 Docker Compose Plugin"
+else
+    warning "未发现 Docker Compose Plugin"
+    compose_command="docker-compose"
+    if [ -z $(command_exists "docker-compose") ]; then
+        warning "未发现 docker-compose 组件"
+        if confirm "是否需要自动安装 Docker Compose Plugin"; then
+            curl -sSLk https://get.docker.com/ | bash
+            if [ $? -ne "0" ]; then
+                abort "Docker Compose Plugin 安装失败"
+            fi
+            info "Docker Compose Plugin 安装完成"
+            compose_command="docker compose"
+        else
+            abort "中止安装"
+        fi
+    else
+        info "发现 docker-compose 组件: '$(command -v docker-compose)'"
+    fi
+fi
+
+container_id=$(docker ps --filter ancestor=chaitin/safeline-mgt-api --format '{{.ID}}')
+mount_path=$(docker inspect --format '{{range .Mounts}}{{if eq .Destination "/logs"}}{{.Source}}{{end}}{{end}}' $container_id)
+safeline_path=$(dirname $mount_path)
+
+while [ -z "$safeline_path" ]; do
+    echo -e -n "\033[34m[SafeLine] 未发现正在运行的雷池,请输入雷池安装路径 (留空则为 '$(pwd)'): \033[0m"
+    read input_path
+    [[ -z "$input_path" ]] && input_path=$(pwd)
+
+    if [[ ! $input_path == /* ]]; then
+        warning "'$input_path' 不是合法的绝对路径"
+        continue
+    fi
+
+    safeline_path=$input_path
+done
+
+cd "$safeline_path"
+
+grep COLLIE .env >/dev/null 2>&1
+if [ $? -eq "0" ]; then
+    abort "检测到你的环境通过牧云主机助手安装,请使用牧云主机助手-应用市场进行升级."
+fi
+
+compose_name=$(ls docker-compose.yaml compose.yaml 2>/dev/null)
+compose_path=$safeline_path/$compose_name
+
+if [ -f "$compose_path" ]; then
+    info "发现位于 '$safeline_path' 的雷池环境"
+else
+    abort "没有发现位于 $safeline_path 的雷池环境"
+fi
+
+mv $compose_name $compose_name.old
+
+curl "https://waf-ce.chaitin.cn/release/beta/compose.yaml" -sSLk -o $compose_name
+if [ $? -ne "0" ]; then
+    abort "下载 compose.yaml 脚本失败"
+fi
+info "下载 compose.yaml 脚本成功"
+
+sed -i "s/IMAGE_TAG=.*/IMAGE_TAG=beta/g" ".env"
+
+grep "SAFELINE_DIR" ".env" >/dev/null || echo "SAFELINE_DIR=$(pwd)" >>".env"
+grep "IMAGE_TAG" ".env" >/dev/null || echo "IMAGE_TAG=beta" >>".env"
+grep "MGT_PORT" ".env" >/dev/null || echo "MGT_PORT=9443" >>".env"
+grep "POSTGRES_PASSWORD" ".env" >/dev/null || echo "POSTGRES_PASSWORD=$(LC_ALL=C tr -dc A-Za-z0-9 </dev/urandom | head -c 32)" >>".env"
+grep "REDIS_PASSWORD" ".env" >/dev/null || echo "REDIS_PASSWORD=$(LC_ALL=C tr -dc A-Za-z0-9 </dev/urandom | head -c 32)" >>".env"
+grep "SUBNET_PREFIX" ".env" >/dev/null || echo "SUBNET_PREFIX=172.22.222" >>".env"
+
+info "升级 .env 脚本成功"
+
+info "即将开始下载新版本 Docker 镜像"
+
+$compose_command pull
+if [ $? -ne "0" ]; then
+    abort "下载新版本 Docker 镜像失败"
+fi
+info "下载新版本 Docker 镜像成功"
+
+info "即将开始替换 Docker 容器"
+
+# 升级到 3.14.0 版本时,移除了 safeline-redis 容器,需要删除容器,否则无法启动新 compose 网络
+docker rm -f safeline-redis &>/dev/null
+
+$compose_command down && $compose_command up -d
+if [ $? -ne "0" ]; then
+    abort "替换 Docker 容器失败"
+fi
+info "雷池升级成功"
+
+qrcode
+
+warning "雷池 WAF 社区版安装成功, 请访问以下地址访问控制台"
+warning "https://0.0.0.0:9443/"

Vissa filer visades inte eftersom för många filer har ändrats