refactor: 前后端目录结构模块化 + v2 优化移植与缺陷修复

前端:
- src/srv/api → src/api,按域分文件夹(auth/cluster/host/storage/deployment/collector)
- 新增 http.ts 引擎(http.get/post/put/delete),域模块改用语义化调用
- index.html 增加 favicon(匹配应用 logo 的 emerald + Activity 脉冲)

后端分层增强(保留包名):
- 新增 repository/:从 models 拆出 JsonDB 持久化层(InitDB/GetDB/Shutdown/RequestSave)
- 新增 dto/:从 controllers 抽出各域请求契约(带 binding 校验)
- 新增 pkg/crypto、pkg/jwt:从 utils 拆出安全原语(外部 jwt 别名 jwtv5 避免冲突)
- models 只留领域实体 + sanitizer;utils 只留 gin/应用相关(response/errors)

v2 优化移植与缺陷修复:
- 移植密钥分离/SSH TOFU/并发写安全/Loki 生产级配置/Docker 加固
- 修复 deployment.go 并发丢更新、Helm values 重复键、EncryptField 哨兵、loki-gateway 端点等审计缺陷
- 实现真正的优雅关停(main.go http.Server + signal + repository.Shutdown)
- 修复登录契约:后端返回 accessToken,前端 auth.ts/Login.tsx 对齐
- 补 crypto/jwt/repository 单元测试(含并发写回归)

验证: go build/vet/test 全绿;npm run build 通过;登录→鉴权→优雅关停冒烟通过

Co-Authored-By: Claude <noreply@anthropic.com>
This commit is contained in:
Logan.LiandClaude committed 2026-06-30 10:46:26 +08:00
1 parent fb8d10231a
commit 327e282356
93 files changed
+8433 -3089

No files matched your search

+97 -6
View File
@@ -1,24 +1,115 @@
version: '3.8'
# ============================================================
# LokiDeploy - Development Docker Compose Configuration
# ============================================================
# P0 Fixes:
# - Non-root kubeconfig mount (/home/lokideploy/.kube)
# - Healthcheck for orchestration visibility
# - Resource limits to prevent noisy-neighbor
# - security_opt: no-new-privileges
# - Log rotation (json-file driver)
# - Named volumes instead of bind mounts
# P1 Fixes:
# - Restart policy optimization
# - Network isolation
# ============================================================
services:
lokideploy:
build:
context: .
dockerfile: Dockerfile
args:
TARGETARCH: ${TARGETARCH:-amd64}
image: lokideploy:v2
container_name: lokideploy
restart: unless-stopped
hostname: lokideploy
# ---- P0: Security options ----
security_opt:
- no-new-privileges:true
cap_drop:
- ALL
cap_add:
# Required for healthcheck (wget) and runtime operations
- NET_BIND_SERVICE
# Required for file operations in /app/data
- CHOWN
- SETGID
- SETUID
read_only: false # Dev mode needs writable /app/data
ports:
- "8080:8080"
- "${SERVER_PORT:-8080}:8080"
# ---- P0: Named volumes for data persistence ----
volumes:
- ./data:/app/data
- ~/.kube:/root/.kube:ro
- lokideploy-data:/app/data
# P0: Mount kubeconfig to non-root user directory
- ${KUBECONFIG_PATH:-${HOME}/.kube}:/home/lokideploy/.kube:ro
# SSH keys for host-based deployments
- ${SSH_KEY_PATH:-${HOME}/.ssh}:/home/lokideploy/.ssh:ro
# ---- P0: Environment variables (no default secrets) ----
environment:
- SERVER_PORT=8080
- DATA_DIR=/app/data
- JWT_SECRET=change-me-in-production
# P0: JWT_SECRET must be provided externally
# Set via .env file or shell export before running docker compose up.
# 注意:错误提示里不要内嵌 $(openssl ...),否则会在 compose 解析时被执行。
- "JWT_SECRET=${JWT_SECRET:?JWT_SECRET is required. Generate: openssl rand -hex 32, then: export JWT_SECRET=<value>}"
# P0: ENCRYPTION_KEY must be provided externally (AES-256, >=32 字符)
- "ENCRYPTION_KEY=${ENCRYPTION_KEY:?ENCRYPTION_KEY is required. Generate: openssl rand -hex 32, then: export ENCRYPTION_KEY=<value>}"
# KUBECONFIG points to non-root user's .kube directory
- KUBECONFIG=/home/lokideploy/.kube/config
# ---- P0: Healthcheck ----
healthcheck:
test: ["CMD", "wget", "--no-verbose", "--tries=1", "--spider", "http://localhost:8080/index.html"]
interval: 30s
timeout: 5s
retries: 3
start_period: 15s
# ---- P0: Resource limits ----
deploy:
resources:
limits:
cpus: '2.0'
memory: 512M
pids: 100
reservations:
cpus: '0.25'
memory: 64M
# ---- P0: Log rotation ----
logging:
driver: "json-file"
options:
max-size: "50m"
max-file: "5"
labels: "service,image"
env: "SERVER_PORT,DATA_DIR"
# ---- P1: Restart policy ----
restart: unless-stopped
stop_grace_period: 15s
networks:
- lokideploy-net
# ---- Named volumes ----
volumes:
lokideploy-data:
driver: local
labels:
- "com.lokideploy.description=LokiDeploy data directory"
# ---- Network isolation ----
networks:
lokideploy-net:
driver: bridge
ipam:
config:
- subnet: 172.28.0.0/16
labels:
- "com.lokideploy.description=LokiDeploy internal network"