chore(deploy): 删除 Knative 部署配置

移除不再使用的 Knative 部署相关文件

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
This commit is contained in:
charilezhou
2026-01-19 12:33:20 +08:00
parent e9bcdaacce
commit 73db0eb809
9 changed files with 0 additions and 739 deletions

View File

@@ -1,81 +0,0 @@
# ================================================
# Seclusion API - 后端多阶段 Dockerfile
# ================================================
# Stage 1: 安装依赖
FROM node:20-alpine AS deps
WORKDIR /app
# 安装 pnpm
RUN corepack enable && corepack prepare pnpm@latest --activate
# 复制 workspace 配置文件
COPY pnpm-lock.yaml pnpm-workspace.yaml package.json ./
COPY apps/api/package.json ./apps/api/
COPY packages/shared/package.json ./packages/shared/
# 安装依赖
RUN pnpm install --frozen-lockfile
# ================================================
# Stage 2: 构建
FROM node:20-alpine AS builder
WORKDIR /app
RUN corepack enable && corepack prepare pnpm@latest --activate
# 复制依赖
COPY --from=deps /app/node_modules ./node_modules
COPY --from=deps /app/apps/api/node_modules ./apps/api/node_modules
COPY --from=deps /app/packages/shared/node_modules ./packages/shared/node_modules
# 复制源代码
COPY packages/shared ./packages/shared
COPY apps/api ./apps/api
COPY pnpm-workspace.yaml package.json tsconfig.json ./
# 构建 shared 包
RUN pnpm --filter @seclusion/shared build
# 生成 Prisma Client
RUN pnpm --filter @seclusion/api db:generate
# 构建 API
RUN pnpm --filter @seclusion/api build
# ================================================
# Stage 3: 生产镜像
FROM node:20-alpine AS runner
WORKDIR /app
# 安装 dumb-init 用于优雅关闭
RUN apk add --no-cache dumb-init
# 创建非 root 用户
RUN addgroup --system --gid 1001 nodejs && \
adduser --system --uid 1001 nestjs
# 复制 Prisma schema支持运行时迁移
COPY --from=builder /app/apps/api/prisma ./prisma
# 复制构建产物和依赖
COPY --from=builder /app/apps/api/dist ./dist
COPY --from=builder /app/apps/api/node_modules ./node_modules
COPY --from=builder /app/apps/api/package.json ./package.json
# 复制 shared 包(运行时需要)
COPY --from=builder /app/packages/shared/dist ./node_modules/@seclusion/shared/dist
COPY --from=builder /app/packages/shared/package.json ./node_modules/@seclusion/shared/package.json
# 设置用户
USER nestjs
# 环境变量
ENV NODE_ENV=production
ENV PORT=4000
EXPOSE 4000
# 使用 dumb-init 启动
ENTRYPOINT ["dumb-init", "--"]
CMD ["node", "dist/main.js"]

View File

@@ -1,88 +0,0 @@
# ================================================
# Seclusion API - Knative Service
# ================================================
apiVersion: serving.knative.dev/v1
kind: Service
metadata:
name: seclusion-api
namespace: default
labels:
app: seclusion-api
spec:
template:
metadata:
annotations:
# 允许缩容到 0
autoscaling.knative.dev/min-scale: "0"
autoscaling.knative.dev/max-scale: "10"
# 并发设置
autoscaling.knative.dev/target: "100"
# 缩容延迟(秒)
autoscaling.knative.dev/scale-down-delay: "30s"
spec:
# Harbor 私有仓库认证(如需要请取消注释)
# imagePullSecrets:
# - name: harbor-registry-secret
containerConcurrency: 100
timeoutSeconds: 300
containers:
- name: api
# 镜像地址(部署时替换)
image: harbor.example.com/seclusion/api:latest
ports:
- containerPort: 4000
protocol: TCP
# 环境变量 - 从 ConfigMap 注入
envFrom:
- configMapRef:
name: seclusion-api-config
# 环境变量 - 从 Secret 注入
env:
- name: DATABASE_URL
valueFrom:
secretKeyRef:
name: seclusion-api-secrets
key: DATABASE_URL
- name: REDIS_URL
valueFrom:
secretKeyRef:
name: seclusion-api-secrets
key: REDIS_URL
- name: JWT_SECRET
valueFrom:
secretKeyRef:
name: seclusion-api-secrets
key: JWT_SECRET
- name: ENCRYPTION_KEY
valueFrom:
secretKeyRef:
name: seclusion-api-secrets
key: ENCRYPTION_KEY
# 资源限制
resources:
requests:
memory: "256Mi"
cpu: "100m"
limits:
memory: "512Mi"
cpu: "1000m"
# 就绪探针
readinessProbe:
httpGet:
path: /api/docs
port: 4000
initialDelaySeconds: 5
periodSeconds: 10
timeoutSeconds: 5
successThreshold: 1
failureThreshold: 3
# 存活探针
livenessProbe:
httpGet:
path: /api/docs
port: 4000
initialDelaySeconds: 15
periodSeconds: 20
timeoutSeconds: 5
failureThreshold: 3

