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:
home
2026-02-23 22:14:00 +03:00
parent cd6b7857ba
commit 328d968f3f
180 changed files with 3022 additions and 9798 deletions

7
deploy/docker/Caddyfile Normal file
View 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
}

View 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
View 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

View 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',
]

View 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

View File

@@ -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

View File

@@ -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

View File

@@ -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

View File

@@ -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

View File

@@ -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"

View File

@@ -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"

View File

@@ -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

View File

@@ -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

View File

@@ -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

View File

@@ -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

View File

@@ -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

View File

@@ -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

View File

@@ -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

View File

@@ -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

View File

@@ -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

View File

@@ -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

View File

@@ -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"

View File

@@ -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

View File

@@ -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

View File

@@ -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: {}

View File

@@ -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

View File

@@ -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

View File

@@ -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

View File

@@ -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

View File

@@ -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
```

View File

@@ -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"

View File

@@ -1 +0,0 @@
# Сюда класть fullchain.pem и privkey.pem (см. deploy/k3s/ssl/README.md)

View File

@@ -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

View File

@@ -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

View File

@@ -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"

View File

@@ -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 "Сертификат будет получен в течение 12 минут."
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

View File

@@ -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

View File

@@ -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