Deploy: migrate k3s → Docker; search logic → master-agents-svc
- deploy/k3s удалён, deploy/docker добавлен (Caddyfile, docker-compose, searxng) - chat-svc: agents/models/prompts удалены, использует llm-svc (LLMClient, EmbeddingClient) - master-agents-svc: SearchOrchestrator, classifier, researcher, actions, widgets - web-svc: ChatModelSelector, Optimization, Sources удалены; InputBarPlus; UnregisterSW - geo-device-svc, localization-svc: Dockerfiles - docs: 02-k3s-services-spec.md, RUNBOOK/TELEMETRY/WORKING удалены Co-authored-by: Cursor <cursoragent@cursor.com>
This commit is contained in:
7
deploy/docker/Caddyfile
Normal file
7
deploy/docker/Caddyfile
Normal file
@@ -0,0 +1,7 @@
|
||||
# gooseek.ru — reverse proxy к web-svc
|
||||
# Caddy автоматически получает SSL от Let's Encrypt
|
||||
|
||||
gooseek.ru, www.gooseek.ru {
|
||||
header Cache-Control "no-cache, no-store, must-revalidate"
|
||||
reverse_proxy web-svc:3000
|
||||
}
|
||||
251
deploy/docker/docker-compose.yml
Normal file
251
deploy/docker/docker-compose.yml
Normal file
@@ -0,0 +1,251 @@
|
||||
# GooSeek — запуск в Docker (без Kubernetes)
|
||||
# gooseek.ru → reverse-proxy (80/443) → web-svc:3000
|
||||
#
|
||||
# Запуск: ./deploy/docker/run.sh
|
||||
# Порты 80 и 443 должны быть открыты на роутере (проброс на ПК)
|
||||
|
||||
services:
|
||||
reverse-proxy:
|
||||
image: caddy:2-alpine
|
||||
container_name: gooseek-reverse-proxy
|
||||
ports:
|
||||
- "80:80"
|
||||
- "443:443"
|
||||
volumes:
|
||||
- ./Caddyfile:/etc/caddy/Caddyfile
|
||||
- caddy-data:/data
|
||||
- caddy-config:/config
|
||||
depends_on:
|
||||
- web-svc
|
||||
restart: unless-stopped
|
||||
|
||||
web-svc:
|
||||
build:
|
||||
context: ../..
|
||||
dockerfile: services/web-svc/Dockerfile
|
||||
args:
|
||||
API_GATEWAY_URL: "http://api-gateway:3015"
|
||||
image: gooseek/web-svc:latest
|
||||
container_name: gooseek-web-svc
|
||||
ports:
|
||||
- "127.0.0.1:3000:3000"
|
||||
environment:
|
||||
PORT: "3000"
|
||||
API_GATEWAY_URL: "http://api-gateway:3015"
|
||||
depends_on:
|
||||
- api-gateway
|
||||
restart: unless-stopped
|
||||
|
||||
api-gateway:
|
||||
build:
|
||||
context: ../../services/api-gateway
|
||||
dockerfile: Dockerfile
|
||||
image: gooseek/api-gateway:latest
|
||||
container_name: gooseek-api-gateway
|
||||
ports:
|
||||
- "3015:3015"
|
||||
environment:
|
||||
PORT: "3015"
|
||||
AUTH_SVC_URL: "http://auth-svc:3014"
|
||||
LLM_SVC_URL: "http://llm-svc:3020"
|
||||
CHAT_SVC_URL: "http://chat-svc:3005"
|
||||
MASTER_AGENTS_SVC_URL: "http://master-agents-svc:3018"
|
||||
LIBRARY_SVC_URL: "http://library-svc:3009"
|
||||
DISCOVER_SVC_URL: "http://discover-svc:3002"
|
||||
SEARCH_SVC_URL: "http://search-svc:3001"
|
||||
FINANCE_SVC_URL: "http://finance-svc:3003"
|
||||
TRAVEL_SVC_URL: "http://travel-svc:3004"
|
||||
CREATE_SVC_URL: "http://create-svc:3011"
|
||||
MEMORY_SVC_URL: "http://memory-svc:3010"
|
||||
PROJECTS_SVC_URL: "http://projects-svc:3006"
|
||||
NOTIFICATIONS_SVC_URL: "http://notifications-svc:3013"
|
||||
BILLING_SVC_URL: "http://billing-svc:3008"
|
||||
AUDIT_SVC_URL: "http://audit-svc:3012"
|
||||
GEO_DEVICE_URL: "http://geo-device-svc:4002"
|
||||
LOCALIZATION_SVC_URL: "http://localization-svc:4003"
|
||||
ALLOWED_ORIGINS: "http://localhost:3000,http://127.0.0.1:3000,https://gooseek.ru,https://www.gooseek.ru"
|
||||
depends_on:
|
||||
- auth-svc
|
||||
- llm-svc
|
||||
- chat-svc
|
||||
restart: unless-stopped
|
||||
|
||||
geo-device-svc:
|
||||
build:
|
||||
context: ../../services/geo-device-svc
|
||||
dockerfile: Dockerfile
|
||||
image: gooseek/geo-device-svc:latest
|
||||
container_name: gooseek-geo-device-svc
|
||||
ports:
|
||||
- "4002:4002"
|
||||
environment:
|
||||
PORT: "4002"
|
||||
restart: unless-stopped
|
||||
|
||||
localization-svc:
|
||||
build:
|
||||
context: ../../services/localization-svc
|
||||
dockerfile: Dockerfile
|
||||
image: gooseek/localization-svc:latest
|
||||
container_name: gooseek-localization-svc
|
||||
ports:
|
||||
- "4003:4003"
|
||||
environment:
|
||||
PORT: "4003"
|
||||
GEO_DEVICE_SVC_URL: "http://geo-device-svc:4002"
|
||||
depends_on:
|
||||
- geo-device-svc
|
||||
restart: unless-stopped
|
||||
|
||||
discover-svc:
|
||||
build:
|
||||
context: ../../services/discover-svc
|
||||
dockerfile: Dockerfile
|
||||
image: gooseek/discover-svc:latest
|
||||
container_name: gooseek-discover-svc
|
||||
ports:
|
||||
- "3002:3002"
|
||||
environment:
|
||||
PORT: "3002"
|
||||
REDIS_URL: "redis://redis:6379"
|
||||
GEO_DEVICE_SERVICE_URL: "http://geo-device-svc:4002"
|
||||
depends_on:
|
||||
- redis
|
||||
- geo-device-svc
|
||||
restart: unless-stopped
|
||||
|
||||
travel-svc:
|
||||
build:
|
||||
context: ../../services/travel-svc
|
||||
dockerfile: Dockerfile
|
||||
image: gooseek/travel-svc:latest
|
||||
container_name: gooseek-travel-svc
|
||||
ports:
|
||||
- "3004:3004"
|
||||
environment:
|
||||
PORT: "3004"
|
||||
REDIS_URL: "redis://redis:6379"
|
||||
depends_on:
|
||||
- redis
|
||||
restart: unless-stopped
|
||||
|
||||
auth-svc:
|
||||
build:
|
||||
context: ../..
|
||||
dockerfile: services/auth-svc/Dockerfile
|
||||
image: gooseek/auth-svc:latest
|
||||
container_name: gooseek-auth-svc
|
||||
ports:
|
||||
- "3014:3014"
|
||||
environment:
|
||||
PORT: "3014"
|
||||
BETTER_AUTH_URL: "https://gooseek.ru"
|
||||
TRUSTED_ORIGINS: "http://localhost:3000,http://127.0.0.1:3000,https://gooseek.ru,https://www.gooseek.ru"
|
||||
DATABASE_PATH: "/data/auth.db"
|
||||
BETTER_AUTH_TELEMETRY: "0"
|
||||
volumes:
|
||||
- auth-data:/data
|
||||
restart: unless-stopped
|
||||
|
||||
llm-svc:
|
||||
build:
|
||||
context: ../../services/llm-svc
|
||||
dockerfile: Dockerfile
|
||||
image: gooseek/llm-svc:latest
|
||||
container_name: gooseek-llm-svc
|
||||
env_file:
|
||||
- ../../.env
|
||||
ports:
|
||||
- "3020:3020"
|
||||
environment:
|
||||
PORT: "3020"
|
||||
DATA_DIR: "/app/data"
|
||||
volumes:
|
||||
- llm-data:/app/data
|
||||
extra_hosts:
|
||||
- "host.docker.internal:host-gateway"
|
||||
restart: unless-stopped
|
||||
|
||||
redis:
|
||||
image: redis:7-alpine
|
||||
container_name: gooseek-redis
|
||||
ports:
|
||||
- "6379:6379"
|
||||
volumes:
|
||||
- redis-data:/data
|
||||
restart: unless-stopped
|
||||
|
||||
searxng:
|
||||
image: searxng/searxng:latest
|
||||
container_name: gooseek-searxng
|
||||
ports:
|
||||
- "8080:8080"
|
||||
volumes:
|
||||
- ./searxng/settings.yml:/etc/searxng/settings.yml:ro
|
||||
- ./searxng/limiter.toml:/etc/searxng/limiter.toml:ro
|
||||
- searxng-cache:/var/cache/searxng
|
||||
environment:
|
||||
SEARXNG_BASE_URL: "http://localhost:8080/"
|
||||
restart: unless-stopped
|
||||
|
||||
search-svc:
|
||||
build:
|
||||
context: ../../services/search-svc
|
||||
dockerfile: Dockerfile
|
||||
image: gooseek/search-svc:latest
|
||||
container_name: gooseek-search-svc
|
||||
ports:
|
||||
- "3001:3001"
|
||||
environment:
|
||||
PORT: "3001"
|
||||
REDIS_URL: "redis://redis:6379"
|
||||
SEARXNG_URL: "http://searxng:8080"
|
||||
depends_on:
|
||||
- redis
|
||||
- searxng
|
||||
restart: unless-stopped
|
||||
|
||||
master-agents-svc:
|
||||
build:
|
||||
context: ../../services/master-agents-svc
|
||||
dockerfile: Dockerfile
|
||||
image: gooseek/master-agents-svc:latest
|
||||
container_name: gooseek-master-agents-svc
|
||||
ports:
|
||||
- "3018:3018"
|
||||
environment:
|
||||
PORT: "3018"
|
||||
LLM_SVC_URL: "http://llm-svc:3020"
|
||||
SEARCH_SVC_URL: "http://search-svc:3001"
|
||||
depends_on:
|
||||
- llm-svc
|
||||
- search-svc
|
||||
restart: unless-stopped
|
||||
|
||||
chat-svc:
|
||||
build:
|
||||
context: ../../services/chat-svc
|
||||
dockerfile: Dockerfile
|
||||
image: gooseek/chat-svc:latest
|
||||
container_name: gooseek-chat-svc
|
||||
ports:
|
||||
- "3005:3005"
|
||||
environment:
|
||||
PORT: "3005"
|
||||
MASTER_AGENTS_SVC_URL: "http://master-agents-svc:3018"
|
||||
LLM_SVC_URL: "http://llm-svc:3020"
|
||||
volumes:
|
||||
- chat-data:/app/data
|
||||
depends_on:
|
||||
- master-agents-svc
|
||||
- llm-svc
|
||||
restart: unless-stopped
|
||||
|
||||
volumes:
|
||||
auth-data:
|
||||
llm-data:
|
||||
redis-data:
|
||||
chat-data:
|
||||
caddy-data:
|
||||
caddy-config:
|
||||
searxng-cache:
|
||||
61
deploy/docker/run.sh
Executable file
61
deploy/docker/run.sh
Executable file
@@ -0,0 +1,61 @@
|
||||
#!/usr/bin/env bash
|
||||
# Запуск GooSeek в Docker (без Kubernetes)
|
||||
# Сервисы из deploy/k3s/deploy.config.yaml (true)
|
||||
#
|
||||
# Использование:
|
||||
# ./deploy/docker/run.sh # полный build + up
|
||||
# ./deploy/docker/run.sh --web # только web-svc (кнопки, UI) — быстро
|
||||
# ./deploy/docker/run.sh --up # только up (без build)
|
||||
# ./deploy/docker/run.sh --down # остановить
|
||||
#
|
||||
# BuildKit + --no-cache: при деплое старый кэш не используется, сборка всегда свежая
|
||||
|
||||
set -e
|
||||
export DOCKER_BUILDKIT=1
|
||||
|
||||
SCRIPT_DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)"
|
||||
REPO_ROOT="$(cd "$SCRIPT_DIR/../.." && pwd)"
|
||||
COMPOSE_FILE="$SCRIPT_DIR/docker-compose.yml"
|
||||
|
||||
cd "$REPO_ROOT"
|
||||
|
||||
case "${1:-}" in
|
||||
--web)
|
||||
docker compose -f "$COMPOSE_FILE" build --no-cache web-svc
|
||||
docker compose -f "$COMPOSE_FILE" up -d --force-recreate web-svc reverse-proxy
|
||||
echo ""
|
||||
echo "web-svc пересобран и перезапущен. Обнови страницу (Ctrl+Shift+R)."
|
||||
;;
|
||||
--down)
|
||||
docker compose -f "$COMPOSE_FILE" down
|
||||
echo "Остановлено."
|
||||
;;
|
||||
--up)
|
||||
docker compose -f "$COMPOSE_FILE" up -d
|
||||
echo ""
|
||||
echo "Сервисы запущены:"
|
||||
echo " web-svc: http://localhost:3000"
|
||||
echo " api-gateway: http://localhost:3015"
|
||||
echo " auth-svc: http://localhost:3014"
|
||||
echo " llm-svc: http://localhost:3020"
|
||||
echo " chat-svc: http://localhost:3005"
|
||||
echo " master-agents: http://localhost:3018"
|
||||
echo " search-svc: http://localhost:3001"
|
||||
;;
|
||||
*)
|
||||
docker compose -f "$COMPOSE_FILE" build --no-cache
|
||||
docker compose -f "$COMPOSE_FILE" up -d --force-recreate
|
||||
echo ""
|
||||
echo "Сервисы запущены:"
|
||||
echo " web-svc: http://localhost:3000"
|
||||
echo " api-gateway: http://localhost:3015"
|
||||
echo " auth-svc: http://localhost:3014"
|
||||
echo " llm-svc: http://localhost:3020"
|
||||
echo " chat-svc: http://localhost:3005"
|
||||
echo " master-agents: http://localhost:3018"
|
||||
echo " search-svc: http://localhost:3001"
|
||||
echo " redis: localhost:6379"
|
||||
echo ""
|
||||
echo "LLM: настройте .env (LLM_PROVIDER=timeweb или ollama)."
|
||||
;;
|
||||
esac
|
||||
18
deploy/docker/searxng/limiter.toml
Normal file
18
deploy/docker/searxng/limiter.toml
Normal file
@@ -0,0 +1,18 @@
|
||||
# GooSeek — разрешить запросы из Docker/частных сетей
|
||||
[botdetection]
|
||||
trusted_proxies = [
|
||||
'127.0.0.0/8',
|
||||
'::1',
|
||||
'10.0.0.0/8',
|
||||
'172.16.0.0/12',
|
||||
'192.168.0.0/16',
|
||||
'fd00::/8',
|
||||
]
|
||||
|
||||
[botdetection.ip_lists]
|
||||
pass_ip = [
|
||||
'127.0.0.0/8',
|
||||
'10.0.0.0/8',
|
||||
'172.16.0.0/12',
|
||||
'192.168.0.0/16',
|
||||
]
|
||||
9
deploy/docker/searxng/settings.yml
Normal file
9
deploy/docker/searxng/settings.yml
Normal file
@@ -0,0 +1,9 @@
|
||||
# GooSeek — SearXNG для внутреннего использования (search-svc)
|
||||
# https://docs.searxng.org/admin/settings/
|
||||
use_default_settings: true
|
||||
search:
|
||||
formats: [html, json, csv, rss]
|
||||
server:
|
||||
secret_key: "gooseek-searxng-internal"
|
||||
limiter: false
|
||||
image_proxy: true
|
||||
@@ -1,85 +0,0 @@
|
||||
# api-gateway — прокси к микросервисам
|
||||
# namespace: gooseek
|
||||
apiVersion: apps/v1
|
||||
kind: Deployment
|
||||
metadata:
|
||||
name: api-gateway
|
||||
namespace: gooseek
|
||||
spec:
|
||||
replicas: 1
|
||||
selector:
|
||||
matchLabels:
|
||||
app: api-gateway
|
||||
template:
|
||||
metadata:
|
||||
labels:
|
||||
app: api-gateway
|
||||
spec:
|
||||
containers:
|
||||
- name: api-gateway
|
||||
image: gooseek/api-gateway:latest
|
||||
imagePullPolicy: Never
|
||||
ports:
|
||||
- containerPort: 3015
|
||||
env:
|
||||
- name: PORT
|
||||
value: "3015"
|
||||
- name: CHAT_SVC_URL
|
||||
value: "http://chat-svc.gooseek:3005"
|
||||
- name: LIBRARY_SVC_URL
|
||||
value: "http://library-svc.gooseek:3009"
|
||||
- name: DISCOVER_SVC_URL
|
||||
value: "http://discover-svc.gooseek:3002"
|
||||
- name: SEARCH_SVC_URL
|
||||
value: "http://search-svc.gooseek:3001"
|
||||
- name: FINANCE_SVC_URL
|
||||
value: "http://finance-svc.gooseek:3003"
|
||||
- name: TRAVEL_SVC_URL
|
||||
value: "http://travel-svc.gooseek:3004"
|
||||
- name: CREATE_SVC_URL
|
||||
value: "http://create-svc.gooseek:3011"
|
||||
- name: MEMORY_SVC_URL
|
||||
value: "http://memory-svc.gooseek:3010"
|
||||
- name: PROJECTS_SVC_URL
|
||||
value: "http://projects-svc.gooseek:3006"
|
||||
- name: NOTIFICATIONS_SVC_URL
|
||||
value: "http://notifications-svc.gooseek:3013"
|
||||
- name: BILLING_SVC_URL
|
||||
value: "http://billing-svc.gooseek:3008"
|
||||
- name: AUDIT_SVC_URL
|
||||
value: "http://audit-svc.gooseek:3012"
|
||||
- name: AUTH_SVC_URL
|
||||
value: "http://auth-svc.gooseek-auth:3014"
|
||||
- name: PROFILE_SVC_URL
|
||||
value: "http://profile-svc.gooseek:3019"
|
||||
- name: LLM_SVC_URL
|
||||
value: "http://llm-svc.gooseek:3020"
|
||||
- name: ALLOWED_ORIGINS
|
||||
valueFrom:
|
||||
configMapKeyRef:
|
||||
name: gooseek-env
|
||||
key: allowed-origins
|
||||
livenessProbe:
|
||||
httpGet:
|
||||
path: /health
|
||||
port: 3015
|
||||
initialDelaySeconds: 5
|
||||
periodSeconds: 10
|
||||
readinessProbe:
|
||||
httpGet:
|
||||
path: /ready
|
||||
port: 3015
|
||||
initialDelaySeconds: 3
|
||||
periodSeconds: 5
|
||||
---
|
||||
apiVersion: v1
|
||||
kind: Service
|
||||
metadata:
|
||||
name: api-gateway
|
||||
namespace: gooseek
|
||||
spec:
|
||||
selector:
|
||||
app: api-gateway
|
||||
ports:
|
||||
- port: 3015
|
||||
targetPort: 3015
|
||||
@@ -1,60 +0,0 @@
|
||||
# audit-svc — Enterprise audit logs
|
||||
# docs/architecture: 02-k3s-microservices-spec.md §3.13
|
||||
apiVersion: apps/v1
|
||||
kind: Deployment
|
||||
metadata:
|
||||
name: audit-svc
|
||||
namespace: gooseek
|
||||
spec:
|
||||
replicas: 1
|
||||
selector:
|
||||
matchLabels:
|
||||
app: audit-svc
|
||||
template:
|
||||
metadata:
|
||||
labels:
|
||||
app: audit-svc
|
||||
annotations:
|
||||
prometheus.io/scrape: "true"
|
||||
prometheus.io/port: "3012"
|
||||
prometheus.io/path: "/metrics"
|
||||
spec:
|
||||
containers:
|
||||
- name: audit-svc
|
||||
image: gooseek/audit-svc:latest
|
||||
ports:
|
||||
- containerPort: 3012
|
||||
env:
|
||||
- name: PORT
|
||||
value: "3012"
|
||||
livenessProbe:
|
||||
httpGet:
|
||||
path: /health
|
||||
port: 3012
|
||||
initialDelaySeconds: 5
|
||||
periodSeconds: 10
|
||||
readinessProbe:
|
||||
httpGet:
|
||||
path: /ready
|
||||
port: 3012
|
||||
initialDelaySeconds: 3
|
||||
periodSeconds: 5
|
||||
resources:
|
||||
requests:
|
||||
cpu: 50m
|
||||
memory: 128Mi
|
||||
limits:
|
||||
cpu: 500m
|
||||
memory: 512Mi
|
||||
---
|
||||
apiVersion: v1
|
||||
kind: Service
|
||||
metadata:
|
||||
name: audit-svc
|
||||
namespace: gooseek
|
||||
spec:
|
||||
selector:
|
||||
app: audit-svc
|
||||
ports:
|
||||
- port: 3012
|
||||
targetPort: 3012
|
||||
@@ -1,94 +0,0 @@
|
||||
# auth-svc — SSO, JWT, Bearer validation (better-auth)
|
||||
# namespace: gooseek-auth
|
||||
# BETTER_AUTH_URL — для callback/redirect (https://gooseek.ru)
|
||||
# docs/architecture: 02-k3s-microservices-spec.md
|
||||
apiVersion: apps/v1
|
||||
kind: Deployment
|
||||
metadata:
|
||||
name: auth-svc
|
||||
namespace: gooseek-auth
|
||||
spec:
|
||||
replicas: 1
|
||||
selector:
|
||||
matchLabels:
|
||||
app: auth-svc
|
||||
template:
|
||||
metadata:
|
||||
labels:
|
||||
app: auth-svc
|
||||
spec:
|
||||
containers:
|
||||
- name: auth-svc
|
||||
image: gooseek/auth-svc:latest
|
||||
imagePullPolicy: Never
|
||||
ports:
|
||||
- containerPort: 3014
|
||||
env:
|
||||
- name: PORT
|
||||
value: "3014"
|
||||
- name: BETTER_AUTH_URL
|
||||
valueFrom:
|
||||
configMapKeyRef:
|
||||
name: gooseek-env
|
||||
key: better-auth-url
|
||||
- name: AUTH_SERVICE_URL
|
||||
value: "http://auth-svc.gooseek-auth:3014"
|
||||
- name: TRUSTED_ORIGINS
|
||||
valueFrom:
|
||||
configMapKeyRef:
|
||||
name: gooseek-env
|
||||
key: trusted-origins
|
||||
- name: DATABASE_PATH
|
||||
value: "/data/auth.db"
|
||||
- name: BETTER_AUTH_TELEMETRY
|
||||
value: "0"
|
||||
volumeMounts:
|
||||
- name: auth-data
|
||||
mountPath: /data
|
||||
livenessProbe:
|
||||
httpGet:
|
||||
path: /health
|
||||
port: 3014
|
||||
initialDelaySeconds: 5
|
||||
periodSeconds: 10
|
||||
readinessProbe:
|
||||
httpGet:
|
||||
path: /ready
|
||||
port: 3014
|
||||
initialDelaySeconds: 3
|
||||
periodSeconds: 5
|
||||
resources:
|
||||
requests:
|
||||
cpu: 50m
|
||||
memory: 128Mi
|
||||
limits:
|
||||
cpu: 500m
|
||||
memory: 512Mi
|
||||
volumes:
|
||||
- name: auth-data
|
||||
persistentVolumeClaim:
|
||||
claimName: auth-data-pvc
|
||||
---
|
||||
apiVersion: v1
|
||||
kind: Service
|
||||
metadata:
|
||||
name: auth-svc
|
||||
namespace: gooseek-auth
|
||||
spec:
|
||||
selector:
|
||||
app: auth-svc
|
||||
ports:
|
||||
- port: 3014
|
||||
targetPort: 3014
|
||||
---
|
||||
apiVersion: v1
|
||||
kind: PersistentVolumeClaim
|
||||
metadata:
|
||||
name: auth-data-pvc
|
||||
namespace: gooseek-auth
|
||||
spec:
|
||||
accessModes:
|
||||
- ReadWriteOnce
|
||||
resources:
|
||||
requests:
|
||||
storage: 1Gi
|
||||
@@ -1,74 +0,0 @@
|
||||
# billing-svc — тарифы, подписки, ЮKassa
|
||||
# docs/architecture: 02-k3s-microservices-spec.md §3.10
|
||||
apiVersion: apps/v1
|
||||
kind: Deployment
|
||||
metadata:
|
||||
name: billing-svc
|
||||
namespace: gooseek
|
||||
spec:
|
||||
replicas: 2
|
||||
selector:
|
||||
matchLabels:
|
||||
app: billing-svc
|
||||
template:
|
||||
metadata:
|
||||
labels:
|
||||
app: billing-svc
|
||||
spec:
|
||||
containers:
|
||||
- name: billing-svc
|
||||
image: gooseek/billing-svc:latest
|
||||
imagePullPolicy: Never
|
||||
ports:
|
||||
- containerPort: 3008
|
||||
env:
|
||||
- name: PORT
|
||||
value: "3008"
|
||||
- name: POSTGRES_URL
|
||||
valueFrom:
|
||||
secretKeyRef:
|
||||
name: db-credentials
|
||||
key: url
|
||||
- name: AUTH_SERVICE_URL
|
||||
value: "http://auth-svc.gooseek-auth:3014"
|
||||
- name: YOOKASSA_SHOP_ID
|
||||
valueFrom:
|
||||
secretKeyRef:
|
||||
name: yookassa-credentials
|
||||
key: shop_id
|
||||
- name: YOOKASSA_SECRET
|
||||
valueFrom:
|
||||
secretKeyRef:
|
||||
name: yookassa-credentials
|
||||
key: secret
|
||||
livenessProbe:
|
||||
httpGet:
|
||||
path: /health
|
||||
port: 3008
|
||||
initialDelaySeconds: 5
|
||||
periodSeconds: 10
|
||||
readinessProbe:
|
||||
httpGet:
|
||||
path: /ready
|
||||
port: 3008
|
||||
initialDelaySeconds: 3
|
||||
periodSeconds: 5
|
||||
resources:
|
||||
requests:
|
||||
cpu: 50m
|
||||
memory: 128Mi
|
||||
limits:
|
||||
cpu: 500m
|
||||
memory: 512Mi
|
||||
---
|
||||
apiVersion: v1
|
||||
kind: Service
|
||||
metadata:
|
||||
name: billing-svc
|
||||
namespace: gooseek
|
||||
spec:
|
||||
selector:
|
||||
app: billing-svc
|
||||
ports:
|
||||
- port: 3008
|
||||
targetPort: 3008
|
||||
@@ -1,85 +0,0 @@
|
||||
# cache-worker — pre-compute discover, finance, travel
|
||||
# docs/architecture: 02-k3s-microservices-spec.md §3.15, 05-gaps-and-best-practices §6
|
||||
# activeDeadlineSeconds защищает от зависших задач
|
||||
|
||||
---
|
||||
apiVersion: batch/v1
|
||||
kind: CronJob
|
||||
metadata:
|
||||
name: cache-worker-finance
|
||||
namespace: gooseek
|
||||
spec:
|
||||
schedule: "*/2 * * * *"
|
||||
concurrencyPolicy: Forbid
|
||||
jobTemplate:
|
||||
spec:
|
||||
activeDeadlineSeconds: 300
|
||||
template:
|
||||
spec:
|
||||
restartPolicy: OnFailure
|
||||
containers:
|
||||
- name: cache-worker
|
||||
image: gooseek/cache-worker:latest
|
||||
args: ["--task=finance"]
|
||||
env:
|
||||
- name: REDIS_URL
|
||||
valueFrom:
|
||||
secretKeyRef:
|
||||
name: redis-credentials
|
||||
key: url
|
||||
- name: FINANCE_SVC_URL
|
||||
value: "http://finance-svc.gooseek:3003"
|
||||
---
|
||||
apiVersion: batch/v1
|
||||
kind: CronJob
|
||||
metadata:
|
||||
name: cache-worker-discover
|
||||
namespace: gooseek
|
||||
spec:
|
||||
schedule: "*/15 * * * *"
|
||||
concurrencyPolicy: Forbid
|
||||
jobTemplate:
|
||||
spec:
|
||||
activeDeadlineSeconds: 600
|
||||
template:
|
||||
spec:
|
||||
restartPolicy: OnFailure
|
||||
containers:
|
||||
- name: cache-worker
|
||||
image: gooseek/cache-worker:latest
|
||||
args: ["--task=discover"]
|
||||
env:
|
||||
- name: REDIS_URL
|
||||
valueFrom:
|
||||
secretKeyRef:
|
||||
name: redis-credentials
|
||||
key: url
|
||||
- name: DISCOVER_SVC_URL
|
||||
value: "http://discover-svc.gooseek:3002"
|
||||
---
|
||||
apiVersion: batch/v1
|
||||
kind: CronJob
|
||||
metadata:
|
||||
name: cache-worker-travel
|
||||
namespace: gooseek
|
||||
spec:
|
||||
schedule: "0 */4 * * *"
|
||||
concurrencyPolicy: Forbid
|
||||
jobTemplate:
|
||||
spec:
|
||||
activeDeadlineSeconds: 1200
|
||||
template:
|
||||
spec:
|
||||
restartPolicy: OnFailure
|
||||
containers:
|
||||
- name: cache-worker
|
||||
image: gooseek/cache-worker:latest
|
||||
args: ["--task=travel"]
|
||||
env:
|
||||
- name: REDIS_URL
|
||||
valueFrom:
|
||||
secretKeyRef:
|
||||
name: redis-credentials
|
||||
key: url
|
||||
- name: TRAVEL_SVC_URL
|
||||
value: "http://travel-svc.gooseek:3004"
|
||||
@@ -1,103 +0,0 @@
|
||||
# chat-svc — LLM, Mastra, Writer, Classifier, Researcher
|
||||
# docs/architecture: 02-k3s-microservices-spec.md
|
||||
# Frontend при CHAT_SVC_URL проксирует /api/chat сюда
|
||||
apiVersion: apps/v1
|
||||
kind: Deployment
|
||||
metadata:
|
||||
name: chat-svc
|
||||
namespace: gooseek
|
||||
spec:
|
||||
replicas: 2
|
||||
selector:
|
||||
matchLabels:
|
||||
app: chat-svc
|
||||
template:
|
||||
metadata:
|
||||
labels:
|
||||
app: chat-svc
|
||||
annotations:
|
||||
prometheus.io/scrape: "true"
|
||||
prometheus.io/port: "3005"
|
||||
prometheus.io/path: "/metrics"
|
||||
spec:
|
||||
containers:
|
||||
- name: chat-svc
|
||||
image: gooseek/chat-svc:latest
|
||||
ports:
|
||||
- containerPort: 3005
|
||||
env:
|
||||
- name: PORT
|
||||
value: "3005"
|
||||
- name: DATA_DIR
|
||||
value: "/app/data"
|
||||
- name: SEARCH_SVC_URL
|
||||
value: "http://search-svc.gooseek:3001"
|
||||
- name: MEMORY_SVC_URL
|
||||
value: "http://memory-svc.gooseek:3010"
|
||||
- name: LLM_SVC_URL
|
||||
value: "http://llm-svc.gooseek:3020"
|
||||
- name: LLM_PROVIDER
|
||||
valueFrom:
|
||||
configMapKeyRef:
|
||||
name: chat-svc-config
|
||||
key: llm-provider
|
||||
- name: OLLAMA_BASE_URL
|
||||
valueFrom:
|
||||
configMapKeyRef:
|
||||
name: chat-svc-config
|
||||
key: ollama-base-url
|
||||
optional: true
|
||||
- name: OPENAI_API_KEY
|
||||
valueFrom:
|
||||
secretKeyRef:
|
||||
name: llm-credentials
|
||||
key: openai-api-key
|
||||
optional: true
|
||||
volumeMounts:
|
||||
- name: chat-data
|
||||
mountPath: /app/data
|
||||
livenessProbe:
|
||||
httpGet:
|
||||
path: /health
|
||||
port: 3005
|
||||
initialDelaySeconds: 10
|
||||
periodSeconds: 10
|
||||
readinessProbe:
|
||||
httpGet:
|
||||
path: /ready
|
||||
port: 3005
|
||||
initialDelaySeconds: 5
|
||||
periodSeconds: 5
|
||||
resources:
|
||||
requests:
|
||||
cpu: 200m
|
||||
memory: 512Mi
|
||||
limits:
|
||||
cpu: 2000m
|
||||
memory: 2Gi
|
||||
volumes:
|
||||
- name: chat-data
|
||||
emptyDir: {}
|
||||
---
|
||||
apiVersion: v1
|
||||
kind: Service
|
||||
metadata:
|
||||
name: chat-svc
|
||||
namespace: gooseek
|
||||
spec:
|
||||
selector:
|
||||
app: chat-svc
|
||||
ports:
|
||||
- port: 3005
|
||||
targetPort: 3005
|
||||
---
|
||||
# ConfigMap для LLM — секреты в llm-credentials (опционально)
|
||||
# При отсутствии ollama в кластере укажите внешний URL или LLM_PROVIDER=openai
|
||||
apiVersion: v1
|
||||
kind: ConfigMap
|
||||
metadata:
|
||||
name: chat-svc-config
|
||||
namespace: gooseek
|
||||
data:
|
||||
llm-provider: "ollama"
|
||||
ollama-base-url: "http://host.docker.internal:11434"
|
||||
@@ -1,57 +0,0 @@
|
||||
# create-svc — Create (таблицы, дашборды), Export PDF/MD
|
||||
# docs/architecture: 01-perplexity-analogue-design.md §5.10
|
||||
apiVersion: apps/v1
|
||||
kind: Deployment
|
||||
metadata:
|
||||
name: create-svc
|
||||
namespace: gooseek
|
||||
spec:
|
||||
replicas: 1
|
||||
selector:
|
||||
matchLabels:
|
||||
app: create-svc
|
||||
template:
|
||||
metadata:
|
||||
labels:
|
||||
app: create-svc
|
||||
annotations:
|
||||
prometheus.io/scrape: "true"
|
||||
prometheus.io/port: "3011"
|
||||
prometheus.io/path: "/metrics"
|
||||
spec:
|
||||
containers:
|
||||
- name: create-svc
|
||||
image: gooseek/create-svc:latest
|
||||
ports:
|
||||
- containerPort: 3011
|
||||
livenessProbe:
|
||||
httpGet:
|
||||
path: /health
|
||||
port: 3011
|
||||
initialDelaySeconds: 5
|
||||
periodSeconds: 10
|
||||
readinessProbe:
|
||||
httpGet:
|
||||
path: /ready
|
||||
port: 3011
|
||||
initialDelaySeconds: 3
|
||||
periodSeconds: 5
|
||||
resources:
|
||||
requests:
|
||||
cpu: 100m
|
||||
memory: 256Mi
|
||||
limits:
|
||||
cpu: 1000m
|
||||
memory: 512Mi
|
||||
---
|
||||
apiVersion: v1
|
||||
kind: Service
|
||||
metadata:
|
||||
name: create-svc
|
||||
namespace: gooseek
|
||||
spec:
|
||||
selector:
|
||||
app: create-svc
|
||||
ports:
|
||||
- port: 3011
|
||||
targetPort: 3011
|
||||
@@ -1,59 +0,0 @@
|
||||
# Конфигурация деплоя GooSeek в Kubernetes (локальный K3s)
|
||||
# Docker build → kubectl apply → rollout restart
|
||||
#
|
||||
# Запуск: ./deploy/k3s/deploy.sh
|
||||
# Или: ./deploy/k3s/deploy.sh --no-build (только apply, без сборки образов)
|
||||
# ./deploy/k3s/deploy.sh --build-only (только сборка, без apply)
|
||||
|
||||
services:
|
||||
# === Обязательные (ядро) ===
|
||||
web-svc: true # Next.js UI — всегда нужен
|
||||
api-gateway: true # Прокси к микросервисам — всегда нужен
|
||||
|
||||
# === Авторизация ===
|
||||
auth-svc: true # better-auth, Sign In/Up (гости работают без него)
|
||||
profile-svc: true # Личные данные, preferences, персонализация (требует PostgreSQL)
|
||||
|
||||
# === Основные функции ===
|
||||
llm-svc: true # LLM providers (Ollama, OpenAI, Timeweb и др.) — единый источник
|
||||
chat-svc: false # Чат, LLM, Writer, SearchAgent
|
||||
search-svc: false # Поиск, SearXNG, патенты
|
||||
library-svc: false # История чатов, треды, экспорт
|
||||
memory-svc: false # AI Memory, персонализация
|
||||
|
||||
# === Контент и discovery ===
|
||||
discover-svc: false # Discover, новости
|
||||
finance-svc: false # Finance, котировки, heatmap
|
||||
travel-svc: false # Travel, маршруты, погода
|
||||
projects-svc: false # Spaces, коллекции, connectors
|
||||
|
||||
# === Дополнительные ===
|
||||
create-svc: false # Create (таблицы, дашборды, изображения)
|
||||
notifications-svc: false # Web Push (требует PostgreSQL)
|
||||
billing-svc: true # Подписки (требует PostgreSQL + yookassa-credentials)
|
||||
audit-svc: false # Enterprise audit logs
|
||||
|
||||
# === Тематические (заглушки в меню, сервисы — в разработке) ===
|
||||
children-svc: false # Дети
|
||||
medicine-svc: false # Медицина
|
||||
education-svc: false # Обучение
|
||||
goods-svc: false # Товары
|
||||
health-svc: false # Здоровье
|
||||
psychology-svc: false # Психология
|
||||
sports-svc: false # Спорт
|
||||
realestate-svc: false # Недвижимость
|
||||
shopping-svc: false # Покупки
|
||||
games-svc: false # Игры
|
||||
taxes-svc: false # Налоги
|
||||
legislation-svc: false # Законодательство
|
||||
|
||||
# === Фоновые задачи ===
|
||||
cache-worker: false # CronJob: discover, finance, travel (требует redis-credentials)
|
||||
|
||||
# Ingress — production https://gooseek.ru
|
||||
ingress:
|
||||
enabled: true
|
||||
# SSL: если backup/fullchain.pem есть — берём из backup, иначе cert-manager (Let's Encrypt)
|
||||
ssl:
|
||||
# true = cert-manager (Let's Encrypt), false = из backup/ (fullchain.pem, privkey.pem)
|
||||
auto: true
|
||||
@@ -1,318 +0,0 @@
|
||||
#!/usr/bin/env bash
|
||||
# Деплой GooSeek в Kubernetes (локальный K3s на этой машине)
|
||||
# Docker build → kubectl apply → rollout restart (подхват новых образов)
|
||||
# Конфигурация: deploy/k3s/deploy.config.yaml
|
||||
#
|
||||
# Использование:
|
||||
# ./deploy/k3s/deploy.sh # полный деплой (build + apply)
|
||||
# ./deploy/k3s/deploy.sh --no-build # только apply манифестов
|
||||
# ./deploy/k3s/deploy.sh --build-only # только сборка образов
|
||||
# ./deploy/k3s/deploy.sh --list # показать включённые сервисы
|
||||
# ./deploy/k3s/deploy.sh --skip-migrate # без миграции auth-svc (быстрее)
|
||||
# ./deploy/k3s/deploy.sh --migrate # принудительно запустить миграцию auth-svc
|
||||
|
||||
set -e
|
||||
|
||||
SCRIPT_DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)"
|
||||
REPO_ROOT="$(cd "$SCRIPT_DIR/../.." && pwd)"
|
||||
CONFIG="$SCRIPT_DIR/deploy.config.yaml"
|
||||
|
||||
# Контекст сборки: . = корень репо, иначе путь к папке сервиса
|
||||
get_build_ctx() {
|
||||
case "$1" in
|
||||
web-svc|auth-svc) echo "." ;;
|
||||
profile-svc) echo "services/profile-svc" ;;
|
||||
api-gateway) echo "services/api-gateway" ;;
|
||||
chat-svc) echo "services/chat-svc" ;;
|
||||
search-svc) echo "services/search-svc" ;;
|
||||
discover-svc) echo "services/discover-svc" ;;
|
||||
finance-svc) echo "services/finance-svc" ;;
|
||||
travel-svc) echo "services/travel-svc" ;;
|
||||
memory-svc) echo "services/memory-svc" ;;
|
||||
library-svc) echo "services/library-svc" ;;
|
||||
create-svc) echo "services/create-svc" ;;
|
||||
projects-svc) echo "services/projects-svc" ;;
|
||||
notifications-svc) echo "services/notifications-svc" ;;
|
||||
billing-svc) echo "services/billing-svc" ;;
|
||||
audit-svc) echo "services/audit-svc" ;;
|
||||
cache-worker) echo "services/cache-worker" ;;
|
||||
llm-svc) echo "services/llm-svc" ;;
|
||||
children-svc|medicine-svc|education-svc|goods-svc|health-svc|psychology-svc|sports-svc|realestate-svc|shopping-svc|games-svc|taxes-svc|legislation-svc) echo "" ;;
|
||||
*) echo "" ;;
|
||||
esac
|
||||
}
|
||||
|
||||
# Манифест для сервиса
|
||||
get_manifest() {
|
||||
case "$1" in
|
||||
web-svc) echo "web-svc.yaml" ;;
|
||||
api-gateway) echo "api-gateway.yaml" ;;
|
||||
auth-svc) echo "auth-svc.yaml" ;;
|
||||
profile-svc) echo "profile-svc.yaml" ;;
|
||||
chat-svc) echo "chat-svc.yaml" ;;
|
||||
search-svc) echo "search-svc.yaml" ;;
|
||||
discover-svc) echo "discover-svc.yaml" ;;
|
||||
finance-svc) echo "finance-svc.yaml" ;;
|
||||
travel-svc) echo "travel-svc.yaml" ;;
|
||||
memory-svc) echo "memory-svc.yaml" ;;
|
||||
library-svc) echo "library-svc.yaml" ;;
|
||||
create-svc) echo "create-svc.yaml" ;;
|
||||
projects-svc) echo "projects-svc.yaml" ;;
|
||||
notifications-svc) echo "notifications-svc.yaml" ;;
|
||||
billing-svc) echo "billing-svc.yaml" ;;
|
||||
audit-svc) echo "audit-svc.yaml" ;;
|
||||
cache-worker) echo "cache-worker.yaml" ;;
|
||||
llm-svc) echo "llm-svc.yaml" ;;
|
||||
children-svc|medicine-svc|education-svc|goods-svc|health-svc|psychology-svc|sports-svc|realestate-svc|shopping-svc|games-svc|taxes-svc|legislation-svc) echo "" ;;
|
||||
*) echo "" ;;
|
||||
esac
|
||||
}
|
||||
|
||||
get_enabled_services() {
|
||||
local in_services=0
|
||||
while IFS= read -r line; do
|
||||
if [[ "$line" =~ ^[a-z].*: ]]; then
|
||||
[[ "$line" =~ ^ingress: ]] && in_services=0
|
||||
fi
|
||||
if [[ "$line" =~ ^services: ]]; then
|
||||
in_services=1
|
||||
continue
|
||||
fi
|
||||
if (( in_services )) && [[ "$line" =~ ^[[:space:]]+([a-z0-9-]+):[[:space:]]+true ]]; then
|
||||
echo "${BASH_REMATCH[1]}"
|
||||
fi
|
||||
done < "$CONFIG"
|
||||
}
|
||||
|
||||
get_ingress_enabled() {
|
||||
grep -A 5 "^ingress:" "$CONFIG" 2>/dev/null | grep "enabled:" | grep -q "true"
|
||||
}
|
||||
|
||||
get_ssl_auto() {
|
||||
grep -A 25 "^ingress:" "$CONFIG" 2>/dev/null | grep -E "^\s+auto:" | head -1 | sed 's/.*auto:[[:space:]]*//' | sed 's/[[:space:]#].*//' | tr -d ' '
|
||||
}
|
||||
|
||||
# SSL: cert-manager + Let's Encrypt (production https://gooseek.ru)
|
||||
do_ssl_production() {
|
||||
if ! kubectl get deployment -n ingress-nginx ingress-nginx-controller &>/dev/null 2>&1; then
|
||||
echo " ⚠ ingress-nginx не найден. Установите: kubectl apply -f https://raw.githubusercontent.com/kubernetes/ingress-nginx/controller-v1.8.2/deploy/static/provider/cloud/deploy.yaml"
|
||||
return 1
|
||||
fi
|
||||
local cert_manager_version="v1.13.0"
|
||||
if ! kubectl get deployment -n cert-manager cert-manager &>/dev/null 2>&1; then
|
||||
echo " → cert-manager"
|
||||
kubectl apply -f "https://github.com/cert-manager/cert-manager/releases/download/${cert_manager_version}/cert-manager.yaml"
|
||||
echo " Ожидание cert-manager (до 2 мин)..."
|
||||
kubectl wait --for=condition=Available deployment/cert-manager -n cert-manager --timeout=120s 2>/dev/null || true
|
||||
kubectl wait --for=condition=Available deployment/cert-manager-webhook -n cert-manager --timeout=120s 2>/dev/null || true
|
||||
else
|
||||
echo " cert-manager уже установлен"
|
||||
fi
|
||||
echo " → ClusterIssuer letsencrypt-prod"
|
||||
kubectl apply -f "$SCRIPT_DIR/ssl/cert-manager-issuer.yaml"
|
||||
echo " → Ingress (TLS, gooseek.ru)"
|
||||
kubectl delete ingress gooseek-web-ingress -n gooseek 2>/dev/null || true
|
||||
kubectl apply -f "$SCRIPT_DIR/ingress-production.yaml"
|
||||
}
|
||||
|
||||
build_image() {
|
||||
local svc="$1"
|
||||
local ctx
|
||||
ctx=$(get_build_ctx "$svc")
|
||||
[[ -z "$ctx" ]] && return 1
|
||||
local img="gooseek/${svc}:latest"
|
||||
local df="services/${svc}/Dockerfile"
|
||||
|
||||
echo " → $img"
|
||||
if [[ "$ctx" == "." ]]; then
|
||||
docker build -t "$img" -f "$df" .
|
||||
else
|
||||
docker build -t "$img" -f "$df" "$ctx"
|
||||
fi
|
||||
}
|
||||
|
||||
do_build() {
|
||||
local enabled
|
||||
enabled=($(get_enabled_services))
|
||||
if [[ ${#enabled[@]} -eq 0 ]]; then
|
||||
echo "Ошибка: нет включённых сервисов в $CONFIG"
|
||||
exit 1
|
||||
fi
|
||||
|
||||
echo "=== Сборка образов (${#enabled[@]} сервисов) ==="
|
||||
cd "$REPO_ROOT"
|
||||
for svc in "${enabled[@]}"; do
|
||||
if get_build_ctx "$svc" | grep -q .; then
|
||||
build_image "$svc"
|
||||
else
|
||||
echo " ⚠ Пропуск $svc (нет конфига сборки)"
|
||||
fi
|
||||
done
|
||||
}
|
||||
|
||||
do_apply() {
|
||||
local enabled
|
||||
enabled=($(get_enabled_services))
|
||||
if [[ ${#enabled[@]} -eq 0 ]]; then
|
||||
echo "Ошибка: нет включённых сервисов в $CONFIG"
|
||||
exit 1
|
||||
fi
|
||||
|
||||
echo "=== Namespace ==="
|
||||
kubectl apply -f "$SCRIPT_DIR/namespace.yaml"
|
||||
|
||||
echo ""
|
||||
echo "=== Config (production https://gooseek.ru) ==="
|
||||
local auth_url="https://gooseek.ru"
|
||||
local origins="https://gooseek.ru,https://www.gooseek.ru"
|
||||
kubectl create configmap gooseek-env -n gooseek \
|
||||
--from-literal=allowed-origins="$origins" \
|
||||
--dry-run=client -o yaml | kubectl apply -f -
|
||||
kubectl create configmap gooseek-env -n gooseek-auth \
|
||||
--from-literal=better-auth-url="$auth_url" \
|
||||
--from-literal=trusted-origins="$origins" \
|
||||
--dry-run=client -o yaml | kubectl apply -f -
|
||||
|
||||
echo ""
|
||||
echo "=== Манифесты (${#enabled[@]} сервисов) ==="
|
||||
for svc in "${enabled[@]}"; do
|
||||
local mf
|
||||
mf=$(get_manifest "$svc")
|
||||
if [[ -n "$mf" && -f "$SCRIPT_DIR/$mf" ]]; then
|
||||
echo " → $mf"
|
||||
kubectl apply -f "$SCRIPT_DIR/$mf"
|
||||
else
|
||||
echo " ⚠ Пропуск $svc (манифест не найден)"
|
||||
fi
|
||||
done
|
||||
|
||||
echo ""
|
||||
echo "=== Rollout restart (подхват новых образов :latest) ==="
|
||||
for svc in "${enabled[@]}"; do
|
||||
local mf
|
||||
mf=$(get_manifest "$svc")
|
||||
[[ -z "$mf" || ! -f "$SCRIPT_DIR/$mf" ]] && continue
|
||||
case "$svc" in
|
||||
auth-svc)
|
||||
kubectl rollout restart deployment/auth-svc -n gooseek-auth 2>/dev/null || true
|
||||
echo " → auth-svc (gooseek-auth)"
|
||||
;;
|
||||
cache-worker)
|
||||
echo " (cache-worker — CronJob, пропуск)"
|
||||
;;
|
||||
*)
|
||||
kubectl rollout restart deployment/"$svc" -n gooseek 2>/dev/null || true
|
||||
echo " → $svc"
|
||||
;;
|
||||
esac
|
||||
done
|
||||
|
||||
# Миграция auth-svc — только при --migrate (не при каждом деплое)
|
||||
# Запускайте ./deploy.sh --migrate после обновления auth-svc или при первой установке
|
||||
# PVC ReadWriteOnce: временно scale down auth-svc, чтобы migrate pod мог смонтировать том
|
||||
if [[ "$FORCE_MIGRATE" -eq 1 ]] && printf '%s\n' "${enabled[@]}" | grep -qx "auth-svc"; then
|
||||
echo ""
|
||||
echo "=== Миграция auth-svc ==="
|
||||
kubectl scale deployment auth-svc -n gooseek-auth --replicas=0 2>/dev/null || true
|
||||
echo " Ожидание остановки auth-svc..."
|
||||
kubectl wait --for=delete pod -l app=auth-svc -n gooseek-auth --timeout=60s 2>/dev/null || sleep 8
|
||||
kubectl run auth-migrate --rm --restart=Never \
|
||||
--image=gooseek/auth-svc:latest \
|
||||
--namespace=gooseek-auth \
|
||||
--overrides='{"spec":{"containers":[{"name":"migrate","image":"gooseek/auth-svc:latest","command":["npx","@better-auth/cli","migrate","--yes"],"env":[{"name":"DATABASE_PATH","value":"/data/auth.db"}],"volumeMounts":[{"name":"auth-data","mountPath":"/data"}]}],"volumes":[{"name":"auth-data","persistentVolumeClaim":{"claimName":"auth-data-pvc"}}]}}' \
|
||||
2>/dev/null || echo " ⚠ Миграция завершилась с ошибкой"
|
||||
kubectl scale deployment auth-svc -n gooseek-auth --replicas=1 2>/dev/null || true
|
||||
echo " auth-svc возвращён в работу"
|
||||
fi
|
||||
|
||||
# Ingress — production https://gooseek.ru
|
||||
if get_ingress_enabled; then
|
||||
echo ""
|
||||
echo "=== Ingress (https://gooseek.ru) ==="
|
||||
kubectl delete ingress gooseek-web-ingress -n gooseek 2>/dev/null || true
|
||||
if [[ -f "$SCRIPT_DIR/ssl/backup/fullchain.pem" ]] && [[ -f "$SCRIPT_DIR/ssl/backup/privkey.pem" ]]; then
|
||||
echo " SSL: серты из backup/"
|
||||
"$SCRIPT_DIR/ssl/apply-secret.sh" 2>/dev/null || true
|
||||
kubectl apply -f "$SCRIPT_DIR/ingress-production-manual.yaml"
|
||||
else
|
||||
local ssl_auto
|
||||
ssl_auto=$(get_ssl_auto)
|
||||
ssl_auto=${ssl_auto:-true}
|
||||
if [[ "$ssl_auto" == "true" ]]; then
|
||||
echo " SSL: cert-manager (Let's Encrypt, первый деплой)"
|
||||
do_ssl_production
|
||||
else
|
||||
echo " ⚠ Нет сертов в backup/. Варианты:"
|
||||
echo " 1) ssl.auto: true в deploy.config.yaml — cert-manager получит серты"
|
||||
echo " 2) Получите серты (certbot), положите в deploy/k3s/ssl/backup/, затем перезапустите деплой"
|
||||
exit 1
|
||||
fi
|
||||
fi
|
||||
fi
|
||||
|
||||
echo ""
|
||||
echo "=== Готово ==="
|
||||
echo "Проверка: kubectl get pods -n gooseek"
|
||||
}
|
||||
|
||||
do_list() {
|
||||
echo "Включённые сервисы:"
|
||||
get_enabled_services | while read -r svc; do
|
||||
echo " - $svc"
|
||||
done
|
||||
echo ""
|
||||
echo "Ingress: $(get_ingress_enabled && echo 'enabled' || echo 'disabled')"
|
||||
echo "Production: https://gooseek.ru"
|
||||
if [[ -f "$SCRIPT_DIR/ssl/backup/fullchain.pem" ]] && [[ -f "$SCRIPT_DIR/ssl/backup/privkey.pem" ]]; then
|
||||
echo "SSL: backup/"
|
||||
else
|
||||
if [[ "$(get_ssl_auto)" == "true" ]]; then
|
||||
echo "SSL: cert-manager (Let's Encrypt)"
|
||||
else
|
||||
echo "SSL: нужен backup/ или ssl.auto: true"
|
||||
fi
|
||||
fi
|
||||
}
|
||||
|
||||
# Main
|
||||
NO_BUILD=0
|
||||
BUILD_ONLY=0
|
||||
LIST_ONLY=0
|
||||
FORCE_MIGRATE=0
|
||||
|
||||
for arg in "$@"; do
|
||||
case "$arg" in
|
||||
--no-build) NO_BUILD=1 ;;
|
||||
--build-only) BUILD_ONLY=1 ;;
|
||||
--list) LIST_ONLY=1 ;;
|
||||
--migrate) FORCE_MIGRATE=1 ;;
|
||||
--skip-migrate) FORCE_MIGRATE=0 ;;
|
||||
-h|--help)
|
||||
echo "Использование: $0 [--no-build|--build-only|--list|--migrate|--skip-migrate]"
|
||||
echo ""
|
||||
echo " --no-build Только apply манифестов (без сборки образов)"
|
||||
echo " --build-only Только сборка образов (без apply)"
|
||||
echo " --list Показать включённые сервисы из deploy.config.yaml"
|
||||
echo " --migrate Запустить миграцию auth-svc (при изменении схемы)"
|
||||
echo " --skip-migrate Пропустить миграцию (по умолчанию)"
|
||||
exit 0
|
||||
;;
|
||||
esac
|
||||
done
|
||||
|
||||
if [[ "$LIST_ONLY" -eq 1 ]]; then
|
||||
do_list
|
||||
exit 0
|
||||
fi
|
||||
|
||||
if [[ "$BUILD_ONLY" -eq 1 ]]; then
|
||||
do_build
|
||||
exit 0
|
||||
fi
|
||||
|
||||
if [[ "$NO_BUILD" -eq 0 ]]; then
|
||||
do_build
|
||||
echo ""
|
||||
fi
|
||||
|
||||
do_apply
|
||||
@@ -1,77 +0,0 @@
|
||||
# discover-svc — агрегация новостей
|
||||
# docs/architecture: 02-k3s-microservices-spec.md
|
||||
apiVersion: apps/v1
|
||||
kind: Deployment
|
||||
metadata:
|
||||
name: discover-svc
|
||||
namespace: gooseek
|
||||
spec:
|
||||
replicas: 2
|
||||
selector:
|
||||
matchLabels:
|
||||
app: discover-svc
|
||||
template:
|
||||
metadata:
|
||||
labels:
|
||||
app: discover-svc
|
||||
annotations:
|
||||
prometheus.io/scrape: "true"
|
||||
prometheus.io/port: "3002"
|
||||
prometheus.io/path: "/metrics"
|
||||
spec:
|
||||
containers:
|
||||
- name: discover-svc
|
||||
image: gooseek/discover-svc:latest
|
||||
ports:
|
||||
- containerPort: 3002
|
||||
env:
|
||||
- name: REDIS_URL
|
||||
valueFrom:
|
||||
secretKeyRef:
|
||||
name: redis-credentials
|
||||
key: url
|
||||
- name: SEARXNG_URL
|
||||
value: "http://searxng.gooseek-infra:8080"
|
||||
- name: GHOST_URL
|
||||
valueFrom:
|
||||
secretKeyRef:
|
||||
name: ghost-credentials
|
||||
key: url
|
||||
optional: true
|
||||
- name: GHOST_CONTENT_API_KEY
|
||||
valueFrom:
|
||||
secretKeyRef:
|
||||
name: ghost-credentials
|
||||
key: content_api_key
|
||||
optional: true
|
||||
livenessProbe:
|
||||
httpGet:
|
||||
path: /health
|
||||
port: 3002
|
||||
initialDelaySeconds: 5
|
||||
periodSeconds: 10
|
||||
readinessProbe:
|
||||
httpGet:
|
||||
path: /ready
|
||||
port: 3002
|
||||
initialDelaySeconds: 3
|
||||
periodSeconds: 5
|
||||
resources:
|
||||
requests:
|
||||
cpu: 50m
|
||||
memory: 128Mi
|
||||
limits:
|
||||
cpu: 500m
|
||||
memory: 512Mi
|
||||
---
|
||||
apiVersion: v1
|
||||
kind: Service
|
||||
metadata:
|
||||
name: discover-svc
|
||||
namespace: gooseek
|
||||
spec:
|
||||
selector:
|
||||
app: discover-svc
|
||||
ports:
|
||||
- port: 3002
|
||||
targetPort: 3002
|
||||
@@ -1,67 +0,0 @@
|
||||
# finance-svc — Market data, heatmap
|
||||
apiVersion: apps/v1
|
||||
kind: Deployment
|
||||
metadata:
|
||||
name: finance-svc
|
||||
namespace: gooseek
|
||||
spec:
|
||||
replicas: 2
|
||||
selector:
|
||||
matchLabels:
|
||||
app: finance-svc
|
||||
template:
|
||||
metadata:
|
||||
labels:
|
||||
app: finance-svc
|
||||
annotations:
|
||||
prometheus.io/scrape: "true"
|
||||
prometheus.io/port: "3003"
|
||||
prometheus.io/path: "/metrics"
|
||||
spec:
|
||||
containers:
|
||||
- name: finance-svc
|
||||
image: gooseek/finance-svc:latest
|
||||
ports:
|
||||
- containerPort: 3003
|
||||
env:
|
||||
- name: REDIS_URL
|
||||
valueFrom:
|
||||
secretKeyRef:
|
||||
name: redis-credentials
|
||||
key: url
|
||||
- name: FMP_API_KEY
|
||||
valueFrom:
|
||||
secretKeyRef:
|
||||
name: finance-keys
|
||||
key: fmp
|
||||
livenessProbe:
|
||||
httpGet:
|
||||
path: /health
|
||||
port: 3003
|
||||
initialDelaySeconds: 5
|
||||
periodSeconds: 10
|
||||
readinessProbe:
|
||||
httpGet:
|
||||
path: /ready
|
||||
port: 3003
|
||||
initialDelaySeconds: 3
|
||||
periodSeconds: 5
|
||||
resources:
|
||||
requests:
|
||||
cpu: 50m
|
||||
memory: 128Mi
|
||||
limits:
|
||||
cpu: 500m
|
||||
memory: 512Mi
|
||||
---
|
||||
apiVersion: v1
|
||||
kind: Service
|
||||
metadata:
|
||||
name: finance-svc
|
||||
namespace: gooseek
|
||||
spec:
|
||||
selector:
|
||||
app: finance-svc
|
||||
ports:
|
||||
- port: 3003
|
||||
targetPort: 3003
|
||||
@@ -1,153 +0,0 @@
|
||||
# HPA — Horizontal Pod Autoscaler
|
||||
# docs/architecture: 02-k3s-microservices-spec.md §3.3, 05-gaps-and-best-practices.md §9
|
||||
# Требует metrics-server в кластере: kubectl apply -f https://github.com/kubernetes-sigs/metrics-server/releases/latest/download/components.yaml
|
||||
|
||||
---
|
||||
# PodDisruptionBudget — docs/architecture: 05-gaps-and-best-practices.md §9
|
||||
apiVersion: policy/v1
|
||||
kind: PodDisruptionBudget
|
||||
metadata:
|
||||
name: chat-svc-pdb
|
||||
namespace: gooseek
|
||||
spec:
|
||||
minAvailable: 1
|
||||
selector:
|
||||
matchLabels:
|
||||
app: chat-svc
|
||||
---
|
||||
apiVersion: policy/v1
|
||||
kind: PodDisruptionBudget
|
||||
metadata:
|
||||
name: search-svc-pdb
|
||||
namespace: gooseek
|
||||
spec:
|
||||
minAvailable: 1
|
||||
selector:
|
||||
matchLabels:
|
||||
app: search-svc
|
||||
---
|
||||
apiVersion: autoscaling/v2
|
||||
kind: HorizontalPodAutoscaler
|
||||
metadata:
|
||||
name: chat-svc-hpa
|
||||
namespace: gooseek
|
||||
spec:
|
||||
scaleTargetRef:
|
||||
apiVersion: apps/v1
|
||||
kind: Deployment
|
||||
name: chat-svc
|
||||
minReplicas: 2
|
||||
maxReplicas: 8
|
||||
metrics:
|
||||
- type: Resource
|
||||
resource:
|
||||
name: cpu
|
||||
target:
|
||||
type: Utilization
|
||||
averageUtilization: 70
|
||||
- type: Resource
|
||||
resource:
|
||||
name: memory
|
||||
target:
|
||||
type: Utilization
|
||||
averageUtilization: 80
|
||||
---
|
||||
apiVersion: autoscaling/v2
|
||||
kind: HorizontalPodAutoscaler
|
||||
metadata:
|
||||
name: search-svc-hpa
|
||||
namespace: gooseek
|
||||
spec:
|
||||
scaleTargetRef:
|
||||
apiVersion: apps/v1
|
||||
kind: Deployment
|
||||
name: search-svc
|
||||
minReplicas: 2
|
||||
maxReplicas: 6
|
||||
metrics:
|
||||
- type: Resource
|
||||
resource:
|
||||
name: cpu
|
||||
target:
|
||||
type: Utilization
|
||||
averageUtilization: 70
|
||||
---
|
||||
apiVersion: autoscaling/v2
|
||||
kind: HorizontalPodAutoscaler
|
||||
metadata:
|
||||
name: discover-svc-hpa
|
||||
namespace: gooseek
|
||||
spec:
|
||||
scaleTargetRef:
|
||||
apiVersion: apps/v1
|
||||
kind: Deployment
|
||||
name: discover-svc
|
||||
minReplicas: 1
|
||||
maxReplicas: 4
|
||||
metrics:
|
||||
- type: Resource
|
||||
resource:
|
||||
name: cpu
|
||||
target:
|
||||
type: Utilization
|
||||
averageUtilization: 70
|
||||
---
|
||||
apiVersion: autoscaling/v2
|
||||
kind: HorizontalPodAutoscaler
|
||||
metadata:
|
||||
name: finance-svc-hpa
|
||||
namespace: gooseek
|
||||
spec:
|
||||
scaleTargetRef:
|
||||
apiVersion: apps/v1
|
||||
kind: Deployment
|
||||
name: finance-svc
|
||||
minReplicas: 1
|
||||
maxReplicas: 4
|
||||
metrics:
|
||||
- type: Resource
|
||||
resource:
|
||||
name: cpu
|
||||
target:
|
||||
type: Utilization
|
||||
averageUtilization: 70
|
||||
---
|
||||
apiVersion: autoscaling/v2
|
||||
kind: HorizontalPodAutoscaler
|
||||
metadata:
|
||||
name: travel-svc-hpa
|
||||
namespace: gooseek
|
||||
spec:
|
||||
scaleTargetRef:
|
||||
apiVersion: apps/v1
|
||||
kind: Deployment
|
||||
name: travel-svc
|
||||
minReplicas: 1
|
||||
maxReplicas: 3
|
||||
metrics:
|
||||
- type: Resource
|
||||
resource:
|
||||
name: cpu
|
||||
target:
|
||||
type: Utilization
|
||||
averageUtilization: 70
|
||||
---
|
||||
apiVersion: autoscaling/v2
|
||||
kind: HorizontalPodAutoscaler
|
||||
metadata:
|
||||
name: memory-svc-hpa
|
||||
namespace: gooseek
|
||||
spec:
|
||||
scaleTargetRef:
|
||||
apiVersion: apps/v1
|
||||
kind: Deployment
|
||||
name: memory-svc
|
||||
minReplicas: 1
|
||||
maxReplicas: 3
|
||||
metrics:
|
||||
- type: Resource
|
||||
resource:
|
||||
name: cpu
|
||||
target:
|
||||
type: Utilization
|
||||
averageUtilization: 70
|
||||
@@ -1,39 +0,0 @@
|
||||
# Production Ingress для gooseek.ru — HTTPS (ручной Secret)
|
||||
# Используется когда cert-manager НЕ установлен. Secret gooseek-tls создаётся через apply-secret.sh
|
||||
# kubectl apply -f deploy/k3s/ingress-production-manual.yaml
|
||||
apiVersion: networking.k8s.io/v1
|
||||
kind: Ingress
|
||||
metadata:
|
||||
name: gooseek-production
|
||||
namespace: gooseek
|
||||
annotations:
|
||||
kubernetes.io/ingress.class: nginx
|
||||
nginx.ingress.kubernetes.io/ssl-redirect: "true"
|
||||
nginx.ingress.kubernetes.io/force-ssl-redirect: "true"
|
||||
spec:
|
||||
tls:
|
||||
- hosts:
|
||||
- gooseek.ru
|
||||
- www.gooseek.ru
|
||||
secretName: gooseek-tls
|
||||
rules:
|
||||
- host: gooseek.ru
|
||||
http:
|
||||
paths:
|
||||
- path: /
|
||||
pathType: Prefix
|
||||
backend:
|
||||
service:
|
||||
name: web-svc
|
||||
port:
|
||||
number: 3000
|
||||
- host: www.gooseek.ru
|
||||
http:
|
||||
paths:
|
||||
- path: /
|
||||
pathType: Prefix
|
||||
backend:
|
||||
service:
|
||||
name: web-svc
|
||||
port:
|
||||
number: 3000
|
||||
@@ -1,43 +0,0 @@
|
||||
# Production Ingress для gooseek.ru — HTTPS
|
||||
# cert-manager создаёт Secret gooseek-tls автоматически (Let's Encrypt)
|
||||
# Требования: DNS gooseek.ru → IP ingress-nginx, порт 80 доступен из интернета
|
||||
apiVersion: networking.k8s.io/v1
|
||||
kind: Ingress
|
||||
metadata:
|
||||
name: gooseek-production
|
||||
namespace: gooseek
|
||||
annotations:
|
||||
kubernetes.io/ingress.class: nginx
|
||||
nginx.ingress.kubernetes.io/ssl-redirect: "true"
|
||||
nginx.ingress.kubernetes.io/force-ssl-redirect: "true"
|
||||
cert-manager.io/cluster-issuer: letsencrypt-prod
|
||||
# Добавить ACME challenge в этот ingress (избегает 404 при отдельном challenge ingress)
|
||||
acme.cert-manager.io/http01-edit-in-place: "true"
|
||||
spec:
|
||||
ingressClassName: nginx
|
||||
tls:
|
||||
- hosts:
|
||||
- gooseek.ru
|
||||
- www.gooseek.ru
|
||||
secretName: gooseek-tls
|
||||
rules:
|
||||
- host: gooseek.ru
|
||||
http:
|
||||
paths:
|
||||
- path: /
|
||||
pathType: Prefix
|
||||
backend:
|
||||
service:
|
||||
name: web-svc
|
||||
port:
|
||||
number: 3000
|
||||
- host: www.gooseek.ru
|
||||
http:
|
||||
paths:
|
||||
- path: /
|
||||
pathType: Prefix
|
||||
backend:
|
||||
service:
|
||||
name: web-svc
|
||||
port:
|
||||
number: 3000
|
||||
@@ -1,132 +0,0 @@
|
||||
# Ingress для GooSeek — path-based маршрутизация к микросервисам
|
||||
# docs/architecture: 02-k3s-microservices-spec.md §4
|
||||
apiVersion: networking.k8s.io/v1
|
||||
kind: Ingress
|
||||
metadata:
|
||||
name: gooseek-ingress
|
||||
namespace: gooseek
|
||||
annotations:
|
||||
kubernetes.io/ingress.class: nginx
|
||||
nginx.ingress.kubernetes.io/ssl-redirect: "true"
|
||||
spec:
|
||||
tls:
|
||||
- hosts:
|
||||
- gooseek.ru
|
||||
- www.gooseek.ru
|
||||
secretName: gooseek-tls
|
||||
rules:
|
||||
- host: gooseek.ru
|
||||
http:
|
||||
paths:
|
||||
- path: /api/v1/discover
|
||||
pathType: Prefix
|
||||
backend:
|
||||
service:
|
||||
name: discover-svc
|
||||
port:
|
||||
number: 3002
|
||||
- path: /api/v1/finance
|
||||
pathType: Prefix
|
||||
backend:
|
||||
service:
|
||||
name: finance-svc
|
||||
port:
|
||||
number: 3003
|
||||
- path: /api/v1/travel
|
||||
pathType: Prefix
|
||||
backend:
|
||||
service:
|
||||
name: travel-svc
|
||||
port:
|
||||
number: 3004
|
||||
- path: /api/v1/library
|
||||
pathType: Prefix
|
||||
backend:
|
||||
service:
|
||||
name: library-svc
|
||||
port:
|
||||
number: 3009
|
||||
- path: /api/v1/collections
|
||||
pathType: Prefix
|
||||
backend:
|
||||
service:
|
||||
name: projects-svc
|
||||
port:
|
||||
number: 3006
|
||||
- path: /api/v1/templates
|
||||
pathType: Prefix
|
||||
backend:
|
||||
service:
|
||||
name: projects-svc
|
||||
port:
|
||||
number: 3006
|
||||
- path: /api/v1/connectors
|
||||
pathType: Prefix
|
||||
backend:
|
||||
service:
|
||||
name: projects-svc
|
||||
port:
|
||||
number: 3006
|
||||
- path: /api/v1/memory
|
||||
pathType: Prefix
|
||||
backend:
|
||||
service:
|
||||
name: memory-svc
|
||||
port:
|
||||
number: 3010
|
||||
- path: /api/v1/create
|
||||
pathType: Prefix
|
||||
backend:
|
||||
service:
|
||||
name: create-svc
|
||||
port:
|
||||
number: 3011
|
||||
- path: /api/v1/export
|
||||
pathType: Prefix
|
||||
backend:
|
||||
service:
|
||||
name: create-svc
|
||||
port:
|
||||
number: 3011
|
||||
- path: /api/v1/search
|
||||
pathType: Prefix
|
||||
backend:
|
||||
service:
|
||||
name: search-svc
|
||||
port:
|
||||
number: 3001
|
||||
- path: /api/v1/tasks
|
||||
pathType: Prefix
|
||||
backend:
|
||||
service:
|
||||
name: chat-svc
|
||||
port:
|
||||
number: 3005
|
||||
- path: /api/v1/patents
|
||||
pathType: Prefix
|
||||
backend:
|
||||
service:
|
||||
name: search-svc
|
||||
port:
|
||||
number: 3001
|
||||
- path: /api/v1/notifications
|
||||
pathType: Prefix
|
||||
backend:
|
||||
service:
|
||||
name: notifications-svc
|
||||
port:
|
||||
number: 3013
|
||||
- path: /api/v1/billing
|
||||
pathType: Prefix
|
||||
backend:
|
||||
service:
|
||||
name: billing-svc
|
||||
port:
|
||||
number: 3008
|
||||
- path: /api/v1/admin
|
||||
pathType: Prefix
|
||||
backend:
|
||||
service:
|
||||
name: audit-svc
|
||||
port:
|
||||
number: 3012
|
||||
@@ -1,64 +0,0 @@
|
||||
# library-svc — история тредов
|
||||
apiVersion: apps/v1
|
||||
kind: Deployment
|
||||
metadata:
|
||||
name: library-svc
|
||||
namespace: gooseek
|
||||
spec:
|
||||
replicas: 2
|
||||
selector:
|
||||
matchLabels:
|
||||
app: library-svc
|
||||
template:
|
||||
metadata:
|
||||
labels:
|
||||
app: library-svc
|
||||
annotations:
|
||||
prometheus.io/scrape: "true"
|
||||
prometheus.io/port: "3009"
|
||||
prometheus.io/path: "/metrics"
|
||||
spec:
|
||||
containers:
|
||||
- name: library-svc
|
||||
image: gooseek/library-svc:latest
|
||||
ports:
|
||||
- containerPort: 3009
|
||||
env:
|
||||
- name: POSTGRES_URL
|
||||
valueFrom:
|
||||
secretKeyRef:
|
||||
name: db-credentials
|
||||
key: url
|
||||
- name: AUTH_SERVICE_URL
|
||||
value: "http://auth-svc.gooseek-auth:3014"
|
||||
livenessProbe:
|
||||
httpGet:
|
||||
path: /health
|
||||
port: 3009
|
||||
initialDelaySeconds: 5
|
||||
periodSeconds: 10
|
||||
readinessProbe:
|
||||
httpGet:
|
||||
path: /ready
|
||||
port: 3009
|
||||
initialDelaySeconds: 3
|
||||
periodSeconds: 5
|
||||
resources:
|
||||
requests:
|
||||
cpu: 50m
|
||||
memory: 128Mi
|
||||
limits:
|
||||
cpu: 500m
|
||||
memory: 512Mi
|
||||
---
|
||||
apiVersion: v1
|
||||
kind: Service
|
||||
metadata:
|
||||
name: library-svc
|
||||
namespace: gooseek
|
||||
spec:
|
||||
selector:
|
||||
app: library-svc
|
||||
ports:
|
||||
- port: 3009
|
||||
targetPort: 3009
|
||||
@@ -1,130 +0,0 @@
|
||||
# llm-svc — LLM providers microservice
|
||||
# API: GET/POST/PATCH/DELETE /api/v1/providers, models CRUD
|
||||
# Используется chat-svc, media-svc, suggestions-svc и др.
|
||||
apiVersion: apps/v1
|
||||
kind: Deployment
|
||||
metadata:
|
||||
name: llm-svc
|
||||
namespace: gooseek
|
||||
spec:
|
||||
replicas: 1
|
||||
selector:
|
||||
matchLabels:
|
||||
app: llm-svc
|
||||
template:
|
||||
metadata:
|
||||
labels:
|
||||
app: llm-svc
|
||||
annotations:
|
||||
prometheus.io/scrape: "true"
|
||||
prometheus.io/port: "3020"
|
||||
prometheus.io/path: "/metrics"
|
||||
spec:
|
||||
containers:
|
||||
- name: llm-svc
|
||||
image: gooseek/llm-svc:latest
|
||||
imagePullPolicy: Never
|
||||
ports:
|
||||
- containerPort: 3020
|
||||
env:
|
||||
- name: PORT
|
||||
value: "3020"
|
||||
- name: DATA_DIR
|
||||
value: "/app/data"
|
||||
- name: LLM_PROVIDER
|
||||
valueFrom:
|
||||
configMapKeyRef:
|
||||
name: llm-svc-config
|
||||
key: llm-provider
|
||||
- name: OLLAMA_BASE_URL
|
||||
valueFrom:
|
||||
configMapKeyRef:
|
||||
name: llm-svc-config
|
||||
key: ollama-base-url
|
||||
optional: true
|
||||
- name: OPENAI_API_KEY
|
||||
valueFrom:
|
||||
secretKeyRef:
|
||||
name: llm-credentials
|
||||
key: openai-api-key
|
||||
optional: true
|
||||
- name: TIMEWEB_API_BASE_URL
|
||||
valueFrom:
|
||||
configMapKeyRef:
|
||||
name: llm-svc-config
|
||||
key: timeweb-api-base-url
|
||||
optional: true
|
||||
- name: LLM_CHAT_MODEL
|
||||
valueFrom:
|
||||
configMapKeyRef:
|
||||
name: llm-svc-config
|
||||
key: llm-chat-model
|
||||
optional: true
|
||||
- name: TIMEWEB_X_PROXY_SOURCE
|
||||
valueFrom:
|
||||
configMapKeyRef:
|
||||
name: llm-svc-config
|
||||
key: timeweb-x-proxy-source
|
||||
optional: true
|
||||
- name: TIMEWEB_AGENT_ACCESS_ID
|
||||
valueFrom:
|
||||
secretKeyRef:
|
||||
name: llm-credentials
|
||||
key: timeweb-agent-access-id
|
||||
optional: true
|
||||
- name: TIMEWEB_API_KEY
|
||||
valueFrom:
|
||||
secretKeyRef:
|
||||
name: llm-credentials
|
||||
key: timeweb-api-key
|
||||
optional: true
|
||||
volumeMounts:
|
||||
- name: llm-data
|
||||
mountPath: /app/data
|
||||
livenessProbe:
|
||||
httpGet:
|
||||
path: /health
|
||||
port: 3020
|
||||
initialDelaySeconds: 10
|
||||
periodSeconds: 10
|
||||
readinessProbe:
|
||||
httpGet:
|
||||
path: /ready
|
||||
port: 3020
|
||||
initialDelaySeconds: 5
|
||||
periodSeconds: 5
|
||||
resources:
|
||||
requests:
|
||||
cpu: 100m
|
||||
memory: 256Mi
|
||||
limits:
|
||||
cpu: 500m
|
||||
memory: 512Mi
|
||||
volumes:
|
||||
- name: llm-data
|
||||
emptyDir: {}
|
||||
---
|
||||
apiVersion: v1
|
||||
kind: Service
|
||||
metadata:
|
||||
name: llm-svc
|
||||
namespace: gooseek
|
||||
spec:
|
||||
selector:
|
||||
app: llm-svc
|
||||
ports:
|
||||
- port: 3020
|
||||
targetPort: 3020
|
||||
---
|
||||
# ConfigMap: llm-provider = ollama | timeweb
|
||||
# Для timeweb: создайте Secret llm-credentials с ключами timeweb-agent-access-id, timeweb-api-key
|
||||
apiVersion: v1
|
||||
kind: ConfigMap
|
||||
metadata:
|
||||
name: llm-svc-config
|
||||
namespace: gooseek
|
||||
data:
|
||||
llm-provider: "timeweb"
|
||||
ollama-base-url: "http://host.docker.internal:11434"
|
||||
timeweb-api-base-url: "https://api.timeweb.cloud"
|
||||
llm-chat-model: "gpt-4"
|
||||
@@ -1,67 +0,0 @@
|
||||
# memory-svc — персональная память AI, Enterprise Memory
|
||||
# docs/architecture: 01-perplexity-analogue-design.md §5.9
|
||||
apiVersion: apps/v1
|
||||
kind: Deployment
|
||||
metadata:
|
||||
name: memory-svc
|
||||
namespace: gooseek
|
||||
spec:
|
||||
replicas: 2
|
||||
selector:
|
||||
matchLabels:
|
||||
app: memory-svc
|
||||
template:
|
||||
metadata:
|
||||
labels:
|
||||
app: memory-svc
|
||||
annotations:
|
||||
prometheus.io/scrape: "true"
|
||||
prometheus.io/port: "3010"
|
||||
prometheus.io/path: "/metrics"
|
||||
spec:
|
||||
containers:
|
||||
- name: memory-svc
|
||||
image: gooseek/memory-svc:latest
|
||||
ports:
|
||||
- containerPort: 3010
|
||||
env:
|
||||
- name: PORT
|
||||
value: "3010"
|
||||
- name: POSTGRES_URL
|
||||
valueFrom:
|
||||
secretKeyRef:
|
||||
name: db-credentials
|
||||
key: url
|
||||
- name: AUTH_SERVICE_URL
|
||||
value: "http://auth-svc.gooseek-auth:3014"
|
||||
livenessProbe:
|
||||
httpGet:
|
||||
path: /health
|
||||
port: 3010
|
||||
initialDelaySeconds: 5
|
||||
periodSeconds: 10
|
||||
readinessProbe:
|
||||
httpGet:
|
||||
path: /ready
|
||||
port: 3010
|
||||
initialDelaySeconds: 3
|
||||
periodSeconds: 5
|
||||
resources:
|
||||
requests:
|
||||
cpu: 100m
|
||||
memory: 256Mi
|
||||
limits:
|
||||
cpu: 1000m
|
||||
memory: 1Gi
|
||||
---
|
||||
apiVersion: v1
|
||||
kind: Service
|
||||
metadata:
|
||||
name: memory-svc
|
||||
namespace: gooseek
|
||||
spec:
|
||||
selector:
|
||||
app: memory-svc
|
||||
ports:
|
||||
- port: 3010
|
||||
targetPort: 3010
|
||||
@@ -1,21 +0,0 @@
|
||||
# docs/architecture: 02-k3s-microservices-spec.md
|
||||
apiVersion: v1
|
||||
kind: Namespace
|
||||
metadata:
|
||||
name: gooseek
|
||||
labels:
|
||||
app.kubernetes.io/name: gooseek
|
||||
---
|
||||
apiVersion: v1
|
||||
kind: Namespace
|
||||
metadata:
|
||||
name: gooseek-auth
|
||||
labels:
|
||||
app.kubernetes.io/name: gooseek-auth
|
||||
---
|
||||
apiVersion: v1
|
||||
kind: Namespace
|
||||
metadata:
|
||||
name: gooseek-infra
|
||||
labels:
|
||||
app.kubernetes.io/name: gooseek-infra
|
||||
@@ -1,17 +0,0 @@
|
||||
# NetworkPolicy — базовая сетевая изоляция
|
||||
# docs/architecture: 05-gaps-and-best-practices.md §3
|
||||
# Разрешает трафик внутри namespace gooseek (chat→search, cache-worker→redis и т.д.)
|
||||
# Для production добавьте ingress namespace в from
|
||||
---
|
||||
apiVersion: networking.k8s.io/v1
|
||||
kind: NetworkPolicy
|
||||
metadata:
|
||||
name: gooseek-allow-internal
|
||||
namespace: gooseek
|
||||
spec:
|
||||
podSelector: {}
|
||||
policyTypes:
|
||||
- Ingress
|
||||
ingress:
|
||||
- from:
|
||||
- podSelector: {}
|
||||
@@ -1,77 +0,0 @@
|
||||
# notifications-svc — Web Push, SMTP email, preferences, reminders
|
||||
# docs/architecture: 02-k3s-microservices-spec.md
|
||||
apiVersion: apps/v1
|
||||
kind: Deployment
|
||||
metadata:
|
||||
name: notifications-svc
|
||||
namespace: gooseek
|
||||
spec:
|
||||
replicas: 1
|
||||
selector:
|
||||
matchLabels:
|
||||
app: notifications-svc
|
||||
template:
|
||||
metadata:
|
||||
labels:
|
||||
app: notifications-svc
|
||||
spec:
|
||||
containers:
|
||||
- name: notifications-svc
|
||||
image: gooseek/notifications-svc:latest
|
||||
ports:
|
||||
- containerPort: 3013
|
||||
env:
|
||||
- name: POSTGRES_URL
|
||||
valueFrom:
|
||||
secretKeyRef:
|
||||
name: db-credentials
|
||||
key: url
|
||||
- name: AUTH_SERVICE_URL
|
||||
value: "http://auth-svc.gooseek-auth:3014"
|
||||
- name: VAPID_PUBLIC_KEY
|
||||
valueFrom:
|
||||
secretKeyRef:
|
||||
name: notifications-credentials
|
||||
key: vapid_public
|
||||
- name: VAPID_PRIVATE_KEY
|
||||
valueFrom:
|
||||
secretKeyRef:
|
||||
name: notifications-credentials
|
||||
key: vapid_private
|
||||
- name: SMTP_URL
|
||||
valueFrom:
|
||||
secretKeyRef:
|
||||
name: notifications-credentials
|
||||
key: smtp_url
|
||||
optional: true
|
||||
livenessProbe:
|
||||
httpGet:
|
||||
path: /health
|
||||
port: 3013
|
||||
initialDelaySeconds: 5
|
||||
periodSeconds: 10
|
||||
readinessProbe:
|
||||
httpGet:
|
||||
path: /ready
|
||||
port: 3013
|
||||
initialDelaySeconds: 5
|
||||
periodSeconds: 5
|
||||
resources:
|
||||
requests:
|
||||
cpu: 50m
|
||||
memory: 128Mi
|
||||
limits:
|
||||
cpu: 500m
|
||||
memory: 512Mi
|
||||
---
|
||||
apiVersion: v1
|
||||
kind: Service
|
||||
metadata:
|
||||
name: notifications-svc
|
||||
namespace: gooseek
|
||||
spec:
|
||||
selector:
|
||||
app: notifications-svc
|
||||
ports:
|
||||
- port: 3013
|
||||
targetPort: 3013
|
||||
@@ -1,67 +0,0 @@
|
||||
# profile-svc — личные данные и персонализация пользователя
|
||||
apiVersion: apps/v1
|
||||
kind: Deployment
|
||||
metadata:
|
||||
name: profile-svc
|
||||
namespace: gooseek
|
||||
spec:
|
||||
replicas: 1
|
||||
selector:
|
||||
matchLabels:
|
||||
app: profile-svc
|
||||
template:
|
||||
metadata:
|
||||
labels:
|
||||
app: profile-svc
|
||||
annotations:
|
||||
prometheus.io/scrape: "true"
|
||||
prometheus.io/port: "3019"
|
||||
prometheus.io/path: "/metrics"
|
||||
spec:
|
||||
containers:
|
||||
- name: profile-svc
|
||||
image: gooseek/profile-svc:latest
|
||||
imagePullPolicy: Never
|
||||
ports:
|
||||
- containerPort: 3019
|
||||
env:
|
||||
- name: PORT
|
||||
value: "3019"
|
||||
- name: POSTGRES_URL
|
||||
valueFrom:
|
||||
secretKeyRef:
|
||||
name: db-credentials
|
||||
key: url
|
||||
- name: AUTH_SERVICE_URL
|
||||
value: "http://auth-svc.gooseek-auth:3014"
|
||||
livenessProbe:
|
||||
httpGet:
|
||||
path: /health
|
||||
port: 3019
|
||||
initialDelaySeconds: 5
|
||||
periodSeconds: 10
|
||||
readinessProbe:
|
||||
httpGet:
|
||||
path: /ready
|
||||
port: 3019
|
||||
initialDelaySeconds: 3
|
||||
periodSeconds: 5
|
||||
resources:
|
||||
requests:
|
||||
cpu: 50m
|
||||
memory: 128Mi
|
||||
limits:
|
||||
cpu: 500m
|
||||
memory: 512Mi
|
||||
---
|
||||
apiVersion: v1
|
||||
kind: Service
|
||||
metadata:
|
||||
name: profile-svc
|
||||
namespace: gooseek
|
||||
spec:
|
||||
selector:
|
||||
app: profile-svc
|
||||
ports:
|
||||
- port: 3019
|
||||
targetPort: 3019
|
||||
@@ -1,55 +0,0 @@
|
||||
# projects-svc — Spaces, Collections
|
||||
apiVersion: apps/v1
|
||||
kind: Deployment
|
||||
metadata:
|
||||
name: projects-svc
|
||||
namespace: gooseek
|
||||
spec:
|
||||
replicas: 2
|
||||
selector:
|
||||
matchLabels:
|
||||
app: projects-svc
|
||||
template:
|
||||
metadata:
|
||||
labels:
|
||||
app: projects-svc
|
||||
spec:
|
||||
containers:
|
||||
- name: projects-svc
|
||||
image: gooseek/projects-svc:latest
|
||||
ports:
|
||||
- containerPort: 3006
|
||||
env:
|
||||
- name: AUTH_SERVICE_URL
|
||||
value: "http://auth-svc.gooseek-auth:3014"
|
||||
livenessProbe:
|
||||
httpGet:
|
||||
path: /health
|
||||
port: 3006
|
||||
initialDelaySeconds: 5
|
||||
periodSeconds: 10
|
||||
readinessProbe:
|
||||
httpGet:
|
||||
path: /ready
|
||||
port: 3006
|
||||
initialDelaySeconds: 3
|
||||
periodSeconds: 5
|
||||
resources:
|
||||
requests:
|
||||
cpu: 50m
|
||||
memory: 128Mi
|
||||
limits:
|
||||
cpu: 500m
|
||||
memory: 512Mi
|
||||
---
|
||||
apiVersion: v1
|
||||
kind: Service
|
||||
metadata:
|
||||
name: projects-svc
|
||||
namespace: gooseek
|
||||
spec:
|
||||
selector:
|
||||
app: projects-svc
|
||||
ports:
|
||||
- port: 3006
|
||||
targetPort: 3006
|
||||
@@ -1,65 +0,0 @@
|
||||
# search-svc — SearXNG proxy, кэш по query_hash
|
||||
# docs/architecture: 02-k3s-microservices-spec.md
|
||||
apiVersion: apps/v1
|
||||
kind: Deployment
|
||||
metadata:
|
||||
name: search-svc
|
||||
namespace: gooseek
|
||||
spec:
|
||||
replicas: 2
|
||||
selector:
|
||||
matchLabels:
|
||||
app: search-svc
|
||||
template:
|
||||
metadata:
|
||||
labels:
|
||||
app: search-svc
|
||||
annotations:
|
||||
prometheus.io/scrape: "true"
|
||||
prometheus.io/port: "3001"
|
||||
prometheus.io/path: "/metrics"
|
||||
spec:
|
||||
containers:
|
||||
- name: search-svc
|
||||
image: gooseek/search-svc:latest
|
||||
ports:
|
||||
- containerPort: 3001
|
||||
env:
|
||||
- name: REDIS_URL
|
||||
valueFrom:
|
||||
secretKeyRef:
|
||||
name: redis-credentials
|
||||
key: url
|
||||
- name: SEARXNG_URL
|
||||
value: "http://searxng.gooseek-infra:8080"
|
||||
livenessProbe:
|
||||
httpGet:
|
||||
path: /health
|
||||
port: 3001
|
||||
initialDelaySeconds: 5
|
||||
periodSeconds: 10
|
||||
readinessProbe:
|
||||
httpGet:
|
||||
path: /ready
|
||||
port: 3001
|
||||
initialDelaySeconds: 3
|
||||
periodSeconds: 5
|
||||
resources:
|
||||
requests:
|
||||
cpu: 50m
|
||||
memory: 128Mi
|
||||
limits:
|
||||
cpu: 500m
|
||||
memory: 512Mi
|
||||
---
|
||||
apiVersion: v1
|
||||
kind: Service
|
||||
metadata:
|
||||
name: search-svc
|
||||
namespace: gooseek
|
||||
spec:
|
||||
selector:
|
||||
app: search-svc
|
||||
ports:
|
||||
- port: 3001
|
||||
targetPort: 3001
|
||||
@@ -1,187 +0,0 @@
|
||||
# SSL-сертификат для gooseek.ru
|
||||
|
||||
Инструкция по получению сертификата, бэкапу и подключению к K3s.
|
||||
|
||||
---
|
||||
|
||||
## 1. Получение сертификата (Let's Encrypt)
|
||||
|
||||
### Вариант A: certbot на сервере (рекомендуется)
|
||||
|
||||
```bash
|
||||
# Установка certbot (Ubuntu/Debian)
|
||||
sudo apt update && sudo apt install -y certbot
|
||||
|
||||
# Получение сертификата (standalone — порт 80 должен быть свободен)
|
||||
sudo certbot certonly --standalone -d gooseek.ru -d www.gooseek.ru \
|
||||
--email admin@gooseek.ru \
|
||||
--agree-tos \
|
||||
--no-eff-email
|
||||
|
||||
# Файлы появятся в:
|
||||
# /etc/letsencrypt/live/gooseek.ru/fullchain.pem
|
||||
# /etc/letsencrypt/live/gooseek.ru/privkey.pem
|
||||
```
|
||||
|
||||
### Вариант B: certbot с webroot (если nginx уже слушает 80)
|
||||
|
||||
```bash
|
||||
sudo certbot certonly --webroot -w /var/www/html \
|
||||
-d gooseek.ru -d www.gooseek.ru \
|
||||
--email admin@gooseek.ru \
|
||||
--agree-tos \
|
||||
--no-eff-email
|
||||
```
|
||||
|
||||
### Вариант C: DNS challenge (если порт 80 недоступен)
|
||||
|
||||
```bash
|
||||
sudo certbot certonly --manual --preferred-challenges dns \
|
||||
-d gooseek.ru -d www.gooseek.ru \
|
||||
--email admin@gooseek.ru \
|
||||
--agree-tos
|
||||
# Certbot попросит добавить TXT-запись в DNS
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
## 2. Бэкап сертификата
|
||||
|
||||
Создайте папку бэкапа и скопируйте туда сертификаты:
|
||||
|
||||
```bash
|
||||
# Из корня репозитория
|
||||
mkdir -p deploy/k3s/ssl/backup
|
||||
|
||||
# Копирование с сервера (после certbot)
|
||||
sudo cp /etc/letsencrypt/live/gooseek.ru/fullchain.pem deploy/k3s/ssl/backup/
|
||||
sudo cp /etc/letsencrypt/live/gooseek.ru/privkey.pem deploy/k3s/ssl/backup/
|
||||
|
||||
# Или через scp с production-сервера:
|
||||
# scp user@gooseek.ru:/etc/letsencrypt/live/gooseek.ru/fullchain.pem deploy/k3s/ssl/backup/
|
||||
# scp user@gooseek.ru:/etc/letsencrypt/live/gooseek.ru/privkey.pem deploy/k3s/ssl/backup/
|
||||
```
|
||||
|
||||
**Важно:** Папка `backup/` в `.gitignore` — сертификаты не попадут в git.
|
||||
|
||||
---
|
||||
|
||||
## 3. Создание Kubernetes Secret из бэкапа
|
||||
|
||||
```bash
|
||||
# Из корня репозитория
|
||||
kubectl create secret tls gooseek-tls \
|
||||
--namespace=gooseek \
|
||||
--cert=deploy/k3s/ssl/backup/fullchain.pem \
|
||||
--key=deploy/k3s/ssl/backup/privkey.pem \
|
||||
--dry-run=client -o yaml | kubectl apply -f -
|
||||
```
|
||||
|
||||
Или обновить существующий:
|
||||
|
||||
```bash
|
||||
kubectl delete secret gooseek-tls -n gooseek 2>/dev/null || true
|
||||
kubectl create secret tls gooseek-tls \
|
||||
--namespace=gooseek \
|
||||
--cert=deploy/k3s/ssl/backup/fullchain.pem \
|
||||
--key=deploy/k3s/ssl/backup/privkey.pem
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
## 4. Применение Ingress с TLS
|
||||
|
||||
При ручных сертах (из backup/):
|
||||
```bash
|
||||
./deploy/k3s/ssl/apply-secret.sh
|
||||
kubectl apply -f deploy/k3s/ingress-production-manual.yaml
|
||||
```
|
||||
|
||||
При cert-manager:
|
||||
```bash
|
||||
kubectl apply -f deploy/k3s/ingress-production.yaml
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
## 5. Автообновление (certbot)
|
||||
|
||||
Let's Encrypt выдаёт сертификаты на 90 дней. Настройте автообновление:
|
||||
|
||||
```bash
|
||||
# Проверка таймера
|
||||
sudo systemctl status certbot.timer
|
||||
|
||||
# Ручное обновление
|
||||
sudo certbot renew --dry-run
|
||||
|
||||
# После обновления — пересоздать Secret и перезапустить ingress
|
||||
sudo cp /etc/letsencrypt/live/gooseek.ru/fullchain.pem deploy/k3s/ssl/backup/
|
||||
sudo cp /etc/letsencrypt/live/gooseek.ru/privkey.pem deploy/k3s/ssl/backup/
|
||||
kubectl create secret tls gooseek-tls -n gooseek \
|
||||
--cert=deploy/k3s/ssl/backup/fullchain.pem \
|
||||
--key=deploy/k3s/ssl/backup/privkey.pem \
|
||||
--dry-run=client -o yaml | kubectl apply -f -
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
## 6. Альтернатива: cert-manager (автоматически)
|
||||
|
||||
Если не хотите вручную обновлять — установите cert-manager:
|
||||
|
||||
```bash
|
||||
kubectl apply -f https://github.com/cert-manager/cert-manager/releases/download/v1.13.0/cert-manager.yaml
|
||||
|
||||
# Создать ClusterIssuer для Let's Encrypt
|
||||
kubectl apply -f deploy/k3s/ssl/cert-manager-issuer.yaml
|
||||
```
|
||||
|
||||
Тогда Secret `gooseek-tls` создаётся автоматически, бэкап не нужен (но можно экспортировать для переноса).
|
||||
|
||||
---
|
||||
|
||||
---
|
||||
|
||||
## 7. Настройка в Kubernetes
|
||||
|
||||
### Автоматически при деплое (рекомендуется)
|
||||
|
||||
В `deploy.config.yaml` установите `ssl.auto: true`. При запуске `./deploy/k3s/deploy.sh` cert-manager и SSL настраиваются автоматически.
|
||||
|
||||
**Требования для HTTP-01 (Let's Encrypt):**
|
||||
- DNS: gooseek.ru и www.gooseek.ru → публичный IP ingress-nginx (LoadBalancer или NodePort)
|
||||
- Порт 80 доступен из интернета (firewall, Security Groups)
|
||||
|
||||
### Вручную
|
||||
|
||||
```bash
|
||||
# Из корня репозитория
|
||||
|
||||
# Вариант A: cert-manager — автоматические сертификаты
|
||||
./deploy/k3s/ssl/setup-kubernetes.sh cert-manager
|
||||
|
||||
# Вариант B: ручные сертификаты (certbot уже выполнен, файлы в backup/)
|
||||
./deploy/k3s/ssl/setup-kubernetes.sh manual
|
||||
```
|
||||
|
||||
**Требования:**
|
||||
- Namespace `gooseek` создан
|
||||
- Ingress-nginx установлен (порт 80 и 443)
|
||||
- Домен gooseek.ru указывает на IP кластера
|
||||
|
||||
---
|
||||
|
||||
## Структура папки
|
||||
|
||||
```
|
||||
deploy/k3s/ssl/
|
||||
├── README.md # эта инструкция
|
||||
├── setup-kubernetes.sh # настройка SSL в K8s (cert-manager или manual)
|
||||
├── obtain-cert.sh # получение сертификата на сервере (certbot)
|
||||
├── apply-secret.sh # создание Secret из backup/
|
||||
├── backup/ # сертификаты (в .gitignore)
|
||||
│ ├── fullchain.pem
|
||||
│ └── privkey.pem
|
||||
└── cert-manager-issuer.yaml
|
||||
```
|
||||
@@ -1,24 +0,0 @@
|
||||
#!/usr/bin/env bash
|
||||
# Создаёт/обновляет Secret gooseek-tls из бэкапа
|
||||
# Запуск из корня репозитория: ./deploy/k3s/ssl/apply-secret.sh
|
||||
|
||||
set -e
|
||||
|
||||
SCRIPT_DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)"
|
||||
BACKUP_DIR="$SCRIPT_DIR/backup"
|
||||
CERT="$BACKUP_DIR/fullchain.pem"
|
||||
KEY="$BACKUP_DIR/privkey.pem"
|
||||
|
||||
if [[ ! -f "$CERT" ]] || [[ ! -f "$KEY" ]]; then
|
||||
echo "Ошибка: нужны fullchain.pem и privkey.pem в $BACKUP_DIR"
|
||||
echo "См. deploy/k3s/ssl/README.md"
|
||||
exit 1
|
||||
fi
|
||||
|
||||
kubectl delete secret gooseek-tls -n gooseek 2>/dev/null || true
|
||||
kubectl create secret tls gooseek-tls \
|
||||
--namespace=gooseek \
|
||||
--cert="$CERT" \
|
||||
--key="$KEY"
|
||||
|
||||
echo "Secret gooseek-tls создан. Примените: kubectl apply -f deploy/k3s/ingress-production.yaml"
|
||||
@@ -1 +0,0 @@
|
||||
# Сюда класть fullchain.pem и privkey.pem (см. deploy/k3s/ssl/README.md)
|
||||
@@ -1,18 +0,0 @@
|
||||
# Опционально: cert-manager для автоматического получения сертификатов
|
||||
# Установка: kubectl apply -f https://github.com/cert-manager/cert-manager/releases/download/v1.13.0/cert-manager.yaml
|
||||
# Затем: kubectl apply -f deploy/k3s/ssl/cert-manager-issuer.yaml
|
||||
---
|
||||
apiVersion: cert-manager.io/v1
|
||||
kind: ClusterIssuer
|
||||
metadata:
|
||||
name: letsencrypt-prod
|
||||
spec:
|
||||
acme:
|
||||
server: https://acme-v02.api.letsencrypt.org/directory
|
||||
email: admin@gooseek.ru
|
||||
privateKeySecretRef:
|
||||
name: letsencrypt-prod-account
|
||||
solvers:
|
||||
- http01:
|
||||
ingress:
|
||||
class: nginx
|
||||
@@ -1,24 +0,0 @@
|
||||
#!/usr/bin/env bash
|
||||
# Проверка статуса сертификата gooseek.ru
|
||||
# Запуск: ./deploy/k3s/ssl/check-cert.sh
|
||||
|
||||
set -e
|
||||
|
||||
echo "=== Certificate (cert-manager) ==="
|
||||
kubectl get certificate -n gooseek 2>/dev/null || echo "Нет Certificate (используется backup?)"
|
||||
|
||||
echo ""
|
||||
echo "=== Secret gooseek-tls ==="
|
||||
kubectl get secret gooseek-tls -n gooseek 2>/dev/null || echo "Secret не найден"
|
||||
|
||||
echo ""
|
||||
echo "=== События Certificate ==="
|
||||
kubectl describe certificate -n gooseek 2>/dev/null | tail -30 || true
|
||||
|
||||
echo ""
|
||||
echo "=== Challenge (ACME) ==="
|
||||
kubectl get challenge -A 2>/dev/null || true
|
||||
|
||||
echo ""
|
||||
echo "=== Ingress ==="
|
||||
kubectl get ingress -n gooseek
|
||||
@@ -1,33 +0,0 @@
|
||||
#!/usr/bin/env bash
|
||||
# Получение SSL-сертификата Let's Encrypt для gooseek.ru
|
||||
# Запускать НА СЕРВЕРЕ (5.187.83.209), где домен указывает на этот IP
|
||||
# Перед запуском: порт 80 должен быть свободен (остановите nginx/приложения)
|
||||
|
||||
set -e
|
||||
|
||||
DOMAIN="gooseek.ru"
|
||||
EMAIL="admin@gooseek.ru"
|
||||
|
||||
echo "=== Установка certbot (если не установлен) ==="
|
||||
sudo apt update && sudo apt install -y certbot 2>/dev/null || true
|
||||
|
||||
echo ""
|
||||
echo "=== Получение сертификата для $DOMAIN и www.$DOMAIN ==="
|
||||
sudo certbot certonly --standalone \
|
||||
-d "$DOMAIN" \
|
||||
-d "www.$DOMAIN" \
|
||||
--email "$EMAIL" \
|
||||
--agree-tos \
|
||||
--no-eff-email \
|
||||
--non-interactive
|
||||
|
||||
echo ""
|
||||
echo "=== Готово! Сертификаты в: ==="
|
||||
echo " /etc/letsencrypt/live/$DOMAIN/fullchain.pem"
|
||||
echo " /etc/letsencrypt/live/$DOMAIN/privkey.pem"
|
||||
echo ""
|
||||
echo "Скопируйте в backup и примените Secret:"
|
||||
echo " sudo cp /etc/letsencrypt/live/$DOMAIN/fullchain.pem deploy/k3s/ssl/backup/"
|
||||
echo " sudo cp /etc/letsencrypt/live/$DOMAIN/privkey.pem deploy/k3s/ssl/backup/"
|
||||
echo " ./deploy/k3s/ssl/apply-secret.sh"
|
||||
echo " kubectl apply -f deploy/k3s/ingress-production.yaml"
|
||||
@@ -1,86 +0,0 @@
|
||||
#!/usr/bin/env bash
|
||||
# Настройка SSL в Kubernetes для gooseek.ru
|
||||
# Запуск из корня репозитория: ./deploy/k3s/ssl/setup-kubernetes.sh
|
||||
#
|
||||
# Вариант A: cert-manager (автоматические сертификаты Let's Encrypt)
|
||||
# Вариант B: ручные сертификаты (certbot на сервере → apply-secret.sh)
|
||||
|
||||
set -e
|
||||
|
||||
SCRIPT_DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)"
|
||||
REPO_ROOT="$(cd "$SCRIPT_DIR/../../.." && pwd)"
|
||||
CERT_MANAGER_VERSION="v1.13.0"
|
||||
|
||||
usage() {
|
||||
echo "Использование: $0 [cert-manager|manual]"
|
||||
echo ""
|
||||
echo " cert-manager — установить cert-manager и настроить автоматические сертификаты (рекомендуется)"
|
||||
echo " manual — применить ingress с ручным Secret (нужны fullchain.pem, privkey.pem в backup/)"
|
||||
echo ""
|
||||
echo "Без аргумента — cert-manager"
|
||||
}
|
||||
|
||||
apply_cert_manager() {
|
||||
echo "=== 1. Установка cert-manager ==="
|
||||
kubectl apply -f "https://github.com/cert-manager/cert-manager/releases/download/${CERT_MANAGER_VERSION}/cert-manager.yaml"
|
||||
echo "Ожидание готовности cert-manager (до 2 мин)..."
|
||||
kubectl wait --for=condition=Available deployment/cert-manager -n cert-manager --timeout=120s 2>/dev/null || true
|
||||
kubectl wait --for=condition=Available deployment/cert-manager-webhook -n cert-manager --timeout=120s 2>/dev/null || true
|
||||
kubectl wait --for=condition=Available deployment/cert-manager-cainjector -n cert-manager --timeout=120s 2>/dev/null || true
|
||||
|
||||
echo ""
|
||||
echo "=== 2. ClusterIssuer Let's Encrypt ==="
|
||||
kubectl apply -f "$SCRIPT_DIR/cert-manager-issuer.yaml"
|
||||
|
||||
echo ""
|
||||
echo "=== 3. Production Ingress (cert-manager создаст Secret gooseek-tls) ==="
|
||||
kubectl apply -f "$REPO_ROOT/deploy/k3s/ingress-production.yaml"
|
||||
|
||||
echo ""
|
||||
echo "=== Готово ==="
|
||||
echo "Сертификат будет получен в течение 1–2 минут."
|
||||
echo "Проверка: kubectl get certificate -n gooseek"
|
||||
echo "Проверка: kubectl get secret gooseek-tls -n gooseek"
|
||||
}
|
||||
|
||||
apply_manual() {
|
||||
if [[ ! -f "$SCRIPT_DIR/backup/fullchain.pem" ]] || [[ ! -f "$SCRIPT_DIR/backup/privkey.pem" ]]; then
|
||||
echo "Ошибка: нужны fullchain.pem и privkey.pem в $SCRIPT_DIR/backup/"
|
||||
echo "См. deploy/k3s/ssl/README.md — получите сертификат через certbot на сервере"
|
||||
exit 1
|
||||
fi
|
||||
|
||||
echo "=== 1. Secret gooseek-tls из backup ==="
|
||||
"$SCRIPT_DIR/apply-secret.sh"
|
||||
|
||||
echo ""
|
||||
echo "=== 2. Production Ingress (ручной Secret) ==="
|
||||
kubectl apply -f "$REPO_ROOT/deploy/k3s/ingress-production-manual.yaml"
|
||||
|
||||
echo ""
|
||||
echo "=== Готово ==="
|
||||
}
|
||||
|
||||
# Проверка namespace
|
||||
if ! kubectl get namespace gooseek &>/dev/null; then
|
||||
echo "Создание namespace gooseek..."
|
||||
kubectl apply -f "$REPO_ROOT/deploy/k3s/namespace.yaml"
|
||||
fi
|
||||
|
||||
# Проверка ingress-nginx
|
||||
if ! kubectl get deployment -n ingress-nginx ingress-nginx-controller &>/dev/null 2>&1; then
|
||||
echo "Внимание: ingress-nginx не найден. Установите:"
|
||||
echo " kubectl apply -f https://raw.githubusercontent.com/kubernetes/ingress-nginx/controller-v1.8.2/deploy/static/provider/cloud/deploy.yaml"
|
||||
echo ""
|
||||
read -p "Продолжить? (y/n) " -n 1 -r
|
||||
echo
|
||||
[[ $REPLY =~ ^[Yy]$ ]] || exit 1
|
||||
fi
|
||||
|
||||
MODE="${1:-cert-manager}"
|
||||
case "$MODE" in
|
||||
cert-manager) apply_cert_manager ;;
|
||||
manual) apply_manual ;;
|
||||
-h|--help) usage; exit 0 ;;
|
||||
*) echo "Неизвестный режим: $MODE"; usage; exit 1 ;;
|
||||
esac
|
||||
@@ -1,62 +0,0 @@
|
||||
# travel-svc — Trending, Inspiration
|
||||
apiVersion: apps/v1
|
||||
kind: Deployment
|
||||
metadata:
|
||||
name: travel-svc
|
||||
namespace: gooseek
|
||||
spec:
|
||||
replicas: 2
|
||||
selector:
|
||||
matchLabels:
|
||||
app: travel-svc
|
||||
template:
|
||||
metadata:
|
||||
labels:
|
||||
app: travel-svc
|
||||
annotations:
|
||||
prometheus.io/scrape: "true"
|
||||
prometheus.io/port: "3004"
|
||||
prometheus.io/path: "/metrics"
|
||||
spec:
|
||||
containers:
|
||||
- name: travel-svc
|
||||
image: gooseek/travel-svc:latest
|
||||
ports:
|
||||
- containerPort: 3004
|
||||
env:
|
||||
- name: REDIS_URL
|
||||
valueFrom:
|
||||
secretKeyRef:
|
||||
name: redis-credentials
|
||||
key: url
|
||||
livenessProbe:
|
||||
httpGet:
|
||||
path: /health
|
||||
port: 3004
|
||||
initialDelaySeconds: 5
|
||||
periodSeconds: 10
|
||||
readinessProbe:
|
||||
httpGet:
|
||||
path: /ready
|
||||
port: 3004
|
||||
initialDelaySeconds: 3
|
||||
periodSeconds: 5
|
||||
resources:
|
||||
requests:
|
||||
cpu: 50m
|
||||
memory: 128Mi
|
||||
limits:
|
||||
cpu: 500m
|
||||
memory: 512Mi
|
||||
---
|
||||
apiVersion: v1
|
||||
kind: Service
|
||||
metadata:
|
||||
name: travel-svc
|
||||
namespace: gooseek
|
||||
spec:
|
||||
selector:
|
||||
app: travel-svc
|
||||
ports:
|
||||
- port: 3004
|
||||
targetPort: 3004
|
||||
@@ -1,60 +0,0 @@
|
||||
# web-svc — Next.js UI
|
||||
# namespace: gooseek
|
||||
# API_GATEWAY_URL — URL api-gateway (внутри кластера или через ingress)
|
||||
apiVersion: apps/v1
|
||||
kind: Deployment
|
||||
metadata:
|
||||
name: web-svc
|
||||
namespace: gooseek
|
||||
spec:
|
||||
replicas: 1
|
||||
selector:
|
||||
matchLabels:
|
||||
app: web-svc
|
||||
template:
|
||||
metadata:
|
||||
labels:
|
||||
app: web-svc
|
||||
spec:
|
||||
containers:
|
||||
- name: web-svc
|
||||
image: gooseek/web-svc:latest
|
||||
imagePullPolicy: Never
|
||||
ports:
|
||||
- containerPort: 3000
|
||||
env:
|
||||
- name: PORT
|
||||
value: "3000"
|
||||
- name: API_GATEWAY_URL
|
||||
value: "http://api-gateway.gooseek:3015"
|
||||
livenessProbe:
|
||||
httpGet:
|
||||
path: /api/health
|
||||
port: 3000
|
||||
initialDelaySeconds: 10
|
||||
periodSeconds: 15
|
||||
readinessProbe:
|
||||
httpGet:
|
||||
path: /api/ready
|
||||
port: 3000
|
||||
initialDelaySeconds: 5
|
||||
periodSeconds: 10
|
||||
resources:
|
||||
requests:
|
||||
cpu: 100m
|
||||
memory: 256Mi
|
||||
limits:
|
||||
cpu: 1000m
|
||||
memory: 1Gi
|
||||
---
|
||||
apiVersion: v1
|
||||
kind: Service
|
||||
metadata:
|
||||
name: web-svc
|
||||
namespace: gooseek
|
||||
spec:
|
||||
selector:
|
||||
app: web-svc
|
||||
ports:
|
||||
- port: 3000
|
||||
targetPort: 3000
|
||||
Reference in New Issue
Block a user