feat: default locale Russian, geo determines language for other countries
- localization-svc: defaultLocale ru, resolveLocale only by geo - web-svc: DEFAULT_LOCALE ru, layout lang=ru, embeddedTranslations fallback ru - countryToLocale: default ru when no country or unknown country Co-authored-by: Cursor <cursoragent@cursor.com>
This commit is contained in:
187
deploy/k3s/ssl/README.md
Normal file
187
deploy/k3s/ssl/README.md
Normal file
@@ -0,0 +1,187 @@
|
||||
# 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
|
||||
```
|
||||
24
deploy/k3s/ssl/apply-secret.sh
Executable file
24
deploy/k3s/ssl/apply-secret.sh
Executable file
@@ -0,0 +1,24 @@
|
||||
#!/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
deploy/k3s/ssl/backup/.gitkeep
Normal file
1
deploy/k3s/ssl/backup/.gitkeep
Normal file
@@ -0,0 +1 @@
|
||||
# Сюда класть fullchain.pem и privkey.pem (см. deploy/k3s/ssl/README.md)
|
||||
18
deploy/k3s/ssl/cert-manager-issuer.yaml
Normal file
18
deploy/k3s/ssl/cert-manager-issuer.yaml
Normal file
@@ -0,0 +1,18 @@
|
||||
# Опционально: 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
|
||||
24
deploy/k3s/ssl/check-cert.sh
Executable file
24
deploy/k3s/ssl/check-cert.sh
Executable file
@@ -0,0 +1,24 @@
|
||||
#!/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
|
||||
33
deploy/k3s/ssl/obtain-cert.sh
Executable file
33
deploy/k3s/ssl/obtain-cert.sh
Executable file
@@ -0,0 +1,33 @@
|
||||
#!/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"
|
||||
86
deploy/k3s/ssl/setup-kubernetes.sh
Executable file
86
deploy/k3s/ssl/setup-kubernetes.sh
Executable file
@@ -0,0 +1,86 @@
|
||||
#!/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
|
||||
Reference in New Issue
Block a user