feat(astrololo): profil deployu swisseph (silnik B, AGPL) #1

Merged
gitea merged 1 commits from feat/swisseph-profile into master 2026-07-21 01:02:30 +00:00
4 changed files with 182 additions and 0 deletions
+70
View File
@@ -0,0 +1,70 @@
# Profil deployu: `swisseph` (silnik B, AGPL)
Drugi, **opcjonalny** wariant deployu astrololo. Ten sam stack co produkcja, ale
warstwa logiczna liczy na **Swiss Ephemeris** (silnik B, AGPL) zamiast na własnym
Skyfieldzie. Zbudowany jako overlay Kustomize nad bazą `../astrololo`.
## Co robi
- dokłada usługę **`engine-swisseph`** (Deployment + Service, **ClusterIP**),
- przełącza `logic` na `EPHEMERIS_ENGINE=swisseph` i ustawia
`ENGINE_SWISSEPH_URL=http://engine-swisseph:8003`,
- data / logic / presentation oraz ich tagi obrazów **dziedziczy z bazy** — profil
śledzi tę samą wersję co produkcja (podbija ją ten sam image-updater).
Włączenie `ENGINE_SWISSEPH_URL` uruchamia też endpoint **`/chart/compare`** — czyli
w jednej instancji logica masz porównanie own vs swisseph (LOG-25/26), bez stawiania
drugiego równoległego stacku.
## ⚠️ Licencja / izolacja
`engine-swisseph` jest **AGPL-3.0** i dlatego:
- to **osobny proces/obraz**, wołany przez HTTP — permisywny produkt nie jest z nim
linkowany,
- Service jest **ClusterIP** (świadomie **bez** NodePort/Ingress): rozmawia z nim
tylko `logic`, usługa nie jest wystawiona użytkownikom końcowym.
Ten profil służy do walidacji / porównań i **nie jest** dystrybucją zamkniętego
produktu.
## Aktywacja
To profil **zastępujący** bazę w tym samym namespace `astrololo` (nie dokładający się
obok). Wskaż kontroler GitOps (Argo CD / Flux) na katalog `astrololo-swisseph`
**zamiast** `astrololo`:
```yaml
# np. w Argo CD Application:
source:
path: astrololo-swisseph # było: astrololo
```
Ręcznie:
```bash
kubectl apply -k astrololo-swisseph
```
> **Nie** trzymaj obu reconcilerów naraz na ns `astrololo` — baza (own) i ten profil
> (swisseph) biłyby się o patch `logica`. Wybierasz jeden albo drugi.
>
> Powrót do własnego silnika: wskaż GitOps z powrotem na `astrololo` (albo
> `kubectl apply -k astrololo` — usuń wtedy ręcznie Deployment/Service
> `engine-swisseph`, bo baza go nie zna).
## Wymagania wstępne
1. **Obraz silnika B** musi istnieć w registry:
`gitea.czernobog.pl/gitea/astrololo-engine-swisseph`. Buduje go workflow
`.gitea/workflows/build-swisseph.yaml` w repo `astrololo` (odpala się przy zmianach
w `services/engine-swisseph/**`; można też ręcznie przez `workflow_dispatch`).
Overlay używa tagu `latest` — podmień w `kustomization.yaml` na przypięty SHA, gdy
zechcesz zamrozić wersję.
2. Ten sam ns `astrololo` → reużywa istniejący pull-secret `gitea-registry` i montaż
NFS z `data.yaml`. (Gdybyś wolał postawić profil **obok** produkcji w osobnym ns,
odkomentuj `namespace:` w `kustomization.yaml` i utwórz w nowym ns pull-secret
`gitea-registry` oraz upewnij się co do dostępu do NFS.)
## Weryfikacja po wdrożeniu
```bash
kubectl -n astrololo rollout status deploy/engine-swisseph
kubectl -n astrololo exec deploy/logic -- \
sh -c 'wget -qO- http://engine-swisseph:8003/health'
# oczekiwane: {"engine":"swisseph","status":"ok","mode":"moshier",...}
```
Następnie w UI/`logic` policz dowolny horoskop i porównaj przez `/chart/compare`.
+51
View File
@@ -0,0 +1,51 @@
# Silnik B — Swiss Ephemeris (AGPL-3.0), IZOLOWANY.
#
# Wdrażany WYŁĄCZNIE w profilu swisseph. Usługa jest wystawiona tylko wewnątrz
# klastra (ClusterIP — brak NodePort/Ingress): rozmawia z nią jedynie `logic`.
# To utrzymuje granicę procesu/sieci wymaganą przez izolację AGPL — permisywny
# produkt nie jest z nią linkowany, a usługa nie jest oferowana użytkownikom
# końcowym bezpośrednio.
apiVersion: apps/v1
kind: Deployment
metadata:
name: engine-swisseph
namespace: astrololo
labels:
app: engine-swisseph
license: AGPL-3.0
spec:
replicas: 1
selector: { matchLabels: { app: engine-swisseph } }
template:
metadata:
labels:
app: engine-swisseph
license: AGPL-3.0
spec:
imagePullSecrets: [{ name: gitea-registry }]
containers:
- name: engine-swisseph
image: gitea.czernobog.pl/gitea/astrololo-engine-swisseph:latest
imagePullPolicy: Always # tag ruchomy (latest) — dociągaj najnowszy
ports: [{ containerPort: 8003 }]
readinessProbe:
httpGet: { path: /health, port: 8003 }
initialDelaySeconds: 3
periodSeconds: 10
livenessProbe:
httpGet: { path: /health, port: 8003 }
initialDelaySeconds: 10
periodSeconds: 30
resources:
requests: { cpu: "50m", memory: "96Mi" }
limits: { cpu: "300m", memory: "256Mi" }
---
apiVersion: v1
kind: Service
metadata:
name: engine-swisseph
namespace: astrololo
spec:
selector: { app: engine-swisseph }
ports: [{ port: 8003, targetPort: 8003 }]
# ClusterIP (domyślnie) — świadomie brak type: NodePort. Tylko ruch wewnątrz klastra.
+39
View File
@@ -0,0 +1,39 @@
apiVersion: kustomize.config.k8s.io/v1beta1
kind: Kustomization
# Profil "swisseph" — DRUGI, opcjonalny wariant deployu, w którym warstwa logiczna
# liczy na silniku B (Swiss Ephemeris / AGPL) zamiast na własnym (Skyfield).
#
# Bierze cały bazowy stack (namespace + data + logic + presentation) i:
# 1. dokłada usługę engine-swisseph (AGPL, izolowaną, tylko wewnątrz klastra),
# 2. przełącza `logic` na EPHEMERIS_ENGINE=swisseph i wskazuje jej silnik B.
#
# Tagi obrazów data/logic/presentation dziedziczą się z bazy (../astrololo) — więc
# ten profil śledzi tę samą wersję co produkcja; podbija je ten sam image-updater.
#
# AKTYWACJA: wskaż kontroler GitOps (Argo/Flux) na `astrololo-swisseph` ZAMIAST
# `astrololo`. To profil ZASTĘPUJĄCY bazę w tym samym namespace — nie uruchamiaj
# obu reconcilerów naraz na ns `astrololo` (biłyby się o patch logica).
# Zobacz README.md.
# Zostaje w tym samym namespace co baza (astrololo) — reużywa m.in. secret
# gitea-registry i montaż NFS z data.yaml. Aby zamiast tego postawić profil obok
# produkcji (A/B w osobnym ns), odkomentuj poniższe i utwórz w nim pull-secret:
# namespace: astrololo-swisseph
resources:
- ../astrololo
- engine-swisseph.yaml
patches:
- path: logic-swisseph.patch.yaml
target:
kind: Deployment
name: logic
images:
# Obraz silnika B budowany osobnym workflow (.gitea/workflows/build-swisseph.yaml
# w repo astrololo) — nie wchodzi do głównego pipeline'u produktu. Podmień na
# przypięty tag (SHA), gdy zechcesz zamrozić wersję.
- name: gitea.czernobog.pl/gitea/astrololo-engine-swisseph
newTag: latest
@@ -0,0 +1,22 @@
# Patch warstwy logicznej dla profilu swisseph.
# Strategic merge po kluczu `name`: nadpisuje EPHEMERIS_ENGINE (own -> swisseph)
# i DODAJE ENGINE_SWISSEPH_URL; DATA_URL i reszta env z bazy zostają nietknięte.
#
# EPHEMERIS_ENGINE=swisseph -> silnikiem GŁÓWNYM jest RemoteEngine (Swiss Ephemeris).
# ENGINE_SWISSEPH_URL -> adres usługi silnika B; włącza też /chart/compare
# (porównanie own vs swisseph, LOG-25/26).
apiVersion: apps/v1
kind: Deployment
metadata:
name: logic
namespace: astrololo
spec:
template:
spec:
containers:
- name: logic
env:
- name: EPHEMERIS_ENGINE
value: "swisseph"
- name: ENGINE_SWISSEPH_URL
value: "http://engine-swisseph:8003"