feat(install): 一键安装脚本 — 对标 1Panel/雷池体验
bash -c "$(curl -fsSL …/scripts/quick_start.sh)" 一条命令: 架构自检(x86_64/arm64)→ 发布包下载(默认 Gitea Release,可镜像)→ 随机密钥生成持久化 → systemd 开机自启 → 健康等待 → 打印访问地址/初始密码/常用命令;重复执行即升级(数据自动备份)。 CentOS 7 真机验证:安装、登录、文档/落地页、升级幂等全通。 配套 upload-release.sh(make dist 后一键发布双架构包到 Gitea Release);README/手册/CHANGELOG 同步。
This commit is contained in:
1 parent
0936234623
commit
88b2ac2a6d
5 files changed
+189
-5
No files matched your search
@@ -11,6 +11,9 @@
|
|||||||
- 资源用量弹窗的可选 Prometheus 接入(峰值/限流查询):统一以「未接入 Prometheus:暂无峰值/限流数据」提示,扩容建议基于 metrics-server 实时值
|
- 资源用量弹窗的可选 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` 访问):产品介绍、特性、快速开始
|
- 落地页(homepage/,`/homepage` 访问):产品介绍、特性、快速开始
|
||||||
- 用户手册文档站(docsify,`/docs` 访问):安装、部署向导、采集、查询、分析、告警、授权、备份、FAQ 十篇
|
- 用户手册文档站(docsify,`/docs` 访问):安装、部署向导、采集、查询、分析、告警、授权、备份、FAQ 十篇
|
||||||
|
|
||||||
|
|||||||
@@ -28,7 +28,15 @@
|
|||||||
|
|
||||||
> 镜像内置全部依赖(Kubernetes 操作走 client-go 直连 API Server),宿主机**无需**安装 `kubectl` / `helm`。
|
> 镜像内置全部依赖(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
|
```bash
|
||||||
docker compose up -d
|
docker compose up -d
|
||||||
|
|||||||
@@ -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
|
- 平台自身:Linux x86_64 或 arm64,内存 ≥ 256MB
|
||||||
- 目标 Kubernetes 集群 ≥ 1.20;或裸金属 Linux 主机(SSH 可达)
|
- 目标 Kubernetes 集群 ≥ 1.20;或裸金属 Linux 主机(SSH 可达)
|
||||||
|
|
||||||
## 方式一:Kubernetes 一键部署
|
## 方式二:Kubernetes 一键部署
|
||||||
|
|
||||||
```bash
|
```bash
|
||||||
bash kubernetes/install.sh
|
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
|
STORAGE_CLASS=local-path bash kubernetes/install.sh # 手动指定 StorageClass
|
||||||
```
|
```
|
||||||
|
|
||||||
## 方式二:Docker
|
## 方式三:Docker
|
||||||
|
|
||||||
```bash
|
```bash
|
||||||
docker compose up -d
|
docker compose up -d
|
||||||
@@ -28,7 +36,7 @@ docker compose up -d
|
|||||||
|
|
||||||
一条命令即可启动:未显式提供 `JWT_SECRET` / `ENCRYPTION_KEY` 时,容器自动生成随机密钥并持久化到数据卷(`$DATA_DIR/.secrets.env`,权限 0600),重启与升级保持不变。需要固定密钥或接入自有密钥管理时,再通过环境变量显式提供即可覆盖。
|
一条命令即可启动:未显式提供 `JWT_SECRET` / `ENCRYPTION_KEY` 时,容器自动生成随机密钥并持久化到数据卷(`$DATA_DIR/.secrets.env`,权限 0600),重启与升级保持不变。需要固定密钥或接入自有密钥管理时,再通过环境变量显式提供即可覆盖。
|
||||||
|
|
||||||
## 方式三:单二进制
|
## 方式四:单二进制
|
||||||
|
|
||||||
从 Release 下载对应架构的包(Linux x86_64 / arm64):
|
从 Release 下载对应架构的包(Linux x86_64 / arm64):
|
||||||
|
|
||||||
|
|||||||
Executable
+131
@@ -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 <<UNIT
|
||||||
|
[Unit]
|
||||||
|
Description=LokiStack - Loki 日志管理平台
|
||||||
|
After=network-online.target
|
||||||
|
Wants=network-online.target
|
||||||
|
|
||||||
|
[Service]
|
||||||
|
Type=simple
|
||||||
|
WorkingDirectory=$INSTALL_DIR
|
||||||
|
EnvironmentFile=$SECRETS
|
||||||
|
Environment=DATA_DIR=$INSTALL_DIR/data
|
||||||
|
Environment=SERVER_PORT=$PORT
|
||||||
|
ExecStart=$INSTALL_DIR/lokistack
|
||||||
|
Restart=on-failure
|
||||||
|
RestartSec=5
|
||||||
|
LimitNOFILE=65535
|
||||||
|
|
||||||
|
[Install]
|
||||||
|
WantedBy=multi-user.target
|
||||||
|
UNIT
|
||||||
|
systemctl daemon-reload
|
||||||
|
systemctl enable --now lokistack
|
||||||
|
ok "服务已启动并设为开机自启"
|
||||||
|
fi
|
||||||
|
|
||||||
|
# ---- 6. 等待健康检查并输出摘要 ----
|
||||||
|
info "等待服务就绪..."
|
||||||
|
for i in $(seq 1 30); do
|
||||||
|
if curl -fs -o /dev/null "http://127.0.0.1:$PORT/api/v1/health" 2>/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'
|
||||||
Executable
+34
@@ -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"
|
||||||
Reference in new issue
Block a user