安装docker
curl -fsSL https://get.docker.com | bash -s docker
步骤一:配置 Cloudflare 隧道 (一劳永逸)
-
在 Cloudflare Zero Trust 仪表板中,转到 Access -> Tunnels。
-
创建一个新隧道(例如,命名为secure-browser-tunnel)。
-
在“Configure”步骤中,您会看到一个“Install and run a connector”页面。
-
在右侧“Run as a Docker container”下,复制token。它看起来像这样:docker run cloudflare/cloudflared:latest tunnel –no-auto-update run –token <YOUR_TOKEN_HERE>
-
-
Service -> Type: http
-
Service -> URL: http://secure_browser:3000
-
服务器上,创建一个docker-compose-tunnel.yml文件:
version: '3.8' networks: cf_tunnel_net: name: cf_tunnel_net driver: bridge services: cloudflared: image: cloudflare/cloudflared:latest container_name: cf_tunnel_service restart: unless-stopped networks: - cf_tunnel_net command: tunnel run --token YOUR_TOKEN_HERE # 警告:请将上面的 YOUR_TOKEN_HERE 替换为您自己的隧道 Token -
启动隧道服务:
docker compose -f docker-compose-tunnel.yml up -d
步骤二:浏览器部署管理脚本
现在,这是您要求的主脚本。它将负责在 cf_tunnel_net 网络上启动、停止和切换浏览器容器。
将以下内容保存为 manage_browser.sh:
#!/bin/bash
# --- 基础配置 ---
CONTAINER_NAME="secure_browser"
DATA_DIR="/opt/docker_browser_data" # (请使用绝对路径)
DOCKER_NETWORK="cf_tunnel_net"
BROWSER_PASSWORD="YourStrongPasswordGoesHere" # (强烈建议修改)
PUID=1000
PGID=1000
TZ="Asia/Shanghai"
INTERNAL_PORT=3000 # (统一内部端口)
# --- 脚本功能 ---
# 检查 Docker 网络
check_network() {
if ! docker network inspect "$DOCKER_NETWORK" &>/dev/null; then
echo "网络 $DOCKER_NETWORK 未找到。"
echo "请确保您已通过 docker-compose-tunnel.yml 启动了隧道服务。"
exit 1
fi
}
# 停止并删除当前
stop_current() {
if docker ps -q --filter "name=$CONTAINER_NAME" | grep -q .; then
echo "正在停止并删除现有的 $CONTAINER_NAME 容器..."
docker stop "$CONTAINER_NAME" >/dev/null
docker rm "$CONTAINER_NAME" >/dev/null
echo "容器已停止。"
else
echo "没有找到正在运行的 $CONTAINER_NAME 容器。"
fi
}
# 启动 jlesage/firefox
start_jlesage_firefox() {
echo "正在启动 jlesage/firefox..."
mkdir -p "$DATA_DIR/jlesage_firefox"
docker run -d \
--name="$CONTAINER_NAME" \
--network="$DOCKER_NETWORK" \
--shm-size="2g" \
-v "$DATA_DIR/jlesage_firefox:/config" \
-e "VNC_PASSWORD=$BROWSER_PASSWORD" \
-e "WEB_LISTENING_PORT=$INTERNAL_PORT" \
-e "LANG=zh_CN.UTF-8" \
jlesage/firefox
echo "jlesage/firefox 已启动。"
}
# 启动 linuxserver/firefox
start_ls_firefox() {
echo "正在启动 linuxserver/firefox..."
mkdir -p "$DATA_DIR/ls_firefox"
docker run -d \
--name="$CONTAINER_NAME" \
--network="$DOCKER_NETWORK" \
--shm-size="2g" \
--security-opt seccomp=unconfined \
-e PUID=$PUID \
-e PGID=$PGID \
-e TZ=$TZ \
-e "LANG=zh_CN.UTF-8" \
-e PASSWORD="$BROWSER_PASSWORD" \
-v "$DATA_DIR/ls_firefox:/config" \
linuxserver/firefox
echo "linuxserver/firefox 已启动。"
}
# 启动 linuxserver/chromium
start_ls_chromium() {
echo "正在启动 linuxserver/chromium..."
mkdir -p "$DATA_DIR/ls_chromium"
docker run -d \
--name="$CONTAINER_NAME" \
--network="$DOCKER_NETWORK" \
--shm-size="2g" \
--security-opt seccomp=unconfined \
-e PUID=$PUID \
-e PGID=$PGID \
-e TZ=$TZ \
-e "LANG=zh_CN.UTF-8" \
-e PASSWORD="$BROWSER_PASSWORD" \
-v "$DATA_DIR/ls_chromium:/config" \
linuxserver/chromium
echo "linuxserver/chromium 已启动。"
}
# --- 新功能 (v1.3) ---
# 重启当前浏览器
restart_current() {
if docker ps -q --filter "name=$CONTAINER_NAME" | grep -q .; then
echo "正在重启 $CONTAINER_NAME 容器..."
docker restart "$CONTAINER_NAME"
echo "容器已重启。"
else
echo "没有找到正在运行的 $CONTAINER_NAME 容器。"
fi
}
# 清除数据子菜单
clear_data_menu() {
while true; do
clear
echo "================================="
echo " 清除浏览器数据"
echo "================================="
echo "警告:此操作将删除所选浏览器的所有配置、"
echo "书签和历史记录,并且无法撤销。"
echo "---------------------------------"
echo " 1) 清除 jlesage/firefox 数据"
echo " 2) 清除 linuxserver/firefox 数据"
echo " 3) 清除 linuxserver/chromium 数据"
echo " 4) ⚠️ 清除 *所有* 浏览器数据"
echo " Q) 返回主菜单"
echo "---------------------------------"
read -rp "请输入选项 [1-4, Q]: " data_choice
case $data_choice in
1) clear_specific_data "jlesage_firefox" "jlesage/firefox" ;;
2) clear_specific_data "ls_firefox" "linuxserver/firefox" ;;
3) clear_specific_data "ls_chromium" "linuxserver/chromium" ;;
4) clear_all_data ;;
[qQ]) break ;;
*) echo "无效选项,请重试。" ; sleep 2 ;;
esac
done
}
# 清除特定数据的帮助函数
clear_specific_data() {
local dir_name="$1"
local image_name_pattern="$2" # e.g., "jlesage/firefox"
local data_path="$DATA_DIR/$dir_name"
echo "您选择清除 '$image_name_pattern' 的数据。"
if [ ! -d "$data_path" ]; then
echo "数据目录 '$data_path' 未找到。可能还未部署过此浏览器。"
read -rp "按 Enter 键返回..."
return
fi
# 检查容器是否正在运行
if docker ps -q --filter "name=$CONTAINER_NAME" | grep -q .; then
local running_image=$(docker inspect "$CONTAINER_NAME" --format '{{.Config.Image}}')
if [[ "$running_image" == *"$image_name_pattern"* ]]; then
echo "警告:'$running_image' 容器 ($CONTAINER_NAME) 当前正在运行。"
echo "清除数据前必须先停止它。"
stop_current
fi
fi
read -rp "您确定要永久删除 '$data_path' 吗?此操作无法撤销!请输入 'yes' 确认: " confirm
if [ "$confirm" == "yes" ]; then
echo "正在删除 $data_path..."
rm -rf "$data_path"
echo "数据已清除。"
else
echo "操作已取消。"
fi
read -rp "按 Enter 键返回..."
}
# 清除所有数据的帮助函数
clear_all_data() {
local path1="$DATA_DIR/jlesage_firefox"
local path2="$DATA_DIR/ls_firefox"
local path3="$DATA_DIR/ls_chromium"
echo "警告:您即将删除 *所有* 浏览器的数据目录!"
if docker ps -q --filter "name=$CONTAINER_NAME" | grep -q .; then
echo "警告:$CONTAINER_NAME 容器当前正在运行。"
echo "清除数据前必须先停止它。"
stop_current
fi
read -rp "您确定要永久删除 '$path1', '$path2', 和 '$path3' 吗?此操作无法撤销!请输入 'yes' 确认: " confirm
if [ "$confirm" == "yes" ]; then
echo "正在删除 $path1..."
rm -rf "$path1"
echo "正在删除 $path2..."
rm -rf "$path2"
echo "正在删除 $path3..."
rm -rf "$path3"
echo "所有数据已清除。"
else
echo "操作已取消。"
fi
read -rp "按 Enter 键返回..."
}
# --- 主菜单 (v1.3) ---
main_menu() {
clear
echo "================================="
echo " 安全浏览器部署管理器 (v1.3)"
echo "================================="
echo "当前运行的容器:"
docker ps --filter "name=$CONTAINER_NAME" --format " {{.Names}} ({{.Image}})"
echo "---------------------------------"
echo "请选择一个操作:"
echo " 1) 部署 jlesage/firefox"
echo " 2) 部署 linuxserver/firefox"
echo " 3) 部署 linuxserver/chromium"
echo " 4) 停止当前浏览器"
echo " 5) 重启当前浏览器"
echo " 6) ⚠️ 清除浏览器数据..."
echo " Q) 退出"
echo "---------------------------------"
read -rp "请输入选项 [1-6, Q]: " choice
}
# --- 脚本执行 ---
if ! command -v docker &> /dev/null; then
echo "错误: Docker 未安装。"
exit 1
fi
check_network
while true; do
main_menu
case $choice in
1) stop_current; start_jlesage_firefox ;;
2) stop_current; start_ls_firefox ;;
3) stop_current; start_ls_chromium ;;
4) stop_current ;;
5) restart_current ;;
6) clear_data_menu ;;
[qQ]) echo "退出。"; exit 0 ;;
*) echo "无效选项,请重试。" ;;
esac
read -rp "按 Enter 键返回主菜单..."
done