feat: SeaweedFS 替代 MinIO,Authentik ForwardAuth,多服务升级
新增: - SeaweedFS v4.28 替代 MinIO (域名 file.xiteng.site) - Authentik Outpost (Uptime Kuma + SeaweedFS 独立实例) - ForwardAuth 为 Uptime Kuma 和 SeaweedFS 提供认证 - gpu-exporter.py 监控脚本 升级: - Traefik v3.6 → v3.7 - Authentik 固定版本 2026.5.0 + trusted proxy CIDR - HedgeDoc PG 11 → 16,添加 OIDC 认证 - Homepage 添加 OIDC 认证 安全: - Outpost token 迁移至 .env 引用(不再硬编码) - .gitignore 扩展覆盖数据/缓存/旧 MinIO - security.toml 清理注释掉的旧密钥 移除: - MinIO(已全部迁移至 SeaweedFS)
This commit is contained in:
+15
@@ -26,4 +26,19 @@ frpc/frpc.toml
|
||||
|
||||
# 忽略 Traefik 证书
|
||||
traefik/letsencrypt/
|
||||
|
||||
# 忽略数据库持久化数据
|
||||
authentik/pgdata/
|
||||
authentik/redis/
|
||||
authentik/media/
|
||||
gitea/db_data/
|
||||
hedgedoc/data_pg11_backup/
|
||||
|
||||
# 忽略旧 MinIO(已迁移至 SeaweedFS)
|
||||
minio/
|
||||
|
||||
# 忽略 SeaweedFS 运行时数据
|
||||
seaweedfs/data/
|
||||
|
||||
# 忽略 AI 工具
|
||||
.aider*
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
services:
|
||||
authentik:
|
||||
image: ghcr.io/goauthentik/server:latest
|
||||
image: ghcr.io/goauthentik/server:2026.5.0
|
||||
container_name: authentik
|
||||
restart: unless-stopped
|
||||
command: server
|
||||
@@ -14,6 +14,7 @@ services:
|
||||
AUTHENTIK_POSTGRESQL__PASSWORD: ${AUTHENTIK_DB_PASSWORD}
|
||||
AUTHENTIK_AVATARS: none
|
||||
AUTHENTIK_LOG_LEVEL: info
|
||||
AUTHENTIK_SECURITY__TRUSTED_PROXY_CIDR: 172.18.0.0/16
|
||||
volumes:
|
||||
- ./media:/media
|
||||
- ./custom-templates:/templates
|
||||
@@ -25,6 +26,10 @@ services:
|
||||
- "traefik.http.routers.authentik.entrypoints=websecure"
|
||||
- "traefik.http.routers.authentik.tls=true"
|
||||
- "traefik.http.routers.authentik.tls.certresolver=cfresolver"
|
||||
# 强制 X-Forwarded-Proto 为 https(Tunnel 走 HTTP:80 入口,Traefik 不知道外层是 HTTPS)
|
||||
- "traefik.http.middlewares.force-https-headers.headers.customrequestheaders.X-Forwarded-Proto=https"
|
||||
- "traefik.http.routers.authentik.middlewares=force-https-headers"
|
||||
- "traefik.http.routers.authentik-http.middlewares=force-https-headers"
|
||||
# --- HTTP 入口 ---
|
||||
- "traefik.http.routers.authentik-http.rule=Host(`auth.xiteng.site`)"
|
||||
- "traefik.http.routers.authentik-http.service=authentik"
|
||||
|
||||
+24
-7
@@ -1,8 +1,10 @@
|
||||
services:
|
||||
db:
|
||||
image: postgres:11.6-alpine
|
||||
env_file:
|
||||
- ../.env
|
||||
hedgedoc-db:
|
||||
image: postgres:16-alpine
|
||||
environment:
|
||||
- POSTGRES_USER=$POSTGRES_USER
|
||||
- POSTGRES_PASSWORD=$POSTGRES_PASSWORD
|
||||
- POSTGRES_DB=$POSTGRES_DB
|
||||
container_name: hedgedoc_db
|
||||
restart: unless-stopped
|
||||
volumes:
|
||||
@@ -14,17 +16,32 @@ services:
|
||||
image: quay.io/hedgedoc/hedgedoc:latest
|
||||
container_name: hedgedoc
|
||||
restart: unless-stopped
|
||||
env_file:
|
||||
- ../.env
|
||||
environment:
|
||||
- CMD_DB_HOST=hedgedoc_db
|
||||
- CMD_DB_PORT=5432
|
||||
- CMD_DB_DATABASE=$POSTGRES_DB
|
||||
- CMD_DB_USERNAME=$POSTGRES_USER
|
||||
- CMD_DB_PASSWORD=$POSTGRES_PASSWORD
|
||||
- CMD_DB_DIALECT=postgres
|
||||
- CMD_DOMAIN=notes.xiteng.site
|
||||
- CMD_URL_ADDPORT=false
|
||||
- CMD_ALLOW_ORIGIN=localhost,notes.xiteng.site
|
||||
- CMD_PROTOCOL_USESSL=true
|
||||
- CMD_OAUTH2_PROVIDERNAME=Authentik
|
||||
- CMD_OAUTH2_CLIENT_ID=hedgedoc-280baa8d
|
||||
- CMD_OAUTH2_CLIENT_SECRET=0630f01b111d4ad68ff9b2d174028994decb5b55b51a4556bda24768d11b4586
|
||||
- CMD_OAUTH2_AUTHORIZATION_URL=https://auth.xiteng.site/application/o/authorize/
|
||||
- CMD_OAUTH2_TOKEN_URL=https://auth.xiteng.site/application/o/token/
|
||||
- CMD_OAUTH2_USER_PROFILE_URL=https://auth.xiteng.site/application/o/userinfo/
|
||||
- CMD_OAUTH2_SCOPE=openid profile email
|
||||
- CMD_OAUTH2_ISSUER=https://auth.xiteng.site/application/o/hedgedoc/
|
||||
- CMD_OAUTH2_USER_PROFILE_USERNAME_ATTR=preferred_username
|
||||
- CMD_OAUTH2_USER_PROFILE_DISPLAY_NAME_ATTR=name
|
||||
- CMD_OAUTH2_USER_PROFILE_EMAIL_ATTR=email
|
||||
volumes:
|
||||
- ./uploads:/hedgedoc/public/uploads
|
||||
depends_on:
|
||||
- db
|
||||
- hedgedoc-db
|
||||
ports:
|
||||
- "3000:3000"
|
||||
labels:
|
||||
|
||||
@@ -5,11 +5,17 @@ services:
|
||||
restart: unless-stopped
|
||||
volumes:
|
||||
- ./config:/app/config
|
||||
- ./config/icons:/app/public/icons:ro
|
||||
- /var/run/docker.sock:/var/run/docker.sock:ro
|
||||
ports:
|
||||
- "3003:3000"
|
||||
environment:
|
||||
- HOMEPAGE_ALLOWED_HOSTS=home.xiteng.site,xiteng.site
|
||||
- HOMEPAGE_AUTH_PROVIDER=oidc
|
||||
- HOMEPAGE_AUTH_OIDC_ISSUER=https://auth.xiteng.site/application/o/homepage/
|
||||
- HOMEPAGE_AUTH_OIDC_CLIENT_ID=homepage-64bfd7a7
|
||||
- HOMEPAGE_AUTH_OIDC_CLIENT_SECRET=b5d710941dba4a4694a92fe7bc381f3c853a248b5114467d9b82b0953928326b
|
||||
- HOMEPAGE_AUTH_OIDC_SCOPE=openid profile email
|
||||
labels:
|
||||
# --- 1. Traefik 路由设置 ---
|
||||
- "traefik.enable=true"
|
||||
|
||||
@@ -0,0 +1,35 @@
|
||||
#!/usr/bin/env python3
|
||||
"""Serve NVIDIA GPU stats as JSON for Homepage customapi widget."""
|
||||
import subprocess, json
|
||||
from http.server import HTTPServer, BaseHTTPRequestHandler
|
||||
|
||||
class GPUHandler(BaseHTTPRequestHandler):
|
||||
def do_GET(self):
|
||||
try:
|
||||
r = subprocess.run(
|
||||
['nvidia-smi', '--query-gpu=utilization.gpu,memory.used,memory.total,temperature.gpu,fan.speed',
|
||||
'--format=csv,noheader,nounits'],
|
||||
capture_output=True, text=True, timeout=5
|
||||
)
|
||||
parts = [p.strip() for p in r.stdout.strip().split(',')]
|
||||
data = {
|
||||
'gpu_util': parts[0] + '%',
|
||||
'mem_used': parts[1],
|
||||
'mem_total': parts[2],
|
||||
'mem': f'{parts[1]} / {parts[2]} MiB',
|
||||
'temp': parts[3] + '°C',
|
||||
'fan': parts[4] + '%',
|
||||
}
|
||||
except Exception as e:
|
||||
data = {'error': str(e)}
|
||||
|
||||
self.send_response(200)
|
||||
self.send_header('Content-Type', 'application/json')
|
||||
self.send_header('Access-Control-Allow-Origin', '*')
|
||||
self.end_headers()
|
||||
self.wfile.write(json.dumps(data).encode())
|
||||
|
||||
def log_message(self, format, *args):
|
||||
pass # suppress logs
|
||||
|
||||
HTTPServer(('0.0.0.0', 9999), GPUHandler).serve_forever()
|
||||
@@ -1,52 +0,0 @@
|
||||
services:
|
||||
minio:
|
||||
image: minio/minio:latest
|
||||
env_file:
|
||||
- ../.env
|
||||
container_name: minio
|
||||
restart: unless-stopped
|
||||
volumes:
|
||||
- ./data:/data
|
||||
command: server /data --console-address ":9001"
|
||||
ports:
|
||||
- "9000:9000"
|
||||
- "9001:9001"
|
||||
labels:
|
||||
# --- Traefik: Console (9001) ---
|
||||
- "traefik.enable=true"
|
||||
- "traefik.http.routers.minio.rule=Host(`minio.xiteng.site`)"
|
||||
- "traefik.http.services.minio.loadbalancer.server.port=9001"
|
||||
- "traefik.http.routers.minio.entrypoints=websecure"
|
||||
- "traefik.http.routers.minio.tls=true"
|
||||
- "traefik.http.routers.minio.tls.certresolver=cfresolver"
|
||||
# --- Traefik: HTTP 入口(cloudflared tunnel)---
|
||||
- "traefik.http.routers.minio-http.rule=Host(`minio.xiteng.site`)"
|
||||
- "traefik.http.routers.minio-http.service=minio"
|
||||
- "traefik.http.routers.minio-http.entrypoints=web"
|
||||
# --- Traefik: API (9000) ---
|
||||
- "traefik.http.routers.minio-api.rule=Host(`minio-api.xiteng.site`)"
|
||||
- "traefik.http.services.minio-api.loadbalancer.server.port=9000"
|
||||
- "traefik.http.routers.minio-api.entrypoints=websecure"
|
||||
- "traefik.http.routers.minio-api.tls=true"
|
||||
- "traefik.http.routers.minio-api.tls.certresolver=cfresolver"
|
||||
# --- Traefik: API HTTP 入口 ---
|
||||
- "traefik.http.routers.minio-api-http.rule=Host(`minio-api.xiteng.site`)"
|
||||
- "traefik.http.routers.minio-api-http.service=minio-api"
|
||||
- "traefik.http.routers.minio-api-http.entrypoints=web"
|
||||
# --- Homepage ---
|
||||
- "homepage.group=我的服务"
|
||||
- "homepage.name=MinIO"
|
||||
- "homepage.icon=minio"
|
||||
- "homepage.href=https://minio.xiteng.site"
|
||||
- "homepage.description=对象存储"
|
||||
# --- AutoKuma ---
|
||||
- "kuma.minio.http.name=MinIO"
|
||||
- "kuma.minio.http.url=http://minio:9000"
|
||||
- "kuma.minio.http.interval=60"
|
||||
- "kuma.minio.http.max_retries=3"
|
||||
networks:
|
||||
- homelab_net
|
||||
|
||||
networks:
|
||||
homelab_net:
|
||||
external: true
|
||||
@@ -0,0 +1,17 @@
|
||||
services:
|
||||
outpost:
|
||||
image: ghcr.io/goauthentik/proxy:2026.5.0
|
||||
container_name: authentik-outpost-seaweedfs
|
||||
restart: unless-stopped
|
||||
environment:
|
||||
AUTHENTIK_HOST: https://auth.xiteng.site
|
||||
AUTHENTIK_TOKEN: ${AUTHENTIK_OUTPOST_SEAWEEDFS_TOKEN}
|
||||
AUTHENTIK_INSECURE: "true"
|
||||
ports:
|
||||
- "9003:9000"
|
||||
networks:
|
||||
- homelab_net
|
||||
|
||||
networks:
|
||||
homelab_net:
|
||||
external: true
|
||||
@@ -0,0 +1,29 @@
|
||||
services:
|
||||
outpost:
|
||||
image: ghcr.io/goauthentik/proxy:2026.5.0
|
||||
container_name: authentik-outpost
|
||||
restart: unless-stopped
|
||||
environment:
|
||||
AUTHENTIK_HOST: https://auth.xiteng.site
|
||||
AUTHENTIK_TOKEN: ${AUTHENTIK_OUTPOST_TOKEN}
|
||||
AUTHENTIK_INSECURE: "true"
|
||||
ports:
|
||||
- "9002:9000"
|
||||
- "9443:9443"
|
||||
labels:
|
||||
# --- Outpost 自身管理界面 ---
|
||||
- "traefik.enable=true"
|
||||
- "traefik.http.routers.outpost.rule=Host(`outpost.xiteng.site`)"
|
||||
- "traefik.http.services.outpost.loadbalancer.server.port=9000"
|
||||
- "traefik.http.routers.outpost.entrypoints=websecure"
|
||||
- "traefik.http.routers.outpost.tls=true"
|
||||
- "traefik.http.routers.outpost.tls.certresolver=cfresolver"
|
||||
- "traefik.http.routers.outpost-http.rule=Host(`outpost.xiteng.site`)"
|
||||
- "traefik.http.routers.outpost-http.service=outpost"
|
||||
- "traefik.http.routers.outpost-http.entrypoints=web"
|
||||
networks:
|
||||
- homelab_net
|
||||
|
||||
networks:
|
||||
homelab_net:
|
||||
external: true
|
||||
@@ -0,0 +1,60 @@
|
||||
services:
|
||||
seaweedfs:
|
||||
image: chrislusf/seaweedfs:latest
|
||||
container_name: seaweedfs
|
||||
restart: unless-stopped
|
||||
command: "server -s3 -s3.port=8333 -master.port=9333 -volume.port=8080 -filer -filer.port=8888 -dir=/data -s3.domainName=file.xiteng.site"
|
||||
environment:
|
||||
- WEED_SECURITY_CONFIG=/etc/seaweedfs/security.toml
|
||||
volumes:
|
||||
- ./data:/data
|
||||
- ./security.toml:/etc/seaweedfs/security.toml:ro
|
||||
ports:
|
||||
- "9333:9333" # master
|
||||
- "8081:8080" # volume
|
||||
- "8888:8888" # filer
|
||||
- "8333:8333" # s3
|
||||
labels:
|
||||
- "traefik.enable=true"
|
||||
# --- Traefik: S3 Console (带 Authentik ForwardAuth) ---
|
||||
- "traefik.http.routers.minio.rule=Host(`file.xiteng.site`)"
|
||||
- "traefik.http.services.minio.loadbalancer.server.port=8888"
|
||||
- "traefik.http.routers.minio.entrypoints=websecure"
|
||||
- "traefik.http.routers.minio.tls=true"
|
||||
- "traefik.http.routers.minio.tls.certresolver=cfresolver"
|
||||
- "traefik.http.routers.minio-http.rule=Host(`file.xiteng.site`)"
|
||||
- "traefik.http.routers.minio-http.service=minio"
|
||||
- "traefik.http.routers.minio-http.entrypoints=web"
|
||||
# --- ForwardAuth:显式转发 Cookie 头给 outpost ---
|
||||
- "traefik.http.middlewares.minio-scheme.headers.customrequestheaders.X-Forwarded-Proto=https"
|
||||
- "traefik.http.middlewares.minio-auth.forwardauth.address=http://authentik-outpost-seaweedfs:9000/outpost.goauthentik.io/auth/traefik"
|
||||
- "traefik.http.middlewares.minio-auth.forwardauth.trustForwardHeader=true"
|
||||
- "traefik.http.middlewares.minio-auth.forwardauth.authResponseHeaders=X-authentik-username,X-authentik-groups,X-authentik-email,X-authentik-name"
|
||||
- "traefik.http.routers.minio.middlewares=minio-scheme,minio-auth"
|
||||
- "traefik.http.routers.minio-http.middlewares=minio-scheme,minio-auth"
|
||||
# --- Traefik: S3 API (8333) ---
|
||||
- "traefik.http.routers.minio-api.rule=Host(`minio-api.xiteng.site`)"
|
||||
- "traefik.http.services.minio-api.loadbalancer.server.port=8333"
|
||||
- "traefik.http.routers.minio-api.entrypoints=websecure"
|
||||
- "traefik.http.routers.minio-api.tls=true"
|
||||
- "traefik.http.routers.minio-api.tls.certresolver=cfresolver"
|
||||
- "traefik.http.routers.minio-api-http.rule=Host(`minio-api.xiteng.site`)"
|
||||
- "traefik.http.routers.minio-api-http.service=minio-api"
|
||||
- "traefik.http.routers.minio-api-http.entrypoints=web"
|
||||
# --- Homepage ---
|
||||
- "homepage.group=我的服务"
|
||||
- "homepage.name=SeaweedFS"
|
||||
- "homepage.icon=/icons/seaweedfs-local.png"
|
||||
- "homepage.href=https://file.xiteng.site"
|
||||
- "homepage.description=对象存储"
|
||||
# --- AutoKuma ---
|
||||
- "kuma.minio.http.name=SeaweedFS"
|
||||
- "kuma.minio.http.url=http://seaweedfs:8888"
|
||||
- "kuma.minio.http.interval=60"
|
||||
- "kuma.minio.http.max_retries=3"
|
||||
networks:
|
||||
- homelab_net
|
||||
|
||||
networks:
|
||||
homelab_net:
|
||||
external: true
|
||||
@@ -0,0 +1,3 @@
|
||||
# Homelab Security Configuration
|
||||
# All JWT sections are commented out — filer UI auth is handled by Authentik ForwardAuth.
|
||||
# See README.md for architecture details.
|
||||
+1
-1
@@ -1,6 +1,6 @@
|
||||
services:
|
||||
traefik:
|
||||
image: traefik:v3.6
|
||||
image: traefik:v3.7
|
||||
container_name: traefik
|
||||
restart: unless-stopped
|
||||
env_file: ../.env
|
||||
|
||||
@@ -17,6 +17,12 @@ services:
|
||||
- "traefik.http.routers.uptime.rule=Host(`uptime.xiteng.site`)"
|
||||
- "traefik.http.services.uptime.loadbalancer.server.port=3001"
|
||||
- "traefik.http.routers.uptime.entrypoints=websecure"
|
||||
# ForwardAuth via Authentik Outpost
|
||||
- "traefik.http.middlewares.authentik-auth.forwardauth.address=http://authentik-outpost:9000/outpost.goauthentik.io/auth/traefik"
|
||||
- "traefik.http.middlewares.authentik-auth.forwardauth.trustForwardHeader=true"
|
||||
- "traefik.http.middlewares.authentik-auth.forwardauth.authResponseHeaders=X-authentik-username,X-authentik-groups,X-authentik-email,X-authentik-name"
|
||||
- "traefik.http.routers.uptime.middlewares=authentik-auth"
|
||||
- "traefik.http.routers.uptime-http.middlewares=authentik-auth"
|
||||
- "traefik.http.routers.uptime-http.rule=Host(`uptime.xiteng.site`)"
|
||||
- "traefik.http.routers.uptime-http.service=uptime"
|
||||
- "traefik.http.routers.uptime-http.entrypoints=web"
|
||||
@@ -25,7 +31,7 @@ services:
|
||||
- "homepage.group=我的服务"
|
||||
- "homepage.name=Uptime Kuma"
|
||||
- "homepage.icon=uptime-kuma"
|
||||
- "homepage.href=https://status.xiteng.site"
|
||||
- "homepage.href=https://uptime.xiteng.site"
|
||||
- "homepage.description=网站监控工具"
|
||||
networks:
|
||||
- homelab_net
|
||||
|
||||
Reference in New Issue
Block a user