pyswisseph to rozszerzenie C, a na PyPI (2.10.3.2) gotowe wheels koncza sie na cp311 i obejmuja wylacznie i686/x86_64. Obraz stoi na python:3.12-slim, wiec pip ZAWSZE kompilowal ze zrodel - a slim nie ma kompilatora. Stad fail. - Dockerfile wieloetapowy: kompilacja w etapie builder (build-essential), do runtime trafia juz tylko gotowy wheel - obraz zostaje czysty i maly. Dziala tez na arm64, gdzie wheeli linuksowych nie ma dla zadnej wersji. - sanity check (import swisseph) na etapie builda, zeby niedzialajacy silnik wywracal build, a nie dopiero pierwszy request. - CI: nowy job swisseph-image - realny docker build + smoke test /health i /positions na horoskopie referencyjnym. - README: udokumentowany powod wieloetapowego builda. Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
engine-swisseph (silnik B — AGPL, izolowany)
Osobna, opcjonalna usługa będąca drugim silnikiem efemeryd (LOG‑27). Liczy pozycje przez pyswisseph / Swiss Ephemeris i służy jako wyrocznia walidacyjna / tryb porównawczy (LOG‑25/26) dla naszego silnika własnego.
⚠️ Licencja
Ten komponent jest AGPL‑3.0 (bo linkuje Swiss Ephemeris) — patrz LICENSE. Jest wydzielony jako osobny proces i wołany przez HTTP, więc nie „zaraża" permisywnej reszty systemu. Nie wchodzi do dystrybucji zamkniętego produktu.
API
POST /positions→{when_utc, lat, lon, objects?}→ pozycje (ten sam kształt co silnik własny)GET /health
Tryb Moshiera (FLG_MOSEPH) — bez plików efemeryd, zero konfiguracji.
Build obrazu
docker compose --profile comparison build engine-swisseph
Dockerfile jest wieloetapowy i to nie jest ozdobnik: pyswisseph to rozszerzenie
C, a na PyPI (2.10.3.2) gotowe wheels kończą się na cp311 i obejmują wyłącznie
i686/x86_64. Dla Pythona 3.12 oraz dla arm64 pip musi kompilować ze źródeł, więc
sam python:3.12-slim (bez kompilatora) build wywracał. Kompilacja idzie w etapie
builder (build-essential), a do obrazu finalnego trafia już tylko gotowy wheel —
runtime zostaje czysty i mały. Pierwszy build trwa ~1–2 min, kolejne idą z cache warstw.
Build kończy się sanity-checkiem (import swisseph), żeby niedziałający silnik
wykrzaczył build, a nie dopiero pierwszy request.
Uruchomienie (tylko profil porównawczy / dev / CI)
pip install -r requirements.txt # wymaga kompilatora C (patrz wyżej)
uvicorn app.main:app --port 8003
Następnie w warstwie logicznej ustaw ENGINE_SWISSEPH_URL=http://localhost:8003,
aby włączyć silnik B (tryb dual-run i testy kontraktowe silnika B).