Skip to main content
Version: 2.0

App Lifecycle

Service: app-service · Port: 8112

KubeOpera deploys applications without anyone writing YAML. You describe what your app is — its image, ports, resources, scaling and exposure — and the app service generates everything Kubernetes needs, following production best practices by default. app-controller commits the result to Git and Flux deploys it.

End-to-end flow​

From Deploy to live

The four stages the Deploy Application wizard shows. Select a stage for details.

Select a stage to see what happens behind it.
  1. You describe the app in the dashboard or through the API.
  2. kubeopera-api records it as a KubeOperaApp resource.
  3. app-controller asks the app service to generate manifests.
  4. app-controller commits them to Git and points Flux at them.
  5. Flux applies them in the tenant's vCluster.

What gets generated​

From one app definition, the app service produces:

ResourceWhenWhy
NamespaceAlwaysEach app gets its own namespace.
ServiceAccountAlwaysA dedicated identity per app, with no extra permissions.
DeploymentAlwaysYour containers, with resources, probes, environment and a safe rolling-update strategy.
ConfigMapWhen you set plain environment variablesConfiguration, kept out of the pod spec.
ServiceWhen service.enabledA stable in-cluster address (ClusterIP by default).
IngressWhen ingress.enabledExternal HTTPS access, with a cert-manager certificate when tls is on.
HorizontalPodAutoscalerWhen autoscaling.enabledScale on CPU (and memory, if set).
PodDisruptionBudgetWhen running 2+ replicasStay available during node maintenance.
NetworkPolicyAlwaysDeny inbound traffic by default, and allow only what the app exposes.

Defaults follow Kubernetes best practice: containers run as non-root with a read-only root filesystem where possible, resource requests are always set, and liveness and readiness probes are added for the app's port.

The app definition​

{
"app": {
"name": "payments-api",
"namespace": "payments",
"type": "api",
"containers": [
{
"name": "payments-api",
"image": "registry.example.com/payments-api:v1.2.3",
"ports": [{ "containerPort": 8080 }],
"env": [
{ "name": "LOG_LEVEL", "value": "info" },
{ "name": "DB_PASSWORD", "valueFrom": { "secretKeyRef": { "name": "payments-db", "key": "password" } } }
],
"resources": {
"requests": { "cpu": "100m", "memory": "128Mi" },
"limits": { "cpu": "500m", "memory": "512Mi" }
},
"healthCheck": { "path": "/healthz" }
}
],
"service": { "enabled": true },
"ingress": { "enabled": true, "host": "payments.example.com", "tls": true },
"autoscaling": { "enabled": true, "minReplicas": 2, "maxReplicas": 10, "targetCPU": 70 }
}
}
FieldDescription
name, namespaceThe app's name and namespace.
typeapi, web, worker or job — sets sensible defaults (for example, workers get no Service or Ingress).
containers[]One or more containers: image, ports, environment, resources and health check.
serviceWhether to create a Service, and its type (ClusterIP or LoadBalancer).
ingressWhether to expose the app, its host and whether to use TLS.
autoscalingReplica bounds and target utilization.

Preview the manifests​

See exactly what KubeOpera will deploy before it does, with the preview endpoint:

curl -X POST http://app-service:8112/api/v1/preview \
-H "Authorization: Bearer $TOKEN" -H "Content-Type: application/json" \
-d @payments-api.json

It returns multi-document YAML — the same manifests app-controller would commit. The dashboard's View manifests option on the Deploy wizard uses this endpoint.

Git and Flux​

For each app, app-controller creates two Flux resources in the tenant's vCluster:

apiVersion: source.toolkit.fluxcd.io/v1
kind: GitRepository
metadata:
name: payments-api-source
spec:
url: https://github.com/acme/fleet-repo
ref: { branch: main }
interval: 1m
secretRef: { name: fleet-git-credentials }
---
apiVersion: kustomize.toolkit.fluxcd.io/v1
kind: Kustomization
metadata:
name: payments-api-sync
spec:
sourceRef: { kind: GitRepository, name: payments-api-source }
path: tenants/alice/apps/payments-api
targetNamespace: payments
prune: true
interval: 1m

The Git credentials Secret contains either ssh-privatekey (SSH) or password (an HTTPS access token).

Configuration​

VariableDefaultDescription
PORT8112HTTP port.
AUTH_JWT_ACCESS_SECRET—Validates bearer tokens.
DEFAULT_NETWORK_POLICYdeny-ingressDefault network policy for new apps (deny-ingress or none).

The fleet repository, branch and Flux interval are configured on kubeopera-api.

Next steps​