View File

@@ -1,17 +0,0 @@
# ================================================
# Seclusion API - ConfigMap
# ================================================
# 非敏感配置项
apiVersion: v1
kind: ConfigMap
metadata:
name: seclusion-api-config
namespace: default
labels:
app: seclusion-api
data:
NODE_ENV: "production"
PORT: "4000"
JWT_EXPIRES_IN: "7d"
ENABLE_ENCRYPTION: "true"

View File

@@ -1,33 +0,0 @@
# ================================================
# Seclusion API - Kubernetes Secret 模板
# ================================================
# 使用方法:
# 1. 复制此文件为 api-secrets.yaml
# 2. 将 <BASE64_ENCODED_VALUE> 替换为 Base64 编码后的真实值
# 3. 使用 echo -n "your-value" | base64 生成 Base64 值
# ================================================
apiVersion: v1
kind: Secret
metadata:
name: seclusion-api-secrets
namespace: default
labels:
app: seclusion-api
type: Opaque
data:
# PostgreSQL 连接字符串
# 示例: postgresql://user:password@host:5432/database?schema=public
DATABASE_URL: <BASE64_ENCODED_VALUE>
# Redis 连接字符串
# 示例: redis://user:password@host:6379
REDIS_URL: <BASE64_ENCODED_VALUE>
# JWT 签名密钥 (建议 32 字符以上的随机字符串)
# 生成: openssl rand -base64 32
JWT_SECRET: <BASE64_ENCODED_VALUE>
# AES-256-GCM 加密密钥 (必须是 32 字节的 Base64 编码)
# 生成: openssl rand -base64 32
ENCRYPTION_KEY: <BASE64_ENCODED_VALUE>

View File

@@ -1,20 +0,0 @@
# ================================================
# Seclusion Web - Kubernetes Secret 模板
# ================================================
# 使用方法:
# 1. 复制此文件为 web-secrets.yaml
# 2. 将 <BASE64_ENCODED_VALUE> 替换为 Base64 编码后的真实值
# ================================================
apiVersion: v1
kind: Secret
metadata:
name: seclusion-web-secrets
namespace: default
labels:
app: seclusion-web
type: Opaque
data:
# AES-256-GCM 加密密钥 (必须与后端 ENCRYPTION_KEY 相同)
# 生成: openssl rand -base64 32
NEXT_PUBLIC_ENCRYPTION_KEY: <BASE64_ENCODED_VALUE>

View File

