mirror of
https://github.com/Oreomeow/VIP.git
synced 2026-02-04 02:53:26 +08:00
298 lines
8.6 KiB
Bash
298 lines
8.6 KiB
Bash
#!/usr/bin/env bash
|
||
# shellcheck disable=SC2181
|
||
|
||
clear
|
||
|
||
echo -e "\e[34m
|
||
mmmm mm mm mmmmm mmmmmm
|
||
\"\"## \"## ##\" #\"\"\"\"##m ##\"\"\"\"#m
|
||
m####m ## m####m m#####m ## ## ## ## ##
|
||
##mmmm## ## ##mmmm## ##\" \" ## ## m#\" ######\"
|
||
##\"\"\"\"\"\" ## ##\"\"\"\"\"\" ## #### m#\" ##
|
||
\"##mmmm# ##mmm \"##mmmm# \"##mmmm# #### m##mmmmm ##
|
||
\"\"\"\"\" \"\"\"\" \"\"\"\"\" \"\"\"\"\" \"\"\"\" \"\"\"\"\"\"\"\" \"\"
|
||
\e[0m
|
||
"
|
||
|
||
DOCKER_IMG_NAME="elecv2/elecv2p"
|
||
V2P_PATH=""
|
||
SHELL_FOLDER=$(pwd)
|
||
CONTAINER_NAME=""
|
||
TAG="latest"
|
||
NETWORK="bridge"
|
||
V2P_PORT=8100 # webUI 后台管理界面。添加规则/JS 文件管理/定时任务管理/MITM 证书等
|
||
HTTP_PORT=8101 # ANYPROXY HTTP 代理端口。(代理端口不是网页,不能通过浏览器直接访问)
|
||
REQUEST_PORT=8102 # ANYPROXY 代理请求查看端口
|
||
|
||
HAS_IMAGE=false
|
||
EXT_ALL=true
|
||
PULL_IMAGE=true
|
||
HAS_CONTAINER=false
|
||
DEL_CONTAINER=true
|
||
INSTALL_WATCH=false
|
||
OLD_IMAGE_ID=""
|
||
|
||
log() {
|
||
echo -e "\e[32m\n$1 \e[0m\n"
|
||
}
|
||
|
||
inp() {
|
||
echo -e "\e[33m\n$1 \e[0m\n"
|
||
}
|
||
|
||
opt() {
|
||
echo -n -e "\e[36m输入您的选择->\e[0m"
|
||
}
|
||
|
||
warn() {
|
||
echo -e "\e[31m$1 \e[0m\n"
|
||
}
|
||
|
||
cancelrun() {
|
||
if [ $# -gt 0 ]; then
|
||
echo -e "\e[31m $1 \e[0m"
|
||
fi
|
||
exit 1
|
||
}
|
||
|
||
docker_install() {
|
||
echo "检测 Docker......"
|
||
if [ -x "$(command -v docker)" ]; then
|
||
echo "检测到 Docker 已安装!"
|
||
else
|
||
if [ -r /etc/os-release ]; then
|
||
lsb_dist="$(. /etc/os-release && echo "$ID")"
|
||
fi
|
||
if [ "$lsb_dist" == "openwrt" ]; then
|
||
echo "openwrt 环境请自行安装 docker"
|
||
exit 1
|
||
else
|
||
echo "安装 docker 环境..."
|
||
curl -fsSL https://get.docker.com | bash -s docker --mirror Aliyun
|
||
echo "安装 docker 环境...安装完成!"
|
||
systemctl enable docker
|
||
systemctl start docker
|
||
fi
|
||
fi
|
||
}
|
||
|
||
# 配置文件保存目录
|
||
set_savedir() {
|
||
echo -n -e "\e[33m\n一、请输入配置文件保存的绝对路径(示例:/root/v2p1),回车默认为 当前目录/elecv2p:\e[0m"
|
||
read -r v2p_path
|
||
if [ -z "$v2p_path" ]; then
|
||
mkdir -p "$SHELL_FOLDER"/elecv2p
|
||
V2P_PATH=$SHELL_FOLDER/elecv2p
|
||
elif [ -d "$v2p_path" ]; then
|
||
V2P_PATH=$v2p_path
|
||
else
|
||
mkdir -p "$v2p_path"
|
||
V2P_PATH=$v2p_path
|
||
fi
|
||
JSFILE_PATH=$V2P_PATH/JSFile
|
||
LISTS_PATH=$V2P_PATH/Lists
|
||
STORE_PATH=$V2P_PATH/Store
|
||
SHELL_PATH=$V2P_PATH/Shell
|
||
ROOTCA_PATH=$V2P_PATH/rootCA
|
||
EFSS_PATH=$V2P_PATH/efss
|
||
}
|
||
|
||
docker_install
|
||
warn "小白基本回车即可,更多学习内容尽在 https://github.com/elecV2/elecV2P"
|
||
|
||
inp "是否将目录映射到外部:\n1) 映射[默认]\n2) 不映射"
|
||
opt
|
||
read -r ext_all
|
||
if [ "$ext_all" = "2" ]; then
|
||
EXT_ALL=false
|
||
else
|
||
set_savedir
|
||
fi
|
||
|
||
# 检测镜像是否存在
|
||
if [ -n "$(docker images -q $DOCKER_IMG_NAME:$TAG 2>/dev/null)" ]; then
|
||
HAS_IMAGE=true
|
||
OLD_IMAGE_ID=$(docker images -q --filter reference=$DOCKER_IMG_NAME:$TAG)
|
||
inp "检测到先前已经存在的镜像,是否拉取最新的镜像:\n1) 拉取[默认]\n2) 不拉取"
|
||
opt
|
||
read -r update
|
||
if [ "$update" = "2" ]; then
|
||
PULL_IMAGE=false
|
||
fi
|
||
fi
|
||
|
||
# 检测容器是否存在
|
||
check_container_name() {
|
||
if docker ps -a | grep "$CONTAINER_NAME" 2>/dev/null; then
|
||
HAS_CONTAINER=true
|
||
inp "检测到先前已经存在的容器,是否删除先前的容器:\n1) 删除[默认]\n2) 不删除"
|
||
opt
|
||
read -r update
|
||
if [ "$update" = "2" ]; then
|
||
PULL_IMAGE=false
|
||
inp "您选择了不删除之前的容器,需要重新输入容器名称"
|
||
input_container_name
|
||
fi
|
||
fi
|
||
}
|
||
|
||
# 容器名称
|
||
input_container_name() {
|
||
echo -n -e "\e[33m\n二、请输入要创建的 Docker 容器名称[默认为:elecv2p]->\e[0m"
|
||
read -r container_name
|
||
if [ -z "$container_name" ]; then
|
||
CONTAINER_NAME="elecv2p"
|
||
else
|
||
CONTAINER_NAME=$container_name
|
||
fi
|
||
check_container_name
|
||
}
|
||
input_container_name
|
||
|
||
# 是否安装 WatchTower
|
||
inp "是否安装 containrrr/watchtower 自动更新 Docker 容器:\n1) 安装\n2) 不安装[默认]"
|
||
opt
|
||
read -r watchtower
|
||
if [ "$watchtower" = "1" ]; then
|
||
INSTALL_WATCH=true
|
||
fi
|
||
|
||
inp "请选择容器的网络类型:\n1) host\n2) bridge[默认]"
|
||
echo -e "\e[31m如果在部分复杂的网络情况下出现无法联网或访问的问题,尝试在命令中添加 --net=host,即选择 host 模式\e[0m\n"
|
||
opt
|
||
read -r net
|
||
if [ "$net" = "1" ]; then
|
||
NETWORK="host"
|
||
MAPPING_V2P_PORT=""
|
||
MAPPING_HTTP_PORT=""
|
||
MAPPING_REQUEST_PORT=""
|
||
fi
|
||
|
||
if [ "$NETWORK" = "bridge" ]; then
|
||
inp "是否修改映射端口[默认 8100|8101|8102]:\n1) 修改\n2) 不修改[默认]"
|
||
opt
|
||
read -r change_port
|
||
if [ "$change_port" = "1" ]; then
|
||
echo -n -e "\e[36m输入您想修改的 webUI 端口->\e[0m"
|
||
read -r V2P_PORT
|
||
echo -n -e "\e[36m输入您想修改的代理端口->\e[0m"
|
||
read -r HTTP_PORT
|
||
echo -n -e "\e[36m输入您想修改的代理请求查看端口->\e[0m"
|
||
read -r REQUEST_PORT
|
||
fi
|
||
fi
|
||
|
||
# 配置已经创建完成,开始执行
|
||
if [ $EXT_ALL = true ]; then
|
||
log "1.开始创建配置文件目录"
|
||
PATH_LIST=("$JSFILE_PATH" "$LISTS_PATH" "$STORE_PATH" "$SHELL_PATH" "$ROOTCA_PATH" "$EFSS_PATH")
|
||
for i in "${PATH_LIST[@]}"; do
|
||
mkdir -p "$i"
|
||
done
|
||
if [ $? -ne 0 ]; then
|
||
cancelrun "** 错误:目录创建错误请重试!"
|
||
fi
|
||
fi
|
||
|
||
if [ $HAS_CONTAINER = true ] && [ $DEL_CONTAINER = true ]; then
|
||
log "2.1.删除先前的容器"
|
||
docker stop "$CONTAINER_NAME" >/dev/null
|
||
docker rm "$CONTAINER_NAME" >/dev/null
|
||
fi
|
||
|
||
if [ $HAS_IMAGE = true ] && [ $PULL_IMAGE = true ]; then
|
||
if [ -n "$OLD_IMAGE_ID" ] && [ $HAS_CONTAINER = true ] && [ $DEL_CONTAINER = true ]; then
|
||
log "2.2.删除旧的镜像"
|
||
docker image rm "$OLD_IMAGE_ID"
|
||
fi
|
||
log "2.3.开始拉取最新的镜像"
|
||
docker pull $DOCKER_IMG_NAME:$TAG
|
||
if [ $? -ne 0 ]; then
|
||
cancelrun "** 错误:拉取不到镜像!"
|
||
fi
|
||
fi
|
||
|
||
# 端口存在检测
|
||
check_port() {
|
||
echo "正在检测端口:$1"
|
||
netstat -tlpn | grep "[[:graph:]]*:${1}\b"
|
||
}
|
||
if [ "$NETWORK" = "bridge" ]; then
|
||
while check_port "$V2P_PORT"; do
|
||
echo -n -e "\e[31m端口:$V2P_PORT 被占用,请重新输入 webUI 端口:\e[0m"
|
||
read -r V2P_PORT
|
||
done
|
||
echo -e "\e[34m恭喜,端口:$V2P_PORT 可用\e[0m"
|
||
MAPPING_V2P_PORT="-p $V2P_PORT:80"
|
||
while check_port "$HTTP_PORT"; do
|
||
echo -n -e "\e[31m端口:$HTTP_PORT 被占用,请重新输入代理端口:\e[0m"
|
||
read -r HTTP_PORT
|
||
done
|
||
echo -e "\e[34m恭喜,端口:$HTTP_PORT 可用\e[0m"
|
||
MAPPING_HTTP_PORT="-p $HTTP_PORT:8001"
|
||
while check_port "$REQUEST_PORT"; do
|
||
echo -n -e "\e[31m端口:$REQUEST_PORT 被占用,请重新输入代理请求端口:\e[0m"
|
||
read -r REQUEST_PORT
|
||
done
|
||
echo -e "\e[34m恭喜,端口:$REQUEST_PORT 可用\e[0m"
|
||
MAPPING_REQUEST_PORT="-p $REQUEST_PORT:8002"
|
||
fi
|
||
|
||
log "3.开始创建容器并执行"
|
||
# shellcheck disable=SC2086
|
||
run_v() {
|
||
docker run -dit \
|
||
-t \
|
||
-e TZ=Asia/Shanghai \
|
||
$MAPPING_V2P_PORT \
|
||
$MAPPING_HTTP_PORT \
|
||
$MAPPING_REQUEST_PORT \
|
||
-v "$JSFILE_PATH":/usr/local/app/script/JSFile \
|
||
-v "$LISTS_PATH":/usr/local/app/script/Lists \
|
||
-v "$STORE_PATH":/usr/local/app/script/Store \
|
||
-v "$SHELL_PATH":/usr/local/app/script/Shell \
|
||
-v "$ROOTCA_PATH":/usr/local/app/rootCA \
|
||
-v "$EFSS_PATH":/usr/local/app/efss \
|
||
--name "$CONTAINER_NAME" \
|
||
--restart always \
|
||
--network $NETWORK \
|
||
$DOCKER_IMG_NAME
|
||
}
|
||
# shellcheck disable=SC2086
|
||
run_nov() {
|
||
docker run -dit \
|
||
-t \
|
||
-e TZ=Asia/Shanghai \
|
||
$MAPPING_V2P_PORT \
|
||
$MAPPING_HTTP_PORT \
|
||
$MAPPING_REQUEST_PORT \
|
||
--name "$CONTAINER_NAME" \
|
||
--restart always \
|
||
--network $NETWORK \
|
||
$DOCKER_IMG_NAME
|
||
}
|
||
if [ $EXT_ALL = true ]; then
|
||
run_v
|
||
else
|
||
run_nov
|
||
fi
|
||
|
||
if [ $? -ne 0 ]; then
|
||
cancelrun "** 错误:容器创建失败,请翻译以上英文报错,Google/百度尝试解决问题!"
|
||
fi
|
||
|
||
if [ $INSTALL_WATCH = true ]; then
|
||
log "3.1.开始创建容器并执行"
|
||
docker run -d \
|
||
--name watchtower \
|
||
--restart always \
|
||
-v /var/run/docker.sock:/var/run/docker.sock \
|
||
containrrr/watchtower -c --schedule "13,14,15 3 * * * *" \
|
||
"$CONTAINER_NAME"
|
||
fi
|
||
|
||
log "4.下面列出所有容器"
|
||
docker ps
|
||
|
||
log "enjoy!!!"
|