Document bootstrap, post-deploy fixes, and day-to-day workflow on remote test contour. Co-authored-by: Cursor <cursoragent@cursor.com>
12 KiB
Как развернуть test-контур на CLOUD-SITE-TEST-01
Пошаговый рассказ: что делали при переносе песочницы с локальной Multipass-VM на удалённый сервер CLOUD-SITE-TEST-01 (dev.sovamed.ru). Для справочника по архитектуре см. CLOUD-SITE-TEST-01, для общего плана — k3s/DEPLOY.md.
0. Что было до этого
Локально крутилась Multipass-ферма (vm-k8s-git, *.sova.local, NodePort). Для общего test-контура на железе решили:
- один сервер, один k3s;
- публичные домены
*.dev.sovamed.ru; - Let's Encrypt вместо self-signed;
- без Redmine (экономия RAM);
- CI/CD и GitOps — как на локалке: Gitea → ArgoCD → Helm.
Исходники лежат в монорепо: оркестрация в k3s/, приложения и Helm — в k8s/.
1. Подготовка сервера и DNS
Сервер
| Имя | CLOUD-SITE-TEST-01 |
| Публичный IP | 46.243.172.227 |
| VPN / SSH / kubectl | 10.0.186.3 |
| Пользователь | petrov |
| RAM | 12 GB (+ swap 8 GB) |
DNS
A-записи на 46.243.172.227:
git.dev.sovamed.ru
argocd.dev.sovamed.ru
grafana.dev.sovamed.ru
api.dev.sovamed.ru
adm.dev.sovamed.ru
cabinet.dev.sovamed.ru
docs.dev.sovamed.ru
Порт 80 с интернета обязателен — без него Let's Encrypt (HTTP-01) не выпустит сертификаты.
VPN
SSH и kubectl с рабочей машины — через VPN на 10.0.186.3. Браузер — на публичные URL через DNS.
2. Настройка на Mac
cd k3s
cp remote.env.example remote.env
Заполнил remote.env (главное):
SERVER_IP=10.0.186.3 # VPN для SSH/kubectl
BASE_DOMAIN=dev.sovamed.ru
GITEA_DOMAIN=git.dev.sovamed.ru
API_DOMAIN=api.dev.sovamed.ru
# ... остальные домены
ENABLE_TLS=1
LETSENCRYPT_EMAIL=devops@sovamed.ru
CLUSTER_ISSUER=letsencrypt-prod
SWAP_GB=8
SKIP_REDMINE=1
KUBECONFIG_PATH=~/.kube/config-sova-remote-test
SSH-пароль и sudo — в remote.env (или ключ). SSH-пароль на сервере потом не меняли — только сервисные креды в k8s.
Права на скрипты:
chmod +x scripts/*.sh scripts/lib/*.sh
chmod +x ../k8s/scripts/*.sh
Проверка:
ssh petrov@10.0.186.3
3. Автоматический bootstrap (основной прогон)
cd k3s
./scripts/bootstrap-remote-test.sh
Скрипт bootstrap-remote-test.sh по шагам:
| Шаг | Что происходит |
|---|---|
| 1 | На сервере: swap 8 GB, apt, установка k3s (--disable traefik), скачивание kubeconfig на Mac |
| 2 | Platform: ingress-nginx (LB 80/443), cert-manager, sealed-secrets, ArgoCD, Prometheus/Grafana, Loki, Gitea; basic auth + ingress для git/argocd/grafana |
| 3 | Gitea: org sova, push репозиториев (backend, adminpanel, cabinet, docs, sova-deploy, sova-mocks) |
| 4 | Gitea Actions runner, CI secrets, registries.yaml на ноде для pull образов |
| 5 | PostgreSQL, MySQL, Redis, WireMock/Mailpit, db-init |
| 6 | ArgoCD: project, test-contour apps, ожидание Healthy |
| 7 | TLS: ClusterIssuer Let's Encrypt, выпуск сертификатов |
| 8 | Итог: список URL и паролей |
Если упало на середине — продолжить:
BOOTSTRAP_FROM_STEP=4 ./scripts/bootstrap-remote-test.sh
Kubeconfig после шага 1:
export KUBECONFIG=~/.kube/config-sova-remote-test
kubectl get nodes
4. Что правили после bootstrap
Автомат не покрывает всё — ниже реальные доработки на этом контуре.
4.1. Домены в GitOps
В k8s/sova-deploy/apps/*/values-test.yaml выставили хосты *.dev.sovamed.ru, TLS, образы из Gitea registry:
ingress:
host: api.dev.sovamed.ru
tls:
enabled: true
clusterIssuer: letsencrypt-prod
image:
repository: git.sova.local/sova/backend
tag: backend-v1.0.13-test
Запушили ветку test в Gitea (sova/sova-deploy) → ArgoCD подхватил.
4.2. Registry и pull образов
CI пушит в registry под git.sova.local, нода должна резолвить registry:
/etc/hostsна сервере:10.0.186.3 git.dev.sovamed.ru git.sova.local/etc/rancher/k3s/registries.yaml— mirror + credentials- Скрипт:
k8s/scripts/configure-k3s-registry-remote.sh
4.3. CI/CD под HTTPS
Обновили workflow build.yml в app-репозиториях и скрипты (gitea-url.sh, release-tag.sh, bootstrap-gitea-ci-secrets.sh) — Gitea с Mac/VPN через https://10.0.186.3 + заголовок Host: git.dev.sovamed.ru.
Проверка релиза:
cd k8s
export KUBECONFIG=~/.kube/config-sova-remote-test
export VM_IP=10.0.186.3 GITEA_SCHEME=https GITEA_HTTP_PORT=443 GITEA_INSECURE_TLS=1
export GITEA_HOST=git.dev.sovamed.ru
./scripts/release-tag.sh backend backend-v1.0.13-test
Цепочка: тег → Gitea Actions → образ в registry → commit в sova-deploy → ArgoCD sync → pod.
4.4. Ветки issues/27
Перенесли feature-ветки из монорепо в Gitea и смержили в test:
./scripts/migrate-issues-27-branches.sh
# merge issues/27 → test для backend, adminpanel, cabinet
4.5. TLS на приложениях
После sync ArgoCD ingress терял TLS — добавили блок tls в Helm-шаблоны sova-deploy/apps/*/templates/all.yaml и ingress.tls.enabled в values-test.
4.6. Redmine убрали
Redmine на этом сервере не нужен:
kubectl delete application redmine-test -n argocd
4.7. Пароли
Сгенерировали сложные пароли для Gitea, ArgoCD, Grafana, БД, app secrets. Применили:
- helm/API для platform;
ALTER USERв PostgreSQL/MySQL;- GitOps (
sova-deploy/data/test,apps/*/values.yaml); - bcrypt для seed-пользователей admin/cabinet.
Все креды — k8s/.generated/platform-credentials.env (не в git). SSH не трогали.
4.8. Admin Panel — API URL
Admin Panel не логинился: в values-test.yaml был ключ env: вместо runtimeEnv: → в pod уходил http://api.test.sova.local. Исправили:
runtimeEnv:
API_BASE_URL: https://api.dev.sovamed.ru
4.9. Grafana + Loki
Grafana падала из-за двух default datasource. Решение:
- Loki подключён через
grafana.additionalDataSourcesвvalues-lite-12gb.yaml; - отдельный ConfigMap
loki-loki-stackудаляется после helm loki-stack.
4.10. Basic Auth на периметре
Все публичные URL закрыты HTTP Basic Auth на ingress:
./scripts/bootstrap-ingress-basic-auth.sh # secret contour-basic-auth
./scripts/deploy-platform-ingress.sh # platform ingress
Логin: sova-contour, пароль — в platform-credentials.env.
Для Gitea — два Ingress: /api, /v2, /sova без auth (CI/git), веб-UI / — с auth.
5. Типичный рабочий цикл после развёртывания
kubectl
export KUBECONFIG=~/.kube/config-sova-remote-test
kubectl get applications -n argocd
kubectl get pods -n sova-test
Выкат новой версии приложения
cd k8s
./scripts/release-tag.sh backend backend-v1.0.14-test
# аналогично: adminpanel, cabinet, docs
Выкат документации
./scripts/release-tag.sh docs docs-v1.0.15-test
ArgoCD sync вручную
kubectl annotate application backend-test -n argocd argocd.argoproj.io/refresh=hard --overwrite
Креды
cat k8s/.generated/platform-credentials.env
./scripts/print-credentials.sh
6. Проверка «всё живо»
export KUBECONFIG=~/.kube/config-sova-remote-test
source k8s/.generated/platform-credentials.env
# Basic auth + TLS
curl -sk -o /dev/null -w "%{http_code}\n" -u "${BASIC_AUTH_USER}:${BASIC_AUTH_PASS}" \
-H "Host: api.dev.sovamed.ru" https://10.0.186.3/
# ArgoCD
kubectl get applications -n argocd
# Сертификаты
kubectl get certificate -A
# CI
curl -sk -u "gitea_admin:${GITEA_ADMIN_PASS}" -H "Host: git.dev.sovamed.ru" \
"https://10.0.186.3/api/v1/repos/sova/backend/actions/runs?limit=1"
Чеклист:
kubectl get nodes— Ready- ArgoCD apps — Synced / Healthy
- URL открываются (с basic auth → затем логин сервиса)
kubectl get certificate -A— Ready- CI по тегу
*-test— success - Grafana Explore → Loki →
{namespace="sova-test"}
7. Карта скриптов (что за что отвечает)
k3s/scripts/bootstrap-remote-test.sh ← главная команда «развернуть всё»
k3s/remote.env ← IP, домены, TLS, SSH
k8s/scripts/deploy-platform-remote.sh ← Helm: ingress, cert-manager, ArgoCD, Gitea…
k8s/scripts/deploy-platform-ingress.sh ← Ingress git / argocd / grafana (+ basic auth)
k8s/scripts/bootstrap-ingress-basic-auth.sh
k8s/scripts/bootstrap-gitea.sh ← org, repos, admin
k8s/scripts/bootstrap-gitea-runner.sh ← Actions runner
k8s/scripts/bootstrap-gitea-ci-secrets.sh
k8s/scripts/configure-k3s-registry-remote.sh
k8s/scripts/deploy-test-stack.sh ← БД + mocks (DATA_ONLY=1)
k8s/scripts/bootstrap-argocd.sh ← GitOps apps
k8s/scripts/bootstrap-tls.sh ← Let's Encrypt
k8s/scripts/release-tag.sh ← тег → CI → deploy
8. Частые проблемы
| Симптом | Что делали |
|---|---|
| ImagePullBackOff | configure-k3s-registry-remote.sh, /etc/hosts на ноде |
| ArgoCD «Failed to authenticate» к Gitea | обновить secret repo-sova-deploy с новым паролем Gitea |
| Admin Panel не логинится | runtimeEnv.API_BASE_URL, не env: |
| Grafana CrashLoop | один default datasource; Loki через Helm additionalDataSources |
| Symfony «parameter 3Dbi6a» | в REDIS_URL/DATABASE_URL удвоить % → %% для GitOps |
| CI 403 на push | проверить Gitea credentials, gitea_git_remote_url (URL-encode пароля) |
| Let's Encrypt pending | DNS, порт 80, /.well-known/acme-challenge без auth |
9. Ссылки
- CLOUD-SITE-TEST-01 — справочник по системе
- Gitea CI / теги
- Система тегов
- ArgoCD apps
- Grafana / Loki
k3s/TLS.md
Документ описывает фактический процесс развёртывания test-контура на CLOUD-SITE-TEST-01 (2026).