@@ -1,82 +0,0 @@
# ================================================
# Seclusion Web - 前端多阶段 Dockerfile
# ================================================
# Stage 1: 安装依赖
FROM node:20-alpine AS deps
WORKDIR /app
# 安装 pnpm
RUN corepack enable && corepack prepare pnpm@latest --activate
# 复制 workspace 配置文件
COPY pnpm-lock.yaml pnpm-workspace.yaml package.json ./
COPY apps/web/package.json ./apps/web/
COPY packages/shared/package.json ./packages/shared/
# 安装依赖
RUN pnpm install --frozen-lockfile
# ================================================
# Stage 2: 构建
FROM node:20-alpine AS builder
WORKDIR /app
RUN corepack enable && corepack prepare pnpm@latest --activate
# 构建时环境变量(通过 ARG 注入)
ARG NEXT_PUBLIC_API_URL
ARG NEXT_PUBLIC_ENCRYPTION_KEY
ARG NEXT_PUBLIC_ENABLE_ENCRYPTION=true
ENV NEXT_PUBLIC_API_URL=${NEXT_PUBLIC_API_URL}
ENV NEXT_PUBLIC_ENCRYPTION_KEY=${NEXT_PUBLIC_ENCRYPTION_KEY}
ENV NEXT_PUBLIC_ENABLE_ENCRYPTION=${NEXT_PUBLIC_ENABLE_ENCRYPTION}
# 复制依赖
COPY --from=deps /app/node_modules ./node_modules
COPY --from=deps /app/apps/web/node_modules ./apps/web/node_modules
COPY --from=deps /app/packages/shared/node_modules ./packages/shared/node_modules
# 复制源代码
COPY packages/shared ./packages/shared
COPY apps/web ./apps/web
COPY pnpm-workspace.yaml package.json tsconfig.json ./
# 构建 shared 包
RUN pnpm --filter @seclusion/shared build
# 构建 Web
RUN pnpm --filter @seclusion/web build
# ================================================
# Stage 3: 生产镜像
FROM node:20-alpine AS runner
WORKDIR /app
# 安装 dumb-init 用于优雅关闭
RUN apk add --no-cache dumb-init
# 创建非 root 用户
RUN addgroup --system --gid 1001 nodejs && \
adduser --system --uid 1001 nextjs
# 设置环境变量
ENV NODE_ENV=production
ENV NEXT_TELEMETRY_DISABLED=1
ENV PORT=3000
ENV HOSTNAME="0.0.0.0"
# 复制 standalone 构建产物
COPY --from=builder /app/apps/web/public ./public
COPY --from=builder --chown=nextjs:nodejs /app/apps/web/.next/standalone ./
COPY --from=builder --chown=nextjs:nodejs /app/apps/web/.next/static ./apps/web/.next/static
# 设置用户
USER nextjs
EXPOSE 3000
# 使用 dumb-init 启动
ENTRYPOINT ["dumb-init", "--"]
CMD ["node", "apps/web/server.js"]

View File

@@ -1,74 +0,0 @@
# ================================================
# Seclusion Web - Knative Service
# ================================================
apiVersion: serving.knative.dev/v1
kind: Service
metadata:
name: seclusion-web
namespace: default
labels:
app: seclusion-web
spec:
template:
metadata:
annotations:
# 允许缩容到 0
autoscaling.knative.dev/min-scale: "0"
autoscaling.knative.dev/max-scale: "10"
# 并发设置
autoscaling.knative.dev/target: "100"
# 缩容延迟(秒)
autoscaling.knative.dev/scale-down-delay: "30s"
spec:
# Harbor 私有仓库认证(如需要请取消注释)
# imagePullSecrets:
# - name: harbor-registry-secret
containerConcurrency: 100
timeoutSeconds: 300
containers:
- name: web
# 镜像地址(部署时替换)
image: harbor.example.com/seclusion/web:latest
ports:
- containerPort: 3000
protocol: TCP
env:
# API 地址(指向后端 Knative Service 内部地址)
- name: NEXT_PUBLIC_API_URL
value: "http://seclusion-api.default.svc.cluster.local"
# 加密密钥(与后端相同)
- name: NEXT_PUBLIC_ENCRYPTION_KEY
valueFrom:
secretKeyRef:
name: seclusion-web-secrets
key: NEXT_PUBLIC_ENCRYPTION_KEY
- name: NEXT_PUBLIC_ENABLE_ENCRYPTION
value: "true"
# 资源限制
resources:
requests:
memory: "128Mi"
cpu: "50m"
limits:
memory: "256Mi"
cpu: "500m"
# 就绪探针
readinessProbe:
httpGet:
path: /
port: 3000
initialDelaySeconds: 5
periodSeconds: 10
timeoutSeconds: 5
successThreshold: 1
failureThreshold: 3
# 存活探针
livenessProbe:
httpGet:
path: /
port: 3000
initialDelaySeconds: 10
periodSeconds: 20
timeoutSeconds: 5
failureThreshold: 3

