- 重构隧道进程管理:将隧道启动从 entrypoint.sh 移至 docker-entrypoint.sh - 添加隧道自动重启机制:监控循环每5秒检查隧道进程状态,异常退出时自动重启 - 增强日志记录:隧道输出重定向至 /tmp/tunnel.log 便于问题排查 - 修复原始架构问题:解决 exec 替换进程导致后台隧道失去父进程监控的问题 - 优化清理逻辑:在信号处理和错误退出时正确清理隧道进程
150 lines
5.4 KiB
Bash
Executable File
150 lines
5.4 KiB
Bash
Executable File
#!/bin/sh
|
||
set -e
|
||
|
||
show_help() {
|
||
cat <<'EOT'
|
||
Portwarden 客户端集成脚本 (entrypoint.sh) — 多服务端并发连接版(HTTPS + /portwarden)
|
||
|
||
用法:
|
||
- 将本脚本作为容器 ENTRYPOINT
|
||
- 通过环境变量提供必要配置
|
||
|
||
必需环境变量:
|
||
- PW_SERVICE_ID : Portwarden 客户端的唯一服务标识
|
||
- PW_SERVER_ADDRS : 逗号分隔的多个服务端地址 (仅支持 https://;禁止 http://;不得包含路径 /portwarden)
|
||
例如: https://bastion.example.org,https://edge.example.net
|
||
- PW_LOCAL_PORT : 应用在容器内监听的端口 (数字,例如 8080)
|
||
|
||
行为:
|
||
1) 验证以上环境变量
|
||
2) 导出为 SERVER_ADDRS/SERVICE_ID/LOCAL_PORT 供 portwardenc 使用
|
||
3) 后台启动 /usr/local/bin/portwardenc
|
||
4) 执行容器 CMD 指定的主程序
|
||
|
||
获取二进制与脚本 (通过 Bastion WebUI 静态发布 /releases):
|
||
- 直接下载:
|
||
GET https://<bastion-domain>/releases/portwardenc-amd64
|
||
GET https://<bastion-domain>/releases/portwardenc-arm64
|
||
GET https://<bastion-domain>/releases/entrypoint.sh
|
||
|
||
- Linux 裸机安装示例 (amd64):
|
||
curl -fsSL https://<bastion-domain>/releases/portwardenc-amd64 -o /usr/local/bin/portwardenc
|
||
curl -fsSL https://<bastion-domain>/releases/entrypoint.sh -o /usr/local/bin/entrypoint.sh
|
||
chmod +x /usr/local/bin/portwardenc /usr/local/bin/entrypoint.sh
|
||
|
||
- Linux 裸机安装示例 (arm64):
|
||
curl -fsSL https://<bastion-domain>/releases/portwardenc-arm64 -o /usr/local/bin/portwardenc
|
||
curl -fsSL https://<bastion-domain>/releases/entrypoint.sh -o /usr/local/bin/entrypoint.sh
|
||
chmod +x /usr/local/bin/portwardenc /usr/local/bin/entrypoint.sh
|
||
|
||
- 参考 Dockerfile 片段:
|
||
ARG TARGETARCH
|
||
ADD https://<bastion-domain>/releases/portwardenc-${TARGETARCH} /usr/local/bin/portwardenc
|
||
ADD https://<bastion-domain>/releases/entrypoint.sh /usr/local/bin/entrypoint.sh
|
||
RUN chmod +x /usr/local/bin/portwardenc /usr/local/bin/entrypoint.sh
|
||
ENTRYPOINT ["/usr/local/bin/entrypoint.sh"]
|
||
|
||
环境变量示例:
|
||
PW_SERVICE_ID="svc-a" \\
|
||
PW_SERVER_ADDRS="https://bastion.example.org,https://edge.example.net" \\
|
||
PW_LOCAL_PORT="3000"
|
||
|
||
EOT
|
||
}
|
||
|
||
if [ "$1" = "--help" ] || [ "$1" = "-h" ]; then
|
||
show_help
|
||
exit 0
|
||
fi
|
||
|
||
if [ -z "$PW_SERVICE_ID" ] || [ -z "$PW_SERVER_ADDRS" ] || [ -z "$PW_LOCAL_PORT" ]; then
|
||
echo "Error: PW_SERVICE_ID, PW_SERVER_ADDRS, and PW_LOCAL_PORT must be set." >&2
|
||
echo "使用 --help 查看用法。" >&2
|
||
exit 1
|
||
fi
|
||
|
||
# 验证格式:支持 http:// 和 https://,但不允许包含路径 /portwarden
|
||
if echo "$PW_SERVER_ADDRS" | grep -qi "/portwarden"; then
|
||
echo "Error: PW_SERVER_ADDRS 不应包含路径 '/portwarden';客户端会自动添加该前缀。" >&2
|
||
exit 1
|
||
fi
|
||
if ! echo "$PW_SERVER_ADDRS" | grep -qE 'https?://'; then
|
||
echo "Error: PW_SERVER_ADDRS 必须为 http:// 或 https:// 地址。" >&2
|
||
exit 1
|
||
fi
|
||
if ! echo "$PW_LOCAL_PORT" | grep -Eq '^[0-9]+$'; then
|
||
echo "Error: PW_LOCAL_PORT 必须是数字端口,例如 8080。" >&2
|
||
exit 1
|
||
fi
|
||
|
||
|
||
# -----------------------------------------------------------------------------
|
||
# 自动安装逻辑 (Auto-Install Logic)
|
||
# -----------------------------------------------------------------------------
|
||
BINARY_PATH="/usr/local/bin/portwardenc"
|
||
|
||
if [ ! -f "$BINARY_PATH" ]; then
|
||
echo "Portwarden binary not found at $BINARY_PATH. Attempting to auto-install..."
|
||
|
||
# 1. Detect Architecture
|
||
ARCH=$(uname -m)
|
||
case $ARCH in
|
||
x86_64)
|
||
TARGET_ARCH="amd64"
|
||
;;
|
||
aarch64|arm64)
|
||
TARGET_ARCH="arm64"
|
||
;;
|
||
*)
|
||
echo "Error: Unsupported architecture: $ARCH" >&2
|
||
exit 1
|
||
;;
|
||
esac
|
||
echo "Detected architecture: $TARGET_ARCH"
|
||
|
||
# 2. Derive Download URL from PW_SERVER_ADDRS
|
||
# Take the first address from the comma-separated list
|
||
FIRST_SERVER=$(echo "$PW_SERVER_ADDRS" | cut -d',' -f1)
|
||
# Remove 'https://' prefix if present for clean URL construction (though curl handles full URL)
|
||
# Actually, we rely on the server hosting /releases/ under the same domain.
|
||
# We construct: <FIRST_SERVER>/releases/portwardenc-<TARGET_ARCH>
|
||
DOWNLOAD_URL="${FIRST_SERVER}/releases/portwardenc-${TARGET_ARCH}"
|
||
|
||
echo "Downloading from: $DOWNLOAD_URL"
|
||
|
||
# 3. Download and Install
|
||
if command -v curl >/dev/null 2>&1; then
|
||
if curl -fsSL "$DOWNLOAD_URL" -o "$BINARY_PATH"; then
|
||
chmod +x "$BINARY_PATH"
|
||
echo "Successfully installed portwardenc to $BINARY_PATH"
|
||
else
|
||
echo "Error: Failed to download portwardenc from $DOWNLOAD_URL" >&2
|
||
exit 1
|
||
fi
|
||
elif command -v wget >/dev/null 2>&1; then
|
||
if wget -qO "$BINARY_PATH" "$DOWNLOAD_URL"; then
|
||
chmod +x "$BINARY_PATH"
|
||
echo "Successfully installed portwardenc to $BINARY_PATH"
|
||
else
|
||
echo "Error: Failed to download portwardenc from $DOWNLOAD_URL" >&2
|
||
exit 1
|
||
fi
|
||
else
|
||
echo "Error: Neither curl nor wget found. Cannot auto-install." >&2
|
||
exit 1
|
||
fi
|
||
else
|
||
echo "Portwarden binary found at $BINARY_PATH. Skipping installation."
|
||
fi
|
||
|
||
export SERVER_ADDRS="$PW_SERVER_ADDRS"
|
||
export SERVICE_ID="$PW_SERVICE_ID"
|
||
export LOCAL_PORT="$PW_LOCAL_PORT"
|
||
|
||
# 注意:隧道进程现在由 docker-entrypoint.sh 管理,不再在这里启动
|
||
|
||
echo "Executing main container command: $@"
|
||
exec "$@"
|
||
|
||
|