# Usługa render — składanie raportu PDF (PRE-24). # # OSOBNY komponent, nie część prezentacji, z tego samego powodu co silnik # swisseph (LOG-27): obraz dźwiga TeX Live, czyli setki megabajtów. W obrazie # produktu spowalniałby każdy build i deploy; tak aktualizuje się niezależnie, # a jego awaria nie kładzie aplikacji — psuje się tylko przycisk „Pobierz PDF". # # Rozmawia WYŁĄCZNIE z prezentacją, po szyfrowanym łączu z własnym, trzecim # kluczem. Wystawiona jako ClusterIP — bez NodePort i bez Ingressu, bo nie ma # powodu, żeby ktokolwiek sięgał do niej z zewnątrz. apiVersion: apps/v1 kind: Deployment metadata: name: render namespace: astrololo spec: replicas: 1 selector: { matchLabels: { app: render } } template: metadata: { labels: { app: render } } spec: imagePullSecrets: [{ name: gitea-registry }] containers: - name: render image: gitea.czernobog.pl/gitea/astrololo-render:latest ports: [{ containerPort: 8004 }] env: # Token międzywarstwowy (LOG-32) — ta usługa dostaje CAŁY raport: # dane urodzeniowe i opisy z baz. - name: INTERNAL_TOKEN valueFrom: secretKeyRef: { name: astrololo-auth, key: INTERNAL_TOKEN } # Szyfrowanie łącza (PRE-16/PRE-24). OSOBNY klucz na parę rozmówców: # przejęcie klucza renderu nie może otwierać łącza do logiki ani danych. - name: LINK_KEY_PRESENTATION_RENDER valueFrom: secretKeyRef: { name: astrololo-link, key: LINK_KEY_PRESENTATION_RENDER } - name: LINK_ENCRYPTION_REQUIRED value: "true" # XeLaTeX na obszernym raporcie potrafi zjeść sporo pamięci i CPU, # ale tylko na chwilę — stąd wyraźna różnica między request a limit. resources: requests: { cpu: "100m", memory: "256Mi" } limits: { cpu: "1500m", memory: "1Gi" } # Kompilacja pisze wyłącznie do katalogu tymczasowego, który sprząta po # sobie. Dajemy na to emptyDir i zamykamy resztę systemu plików — # raport nie ma prawa zostawić śladu w kontenerze. volumeMounts: - { name: tmp, mountPath: /tmp } securityContext: readOnlyRootFilesystem: true allowPrivilegeEscalation: false readinessProbe: httpGet: { path: /health, port: 8004 } initialDelaySeconds: 5 periodSeconds: 15 volumes: - name: tmp emptyDir: { sizeLimit: 512Mi } --- apiVersion: v1 kind: Service metadata: name: render namespace: astrololo spec: type: ClusterIP # tylko dla prezentacji, bez wejścia z zewnątrz selector: { app: render } ports: [{ port: 8004, targetPort: 8004 }]