View File

@@ -1,141 +0,0 @@
#!/bin/bash
# ================================================
# Seclusion - Docker 镜像构建脚本
# ================================================
# 使用方法:
# ./build.sh api # 仅构建后端
# ./build.sh web # 仅构建前端
# ./build.sh all # 构建全部
# ./build.sh all --push # 构建并推送
#
# 必需环境变量:
# HARBOR_REGISTRY # Harbor 仓库地址 (如: harbor.example.com/seclusion)
# TAG # 镜像标签 (如: v1.0.0)
#
# 前端构建必需环境变量:
# NEXT_PUBLIC_API_URL # 后端 API 地址
# NEXT_PUBLIC_ENCRYPTION_KEY # 加密密钥
# ================================================
set -e
# 颜色输出
RED='\033[0;31m'
GREEN='\033[0;32m'
YELLOW='\033[1;33m'
NC='\033[0m'
# 项目根目录
SCRIPT_DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)"
PROJECT_ROOT="$(cd "$SCRIPT_DIR/../.." && pwd)"
# 默认值
HARBOR_REGISTRY="${HARBOR_REGISTRY:-harbor.example.com/seclusion}"
TAG="${TAG:-latest}"
PUSH=false
# 解析参数
TARGET=""
for arg in "$@"; do
case $arg in
api|web|all)
TARGET=$arg
;;
--push)
PUSH=true
;;
*)
echo -e "${RED}未知参数: $arg${NC}"
exit 1
;;
esac
done
if [ -z "$TARGET" ]; then
echo -e "${YELLOW}使用方法: $0 <api|web|all> [--push]${NC}"
exit 1
fi
echo -e "${GREEN}========================================${NC}"
echo -e "${GREEN}Seclusion Docker 镜像构建${NC}"
echo -e "${GREEN}========================================${NC}"
echo -e "仓库地址: ${YELLOW}$HARBOR_REGISTRY${NC}"
echo -e "镜像标签: ${YELLOW}$TAG${NC}"
echo -e "推送镜像: ${YELLOW}$PUSH${NC}"
echo ""
# 切换到项目根目录
cd "$PROJECT_ROOT"
# 构建后端
build_api() {
echo -e "${GREEN}[1/2] 构建后端镜像...${NC}"
docker build \
-f deploy/knative/api/Dockerfile \
-t "$HARBOR_REGISTRY/api:$TAG" \
.
echo -e "${GREEN}✓ 后端镜像构建完成: $HARBOR_REGISTRY/api:$TAG${NC}"
if [ "$PUSH" = true ]; then
echo -e "${YELLOW}推送后端镜像...${NC}"
docker push "$HARBOR_REGISTRY/api:$TAG"
echo -e "${GREEN}✓ 后端镜像推送完成${NC}"
fi
}
# 构建前端
build_web() {
echo -e "${GREEN}[2/2] 构建前端镜像...${NC}"
# 检查必需的环境变量
if [ -z "$NEXT_PUBLIC_API_URL" ]; then
echo -e "${RED}错误: 缺少 NEXT_PUBLIC_API_URL 环境变量${NC}"
exit 1
fi
if [ -z "$NEXT_PUBLIC_ENCRYPTION_KEY" ]; then
echo -e "${RED}错误: 缺少 NEXT_PUBLIC_ENCRYPTION_KEY 环境变量${NC}"
exit 1
fi
docker build \
-f deploy/knative/web/Dockerfile \
--build-arg NEXT_PUBLIC_API_URL="$NEXT_PUBLIC_API_URL" \
--build-arg NEXT_PUBLIC_ENCRYPTION_KEY="$NEXT_PUBLIC_ENCRYPTION_KEY" \
--build-arg NEXT_PUBLIC_ENABLE_ENCRYPTION="${NEXT_PUBLIC_ENABLE_ENCRYPTION:-true}" \
-t "$HARBOR_REGISTRY/web:$TAG" \
.
echo -e "${GREEN}✓ 前端镜像构建完成: $HARBOR_REGISTRY/web:$TAG${NC}"
if [ "$PUSH" = true ]; then
echo -e "${YELLOW}推送前端镜像...${NC}"
docker push "$HARBOR_REGISTRY/web:$TAG"
echo -e "${GREEN}✓ 前端镜像推送完成${NC}"
fi
}
# 执行构建
case $TARGET in
api)
build_api
;;
web)
build_web
;;
all)
build_api
build_web
;;
esac
echo ""
echo -e "${GREEN}========================================${NC}"
echo -e "${GREEN}构建完成!${NC}"
echo -e "${GREEN}========================================${NC}"
if [ "$PUSH" = false ]; then
echo -e "${YELLOW}提示: 使用 --push 参数可自动推送镜像到 Harbor${NC}"
fi

