Deine erste App deployen
Das ist der zweite Schritt des Lernpfads. Du betreibst upcheck, eine Django-App mit Celery-Worker, Scheduler, Postgres und Cache, auf dem Cluster aus Schritt 1, über HTTPS unter einem Namen von dir erreichbar. Dafür reicht eine Datei, die die nächsten Schritte unverändert auf andere Cluster anwenden, nur mit anderem Namen.
Was du am Ende hast
Abschnitt betitelt „Was du am Ende hast“upcheck auf upcheck-prod, mit Postgres, betrieben von CloudNativePG, einem Valkey-Cache und Migrationen, die vor jeder neuen Version laufen. All das ist eine Datei, upcheck.yaml, mit einer SaaSApplication: der Beschreibung der App, was sie braucht. Das Add-on PaaSbox Platform macht daraus Deployments, Jobs, eine Datenbank und einen Ingress mit Zertifikat.
Was du brauchst
Abschnitt betitelt „Was du brauchst“upcheck-prodaus Schritt 1, auf Release2026.10.2oder neuer: Mit diesem Release kommt die PaaSbox Platform. Der Kopf der Cluster-Seite nennt sein Release; nennt er ein älteres, upgrade den Cluster zuerst.- Ein Image von upcheck in einer Registry, aus der der Server ziehen kann. Bau es aus github.com/mitja/upcheck und push es. Für eine private Registry legst du ein Pull-Secret im Namespace
upcheckan und nennst es unterspec.imagePullSecrets. - Einen Hostnamen für die App in einer DNS-Zone, in die du schreiben kannst, zum Beispiel
upcheck.example.com. Das Portal legt pro Cluster einen DNS-Namen an, für seine Kubernetes-API, und keinen für Apps. Ein Name unter<team>.paasbox.appdeines Teams geht auch, sobald dieser Dienst öffnet. - Die Admin-Kubeconfig von
upcheck-prodaus Schritt 1.
Den Namen auf den Server richten
Abschnitt betitelt „Den Namen auf den Server richten“-
Auf der Overview des Clusters zeigt die Tabelle Nodes die IPv4-Adresse des Servers unter Address.
-
Leg in deiner DNS-Zone einen
A-Record vonupcheck.example.comauf diese Adresse an. Let’s Encrypt prüft den Namen über HTTP auf Port 80, den die Firewall des Clusters für alle öffnet; das Zertifikat lässt sich also erst ausstellen, wenn der Name auf den Server zeigt.
Die PaaSbox Platform einschalten
Abschnitt betitelt „Die PaaSbox Platform einschalten“-
Öffne den Reiter Add-ons des Clusters und such PaaSbox Platform (
paasbox-platform). Setz das Häkchen bei On. Lass das Profile aufsaas-http01: Postgres mit Backups und Wiederherstellung und ein Let’s-Encrypt-Zertifikat pro App über HTTP-01. Lass Observability aus: Mit Postgres braucht es einen Server mit 8 GB, und auf einemcpx22lehnt die Seite es ab. Trag unter ACME e-mail deine Adresse ein: Let’s Encrypt legt das Konto unter ihr an, und ohne sie speichert das Add-on nicht. Lass Let’s Encrypt aufproduction, für ein Zertifikat, dem Browser vertrauen;stagingprobiert ein Setup ohne die Ratenlimits der Produktion aus. -
Setz unter In the same save das Häkchen bei Switch Flux on too. Die Plattform installiert ihre Teile als Flux-Kustomizations und braucht darum das Add-on Flux. Ist das Add-on cert-manager an, setz auch Switch cert-manager off in the same save: Die Plattform bringt ihren eigenen cert-manager mit, und beide können nicht nebeneinander laufen. Wähle Save.
-
Die Zeile des Add-ons sagt, was der Cluster meldet, etwa 30 Sekunden später. Sie bleibt pending, während Flux cert-manager, CloudNativePG und die Issuer installiert, und wechselt auf applied, sobald die Plattform bereit ist. Im Labor am 2026-10-11 war Flux allein 71 Sekunden nach dem Speichern applied, und Flux mit dem Profil
minimalder Plattform in einem Speichern nach 2 Minuten 53 Sekunden. Prüf es von deinem Rechner aus:Terminal-Fenster kubectl get platformkubectl -n flux-system get kustomizationsEine Platform, benannt nach dem Cluster, mit
READYTrueund dem Profilsaas-http01; die Kustomizationsplatform-cert-manager,platform-tlsundplatform-postgressind bereit.
Wenn das Add-on pending bleibt. Ein Teil der Plattform, der einmal fehlgeschlagen ist, wird erst nach einer Stunde wieder versucht. Im Labor geschah das, als vorher das Add-on cert-manager an war: Der Webhook von cert-manager wechselte sein Zertifikat, während Postgres eingerichtet wurde. Such die Kustomization, deren READY auf False steht, und bitte Flux, sie jetzt zu versuchen, zuerst die innere (tls, postgres), dann ihre platform--Kustomization:
kubectl -n flux-system get kustomizationskubectl -n flux-system annotate --overwrite kustomization tls reconcile.fluxcd.io/requestedAt="$(date +%s)"kubectl -n flux-system annotate --overwrite kustomization platform-tls reconcile.fluxcd.io/requestedAt="$(date +%s)"Im Labor hatte ein cpx22 mit Flux und saas-http01 ohne App 1,4 GiB Speicher frei, und upcheck belegte 559 bis 606 MiB: Platz für eine App von der Größe von upcheck, nicht für zwei. Das Release plant für Flux 170 MiB und für die Plattform 300 MiB, mehr als das Labor gemessen hat.
upcheck.yaml schreiben
Abschnitt betitelt „upcheck.yaml schreiben“Speichere das als upcheck.yaml, mit deinem Image und deinem Hostnamen:
apiVersion: v1kind: Namespacemetadata: name: upcheck---apiVersion: platform.paasbox.com/v1alpha1kind: SaaSApplicationmetadata: name: upcheck namespace: upcheckspec: image: registry.example.com/upcheck:1 # dein Build von upcheck framework: profile: django components: - name: web runtime: requestDriven port: 8000 - name: worker command: [celery, -A, project, worker, -l, INFO, --concurrency, "2"] - name: beat runtime: singleton # nie zwei: sie würden jede Aufgabe doppelt planen command: [celery, -A, project, beat, -l, INFO, --scheduler, django_celery_beat.schedulers:DatabaseScheduler] data: postgres: class: small cache: class: small release: preDeploy: - name: migrate command: [python, manage.py, migrate, --noinput] - name: bootstrap command: [python, manage.py, bootstrap_celery_tasks] env: - name: DJANGO_SETTINGS_MODULE value: project.settings_production exposure: hostname: upcheck.example.com # dein Name; jede Stage bekommt ihren eigenen tls: clusterIssuer: letsencrypt-http01framework.profile: djangosetztSECRET_KEY(einmal erzeugt),ALLOWED_HOSTSundCSRF_TRUSTED_ORIGINSund prüft die App mit ihrem öffentlichen Hostnamen.componentswerden Deployments;webbekommt den Serviceupcheck-webauf Port 80, vor dem Port 8000 des Containers.beatläuft als ein Replikat, das gestoppt wird, bevor ein neues startet.datalegt die Postgres-Datenbankupcheck-pgmit einer Instanz und einem Volume von 2 GiB an, gebunden alsDATABASE_URL, und den Valkey-Cache, gebunden alsREDIS_URL.release.preDeployführt die Migrationen als Job aus, bevor irgendeine Komponente ein neues Image bekommt.exposurelegt einen Ingress über Traefik an, mit einem Zertifikat vonletsencrypt-http01, dem Issuer der Plattform; er fragt den Dienst von Let’s Encrypt an, den die Option Let’s Encrypt des Add-ons nennt. Statt eines Hostnamens pro App kannst du die Default domain des Add-ons setzen, zum Beispielapps.example.commit einemA-Record für*.apps.example.com, undexposure: {}schreiben: Die App läuft dann unterupcheck.apps.example.com. Das Labor hat upcheck so betrieben.
Deployen
Abschnitt betitelt „Deployen“-
Wende die Datei an und beobachte die App:
Terminal-Fenster kubectl apply -f upcheck.yamlkubectl -n upcheck get saasapp upcheck -w -
Verfolge die Phase. Pending: Postgres und der Cache sind noch nicht bereit, sonst läuft nichts. Releasing: Der Job
upcheck-release-<id>führtmigrateundbootstrapaus; keine Komponente existiert, bevor das erste Release seine Hooks bestanden hat, also bedient nichts eine Datenbank, die nicht migriert ist. Ready: Jede Komponente hat ihre Replikate. Failed heißt, ein Hook ist fehlgeschlagen;kubectl -n upcheck describe saasapp upcheckzeigt jeden Phasenwechsel als Event. -
Steht die Phase auf Ready, zeigt die Spalte
URLhttps://upcheck.example.com. Öffne sie in deinem Browser. Im Labor am 2026-10-11 war upcheck 82 Sekunden nachkubectl applyReady, sein Release-Job fertig, bevor seine Deployments angelegt wurden.
Ohne das Platform-Add-on
Abschnitt betitelt „Ohne das Platform-Add-on“Für eine App, die aus einem Image besteht, reichen Traefik und das Add-on cert-manager. Schalte auf dem Reiter Add-ons cert-manager ein, mit deiner ACME e-mail und der Challenge http01. Ein Ingress mit der Annotation kubernetes.io/tls-acme: "true" bekommt dann ein Zertifikat vom Default issuer:
apiVersion: networking.k8s.io/v1kind: Ingressmetadata: name: web annotations: kubernetes.io/tls-acme: "true"spec: ingressClassName: traefik rules: - host: web.example.com http: paths: - {path: /, pathType: Prefix, backend: {service: {name: web, port: {number: 80}}}} tls: - {hosts: [web.example.com], secretName: web-tls}Gebaut Im Labor waren die Issuer des Add-ons nach 21 Sekunden bereit, und ein Zertifikat vom Staging-Dienst von Let’s Encrypt war über Traefik nach 31 Sekunden ausgestellt. Ein Deployment und einen Service für das Image, und Postgres oder Redis daneben, findest du unter Deine Apps betreiben. Dieser Weg und die Plattform schließen sich auf einem Cluster aus.
Was du jetzt hast
Abschnitt betitelt „Was du jetzt hast“upcheck in Produktion, unter deinem Namen, über HTTPS, aus einer Datei. Lass es laufen: In Schritt 3 testet ein Agent es in einem eigenen Cluster, und Schritt 4 deployt dieselbe Datei nach Staging. Sein web läuft mit einer Replik: Während eine neue Version ausgerollt wird, antwortete die App im Labor etwa 30 Sekunden lang mit Fehlern.
Die Datenbank ist ein Volume auf der Platte des Servers, und ein Snapshot des Clusters enthält sie nicht (Schritt 5 zeigt das). Bevor echte Nutzer davon abhängen, gib ihr eigene Backups: data.postgres.backup schickt ihr Write-Ahead-Log laufend in einen S3-Bucket und macht jeden Tag ein Basis-Backup. Gib jeder Stage einen eigenen Ordner: Ein Ordner, der schon das Log einer anderen Datenbank enthält, wird abgelehnt.