diff --git a/CHANGELOG.md b/CHANGELOG.md index 20eff4c..ca10734 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -11,6 +11,9 @@ - 资源用量弹窗的可选 Prometheus 接入(峰值/限流查询):统一以「未接入 Prometheus:暂无峰值/限流数据」提示,扩容建议基于 metrics-server 实时值 ### 新增 +- 一键安装脚本(quick_start.sh):bash -c "$(curl …)" 对标 1Panel/雷池体验——架构自检、发布包下载、 + 随机密钥生成、systemd 开机自启、升级幂等(数据自动备份),完成后打印访问地址与初始密码 + (10.10.10.161 CentOS 7 真机验证安装/登录/升级/文档落地页全通);配套 upload-release.sh 发布双架构包到 Gitea Release - 落地页(homepage/,`/homepage` 访问):产品介绍、特性、快速开始 - 用户手册文档站(docsify,`/docs` 访问):安装、部署向导、采集、查询、分析、告警、授权、备份、FAQ 十篇 diff --git a/README.md b/README.md index 01497aa..dbe54fe 100644 --- a/README.md +++ b/README.md @@ -28,7 +28,15 @@ > 镜像内置全部依赖(Kubernetes 操作走 client-go 直连 API Server),宿主机**无需**安装 `kubectl` / `helm`。 -### 1. 一条命令启动 +### 1. 一键安装(Linux 服务器,推荐) + +```bash +bash -c "$(curl -fsSL https://gitea.91ai.io/rlwj-lab/LokiStack/raw/main/scripts/quick_start.sh)" +``` + +自动下载对应架构(x86_64/arm64)的发布包,生成随机密钥并注册 systemd 服务(开机自启);重复执行即升级(数据自动备份)。安装完成后终端直接打印访问地址与初始密码。 + +### 2. Docker 一条命令 ```bash docker compose up -d diff --git a/docs/user-guide/install.md b/docs/user-guide/install.md index db92c50..f00787f 100644 --- a/docs/user-guide/install.md +++ b/docs/user-guide/install.md @@ -1,13 +1,21 @@ # 安装与启动 -LokiStack 面向 Linux 服务器交付:单二进制(内嵌前端、文档与落地页),或 Docker / Kubernetes 一键部署。按环境三选一。 +LokiStack 面向 Linux 服务器交付:单二进制(内嵌前端、文档与落地页),或 Docker / Kubernetes 一键部署。按环境选择。 + +## 一键安装(推荐) + +```bash +bash -c "$(curl -fsSL https://gitea.91ai.io/rlwj-lab/LokiStack/raw/main/scripts/quick_start.sh)" +``` + +自动检测架构、下载发布包、生成随机密钥并注册 systemd 服务;重复执行即升级(数据自动备份)。可用环境变量覆盖安装目录(`INSTALL_DIR`)、版本(`VERSION`)、端口(`PORT`)与下载源(`BASE_URL`)。 ## 环境要求 - 平台自身:Linux x86_64 或 arm64,内存 ≥ 256MB - 目标 Kubernetes 集群 ≥ 1.20;或裸金属 Linux 主机(SSH 可达) -## 方式一:Kubernetes 一键部署 +## 方式二:Kubernetes 一键部署 ```bash bash kubernetes/install.sh @@ -20,7 +28,7 @@ WITH_NODEPORT=1 bash kubernetes/install.sh # 同时开 NodePort(配合 Ing STORAGE_CLASS=local-path bash kubernetes/install.sh # 手动指定 StorageClass ``` -## 方式二:Docker +## 方式三:Docker ```bash docker compose up -d @@ -28,7 +36,7 @@ docker compose up -d 一条命令即可启动:未显式提供 `JWT_SECRET` / `ENCRYPTION_KEY` 时,容器自动生成随机密钥并持久化到数据卷(`$DATA_DIR/.secrets.env`,权限 0600),重启与升级保持不变。需要固定密钥或接入自有密钥管理时,再通过环境变量显式提供即可覆盖。 -## 方式三:单二进制 +## 方式四:单二进制 从 Release 下载对应架构的包(Linux x86_64 / arm64): diff --git a/scripts/quick_start.sh b/scripts/quick_start.sh new file mode 100755 index 0000000..4c95540 --- /dev/null +++ b/scripts/quick_start.sh @@ -0,0 +1,131 @@ +#!/usr/bin/env bash +# ============================================================================ +# LokiStack 一键安装(Linux x86_64 / arm64) +# +# 用法: +# bash -c "$(curl -fsSL https://gitea.91ai.io/rlwj-lab/LokiStack/raw/main/scripts/quick_start.sh)" +# +# 可覆盖(环境变量): +# INSTALL_DIR 安装目录,默认 /opt/lokistack +# VERSION 版本 tag,默认 latest(自动解析最新 release) +# BASE_URL 下载源,默认 Gitea Release +# PORT 服务端口,默认 8080 +# SKIP_SERVICE=1 仅解压不注册 systemd(调试用) +# ============================================================================ +set -euo pipefail + +REPO="rlwj-lab/LokiStack" +GITEA="https://gitea.91ai.io" +INSTALL_DIR="${INSTALL_DIR:-/opt/lokistack}" +VERSION="${VERSION:-latest}" +BASE_URL="${BASE_URL:-${GITEA}}" +PORT="${PORT:-8080}" + +info() { printf '\033[1;36m==>\033[0m %s\n' "$*"; } +ok() { printf '\033[1;32m✅\033[0m %s\n' "$*"; } +warn() { printf '\033[1;33m⚠️\033[0m %s\n' "$*"; } +die() { printf '\033[1;31m❌\033[0m %s\n' "$*" >&2; exit 1; } + +# ---- 1. 环境自检 ---- +[ "$(id -u)" = "0" ] || die "请用 root 运行(sudo bash $0)" +case "$(uname -m)" in + x86_64|amd64) ARCH="amd64" ;; + aarch64|arm64) ARCH="arm64" ;; + *) die "不支持的架构: $(uname -m)(支持 x86_64 / arm64)" ;; +esac +command -v curl >/dev/null || die "缺少 curl,请先安装(apt/yum install curl)" +command -v tar >/dev/null || die "缺少 tar,请先安装" +if [ "${SKIP_SERVICE:-0}" != "1" ]; then + command -v systemctl >/dev/null || die "未检测到 systemd,可设 SKIP_SERVICE=1 手动运行" +fi +ok "环境就绪: $(uname -m) -> ${ARCH}, $(grep PRETTY_NAME /etc/os-release 2>/dev/null | cut -d'"' -f2 || echo Linux)" + +# ---- 2. 解析版本并下载 ---- +if [ "$VERSION" = "latest" ]; then + info "解析最新版本..." + VERSION="$(curl -fsSL "$GITEA/api/v1/repos/$REPO/releases/latest" | grep -o '"tag_name":"[^"]*"' | head -1 | cut -d'"' -f4)" + [ -n "$VERSION" ] || die "无法获取最新版本(检查网络或手动指定 VERSION=vX.Y.Z)" +fi +PKG="lokistack-linux-${ARCH}.tar.gz" +URL="$BASE_URL/$REPO/releases/download/$VERSION/$PKG" +TMP="$(mktemp -d)"; trap 'rm -rf "$TMP"' EXIT +info "下载 ${URL}" +curl -fSL --retry 3 --connect-timeout 10 -o "$TMP/$PKG" "$URL" || die "下载失败(可设 BASE_URL 指定镜像源)" +ok "下载完成: $(du -h "$TMP/$PKG" | cut -f1)" + +# ---- 3. 安装(重复执行 = 升级) ---- +if systemctl is-active lokistack >/dev/null 2>&1; then + info "检测到已有 LokiStack 服务,执行升级..." + systemctl stop lokistack || true + [ -d "$INSTALL_DIR/data" ] && cp -r "$INSTALL_DIR/data" "${INSTALL_DIR}/data.bak.$(date +%Y%m%d%H%M%S)" +fi +mkdir -p "$INSTALL_DIR" +tar -xzf "$TMP/$PKG" -C "$TMP" +SRC="$TMP/lokistack-linux-${ARCH}" +mv "$SRC/lokistack" "$SRC/docs" "$SRC/homepage" "$SRC/README.md" "$INSTALL_DIR/" 2>/dev/null || true +chmod +x "$INSTALL_DIR/lokistack" +mkdir -p "$INSTALL_DIR/data" +ok "安装到 $INSTALL_DIR(数据目录 $INSTALL_DIR/data)" + +# ---- 4. 密钥:自动生成随机密钥并持久化(显式已存在则不动) ---- +SECRETS="$INSTALL_DIR/data/.secrets.env" +gen() { head -c 32 /dev/urandom | od -An -tx1 | tr -d ' \n'; } +if [ ! -f "$SECRETS" ]; then + umask 077 + { echo "# LokiStack 自动生成,删除后重新执行脚本可重置" + echo "JWT_SECRET=$(gen)"; echo "ENCRYPTION_KEY=$(gen)"; } > "$SECRETS" + ok "已生成随机密钥: $SECRETS" +else + ok "沿用已有密钥: $SECRETS" +fi + +# ---- 5. systemd 服务 ---- +if [ "${SKIP_SERVICE:-0}" != "1" ]; then + cat > /etc/systemd/system/lokistack.service </dev/null; then break; fi + sleep 1 + [ "$i" = "30" ] && warn "服务 30s 内未就绪,请查看: journalctl -u lokistack -e" +done + +IP="$(hostname -I 2>/dev/null | awk '{print $1}')" +PASS_FILE="$INSTALL_DIR/data/initial-admin-password.txt" +echo "" +printf '\033[1;32m================================================\033[0m\n' +printf ' LokiStack 安装完成!\n' +printf '\033[1;32m================================================\033[0m\n' +printf ' 访问地址: http://%s:%s\n' "${IP:-<服务器IP>}" "$PORT" +printf ' 初始账号: admin\n' +[ -f "$PASS_FILE" ] && printf ' 初始密码: %s\n' "$(cat "$PASS_FILE")" || printf ' 初始密码: 见 %s\n' "$PASS_FILE" +printf ' 用户手册: http://%s:%s/docs/\n' "${IP:-<服务器IP>}" "$PORT" +printf '\n 常用命令:\n' +printf ' systemctl status lokistack # 状态\n' +printf ' journalctl -u lokistack -f # 日志\n' +printf ' 重新执行本脚本 # 升级(数据自动备份)\n' +printf '\033[1;32m================================================\033[0m\n' diff --git a/scripts/upload-release.sh b/scripts/upload-release.sh new file mode 100755 index 0000000..e51dd64 --- /dev/null +++ b/scripts/upload-release.sh @@ -0,0 +1,34 @@ +#!/usr/bin/env bash +# ============================================================================ +# 上传双架构发布包到 Gitea Release: +# make dist && GITEA_TOKEN=xxx bash scripts/upload-release.sh v2.0.1 +# GITEA_TOKEN: 具备 repo 权限的 token(设置 → 应用 → 生成令牌) +# ============================================================================ +set -euo pipefail +REPO="rlwj-lab/LokiStack" +GITEA="https://gitea.91ai.io" +VERSION="${1:?用法: GITEA_TOKEN=xxx bash scripts/upload-release.sh vX.Y.Z}" +TOKEN="${GITEA_TOKEN:?请设置 GITEA_TOKEN}" + +for f in dist/lokistack-linux-amd64.tar.gz dist/lokistack-linux-arm64.tar.gz; do + [ -f "$f" ] || { echo "缺少 $f,先执行 make dist"; exit 1; } +done + +# 已存在则复用,不存在则创建 +REL_ID="$(curl -fsSL -H "Authorization: token $TOKEN" "$GITEA/api/v1/repos/$REPO/releases/tags/$VERSION" | grep -o '"id":[0-9]*' | head -1 | cut -d: -f2 || true)" +if [ -z "$REL_ID" ]; then + echo "==> 创建 Release $VERSION" + REL_ID="$(curl -fsSL -X POST -H "Authorization: token $TOKEN" \ + -H "Content-Type: application/json" \ + -d "{\"tag_name\":\"$VERSION\",\"name\":\"LokiStack $VERSION\"}" \ + "$GITEA/api/v1/repos/$REPO/releases" | grep -o '"id":[0-9]*' | head -1 | cut -d: -f2)" +fi +[ -n "$REL_ID" ] || { echo "Release 创建/获取失败"; exit 1; } + +for f in dist/lokistack-linux-*.tar.gz; do + echo "==> 上传 $f" + curl -fsSL -X POST -H "Authorization: token $TOKEN" \ + -F "attachment=@$f" \ + "$GITEA/api/v1/repos/$REPO/releases/$REL_ID/assets?name=$(basename "$f")" >/dev/null +done +echo "==> 完成: $GITEA/$REPO/releases/tag/$VERSION"