View File

@@ -1,203 +0,0 @@
#!/bin/bash
# ================================================
# Seclusion - Knative 部署脚本
# ================================================
# 使用方法:
# ./deploy.sh deploy # 部署服务
# ./deploy.sh migrate # 运行数据库迁移
# ./deploy.sh status # 查看服务状态
# ./deploy.sh logs <api|web> # 查看服务日志
# ./deploy.sh delete # 删除服务
#
# 必需环境变量:
# HARBOR_REGISTRY # Harbor 仓库地址
# TAG # 镜像标签
# ================================================
set -e
# 颜色输出
RED='\033[0;31m'
GREEN='\033[0;32m'
YELLOW='\033[1;33m'
BLUE='\033[0;34m'
NC='\033[0m'
# 项目根目录
SCRIPT_DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)"
KNATIVE_DIR="$(cd "$SCRIPT_DIR/../knative" && pwd)"
# 默认值
HARBOR_REGISTRY="${HARBOR_REGISTRY:-harbor.example.com/seclusion}"
TAG="${TAG:-latest}"
NAMESPACE="${NAMESPACE:-default}"
# 打印标题
print_header() {
echo -e "${GREEN}========================================${NC}"
echo -e "${GREEN}$1${NC}"
echo -e "${GREEN}========================================${NC}"
}
# 部署服务
deploy() {
print_header "Seclusion Knative 部署"
echo -e "${YELLOW}[1/4] 应用 ConfigMap...${NC}"
kubectl apply -f "$KNATIVE_DIR/configmaps/api-config.yaml" -n "$NAMESPACE"
echo -e "${YELLOW}[2/4] 应用 Secrets...${NC}"
if [ -f "$KNATIVE_DIR/secrets/api-secrets.yaml" ]; then
kubectl apply -f "$KNATIVE_DIR/secrets/api-secrets.yaml" -n "$NAMESPACE"
else
echo -e "${RED}警告: api-secrets.yaml 不存在,请从 .example 复制并填入真实值${NC}"
fi
if [ -f "$KNATIVE_DIR/secrets/web-secrets.yaml" ]; then
kubectl apply -f "$KNATIVE_DIR/secrets/web-secrets.yaml" -n "$NAMESPACE"
else
echo -e "${RED}警告: web-secrets.yaml 不存在,请从 .example 复制并填入真实值${NC}"
fi
echo -e "${YELLOW}[3/4] 部署后端服务...${NC}"
# 替换镜像地址
sed "s|image: harbor.example.com/seclusion/api:latest|image: $HARBOR_REGISTRY/api:$TAG|g" \
"$KNATIVE_DIR/api/service.yaml" | kubectl apply -f - -n "$NAMESPACE"
echo -e "${YELLOW}[4/4] 部署前端服务...${NC}"
sed "s|image: harbor.example.com/seclusion/web:latest|image: $HARBOR_REGISTRY/web:$TAG|g" \
"$KNATIVE_DIR/web/service.yaml" | kubectl apply -f - -n "$NAMESPACE"
echo ""
echo -e "${GREEN}✓ 部署完成!${NC}"
echo ""
# 等待服务就绪
echo -e "${YELLOW}等待服务就绪...${NC}"
kubectl wait --for=condition=Ready ksvc/seclusion-api -n "$NAMESPACE" --timeout=300s || true
kubectl wait --for=condition=Ready ksvc/seclusion-web -n "$NAMESPACE" --timeout=300s || true
status
}
# 运行数据库迁移
migrate() {
print_header "运行数据库迁移"
echo -e "${YELLOW}创建迁移 Job...${NC}"
# 获取当前 API 镜像
API_IMAGE="$HARBOR_REGISTRY/api:$TAG"
# 创建一次性迁移 Job
kubectl run seclusion-migrate \
--image="$API_IMAGE" \
--restart=Never \
--rm \
-i \
--env="DATABASE_URL=$(kubectl get secret seclusion-api-secrets -n $NAMESPACE -o jsonpath='{.data.DATABASE_URL}' | base64 -d)" \
-n "$NAMESPACE" \
-- npx prisma migrate deploy
echo -e "${GREEN}✓ 数据库迁移完成!${NC}"
}
# 查看服务状态
status() {
print_header "服务状态"
echo -e "${BLUE}Knative Services:${NC}"
kubectl get ksvc -n "$NAMESPACE" -l app=seclusion-api -o wide 2>/dev/null || echo "后端服务未部署"
kubectl get ksvc -n "$NAMESPACE" -l app=seclusion-web -o wide 2>/dev/null || echo "前端服务未部署"
echo ""
echo -e "${BLUE}服务 URL:${NC}"
API_URL=$(kubectl get ksvc seclusion-api -n "$NAMESPACE" -o jsonpath='{.status.url}' 2>/dev/null || echo "未获取到")
WEB_URL=$(kubectl get ksvc seclusion-web -n "$NAMESPACE" -o jsonpath='{.status.url}' 2>/dev/null || echo "未获取到")
echo -e "后端 API: ${GREEN}$API_URL${NC}"
echo -e "前端 Web: ${GREEN}$WEB_URL${NC}"
echo ""
echo -e "${BLUE}Pod 状态:${NC}"
kubectl get pods -n "$NAMESPACE" -l serving.knative.dev/service=seclusion-api 2>/dev/null || true
kubectl get pods -n "$NAMESPACE" -l serving.knative.dev/service=seclusion-web 2>/dev/null || true
}
# 查看日志
logs() {
local SERVICE=$1
if [ -z "$SERVICE" ]; then
echo -e "${RED}请指定服务: api 或 web${NC}"
exit 1
fi
print_header "查看 $SERVICE 日志"
case $SERVICE in
api)
kubectl logs -f -l serving.knative.dev/service=seclusion-api -n "$NAMESPACE" --all-containers
;;
web)
kubectl logs -f -l serving.knative.dev/service=seclusion-web -n "$NAMESPACE" --all-containers
;;
*)
echo -e "${RED}未知服务: $SERVICE${NC}"
exit 1
;;
esac
}
# 删除服务
delete() {
print_header "删除 Seclusion 服务"
echo -e "${YELLOW}确认删除所有 Seclusion 服务? [y/N]${NC}"
read -r confirm
if [ "$confirm" != "y" ] && [ "$confirm" != "Y" ]; then
echo "取消删除"
exit 0
fi
echo -e "${YELLOW}删除 Knative Services...${NC}"
kubectl delete ksvc seclusion-api seclusion-web -n "$NAMESPACE" --ignore-not-found
echo -e "${YELLOW}删除 ConfigMaps...${NC}"
kubectl delete configmap seclusion-api-config -n "$NAMESPACE" --ignore-not-found
echo -e "${YELLOW}删除 Secrets...${NC}"
kubectl delete secret seclusion-api-secrets seclusion-web-secrets -n "$NAMESPACE" --ignore-not-found
echo -e "${GREEN}✓ 删除完成!${NC}"
}
# 主入口
case "${1:-}" in
deploy)
deploy
;;
migrate)
migrate
;;
status)
status
;;
logs)
logs "$2"
;;
delete)
delete
;;
*)
echo -e "${YELLOW}使用方法: $0 <deploy|migrate|status|logs|delete>${NC}"
echo ""
echo "命令:"
echo " deploy 部署 Knative 服务"
echo " migrate 运行数据库迁移"
echo " status 查看服务状态"
echo " logs <api|web> 查看服务日志"
echo " delete 删除所有服务"
exit 1
;;
esac