Sealos Version
main @ 13d3350
How to reproduce the bug?
This was reproduced against a managed Sealos Cloud namespace by running the App Launchpad and App Store frontends locally from `main`. At the time of reporting, the official `main` HEAD is `13d3350e5b61`. The commits added after the original reproduction do not modify the affected App Launchpad or App Store lifecycle code, and the same missing ownerReference handling remains in the official HEAD. The local development authentication adapter only supplies the kubeconfig and does not change the application or resource lifecycle logic.
1. Install an application with a public port from Sealos App Store. The installed namespaced resources initially have an ownerReference to the App Store Instance.
2. Open the installed application in the locally running App Launchpad from `main`.
3. Delete the original port from the application edit page.
4. Add a new HTTPS port and save the application.
5. Inspect the newly created resources. App Launchpad creates a new ClusterIP Service and an Ingress, but both resources have an empty `metadata.ownerReferences` field.
6. Delete the application from the locally running App Store instance page (`/api/instance/deleteByName`).
7. Confirm that the Instance and its Deployment/StatefulSet are deleted.
8. List the application's Service and Ingress resources. The resources recreated in step 4 remain in the namespace.
The issue is easiest to reproduce by removing the original port and adding a new one. Merely changing a port while preserving the same Service name may use the patch path, which preserves the existing ownerReference and does not reproduce the problem.
Control test: another freshly installed App Store instance was deleted through the same `/api/instance/deleteByName` endpoint without first recreating its ports. Its Instance, workload and Service were all removed successfully. This isolates the failure to resources recreated by the App Launchpad edit flow rather than the general App Store deletion endpoint.
Sanitized evidence from the reproduced orphaned Service:
```yaml
apiVersion: v1
kind: Service
metadata:
name: <app-name>-<generated-suffix>
labels:
cloud.sealos.io/app-deploy-manager: <app-name>
ownerReferences: []
spec:
type: ClusterIP
selector:
app: <app-name>
ports:
- port: 4819
targetPort: 4819
protocol: TCP
```
A corresponding Ingress also remained. It used the orphaned Service as its backend, had `nginx.ingress.kubernetes.io/backend-protocol: HTTP` and TLS configured, and had no ownerReference. The application workload no longer existed.
What is the expected behavior?
Network resources recreated by App Launchpad should remain part of the application's ownership chain.
Newly created Services, Ingresses, Certificates and Issuers should receive an ownerReference to the application's Deployment or StatefulSet. Deleting the App Store Instance should then garbage-collect the workload and all of its dependent network resources.
The behavior should be consistent for all supported port modes:
- HTTPS, WSS and GRPC/GRPCS: ClusterIP Service and Ingress
- TCP and UDP: NodePort Service
- Internal-only ports: ClusterIP Service
What do you see instead?
On `main`, resources recreated by App Launchpad contain the `cloud.sealos.io/app-deploy-manager` label but do not contain an ownerReference.
The App Store deletion path detects that the Instance was installed with ownerReferences enabled and relies on Kubernetes garbage collection instead of explicitly deleting every Service and Ingress. Kubernetes deletes the Instance and owned workload resources, but the recreated unowned Service and Ingress remain active.
Observed state after `/api/instance/deleteByName` returned HTTP 200:
```text
Instance: NotFound
Deployment: NotFound
StatefulSet: NotFound
Recreated ClusterIP Service: Active, ownerReferences=[]
Recreated Ingress: Active, ownerReferences=[]
```
The orphaned resources can continue to expose an endpoint and leave resource or billing state behind after the user has been told that the application was deleted.
Source analysis indicates that the create path in `frontend/providers/applaunchpad/src/pages/api/updateApp.ts` passes newly created YAML resources directly to `applyYamlList` without injecting ownerReferences. Resources whose names do not change use the patch path and preserve their existing ownerReferences, which explains why only replacement/recreation operations trigger the leak.
`release-v5.1` already contains ownerReference injection introduced by #6623, but the corresponding lifecycle handling is absent from `main`. This report therefore concerns a missing forward-port/regression on `main`; the mixed-branch reproduction does not establish that the current `release-v5.1` deployment is still affected.
Operating environment
- Sealos version: official `main @ 13d3350e5b61`; application installed in managed Sealos Cloud
- Docker version: not involved in the local frontend reproduction
- Kubernetes version: managed by Sealos Cloud; exact server version not exposed in this test
- Operating system: macOS 26.5.2 (25F84), arm64
- Runtime environment: local Node.js v26.0.0 and pnpm 11.16.0, using a kubeconfig to access a managed Sealos Cloud namespace
- Cluster size: managed by Sealos Cloud; not visible to the namespace user
- Additional information: App Launchpad and App Store frontends were run locally. No kubeconfig, token, Authorization header, namespace identifier, cluster endpoint or other credential is included in this report.
Additional information
Relevant source locations on `main`:
- `frontend/providers/applaunchpad/src/pages/app/edit/components/NetworkSection.tsx`: protocol and external-access transitions clear `serviceName`, causing a newly named Service to be generated.
- `frontend/providers/applaunchpad/src/utils/deployYaml2Json.ts`: generated Service and Ingress manifests contain application labels but no ownerReferences.
- `frontend/providers/applaunchpad/src/utils/tools.ts`: a changed resource name produces separate `delete` and `create` actions, while same-name patches preserve the existing ownerReferences.
- `frontend/providers/applaunchpad/src/pages/api/updateApp.ts`: the `create` path applies the generated YAML directly.
- `frontend/providers/template/src/pages/api/instance/deleteByName.ts`: owner-reference-ready Instances use the Kubernetes garbage-collection deletion path.
Related implementation:
- #6623 added ownerReference handling to `release-v5.1`.
- `release-v5.1` currently reads the Deployment/StatefulSet UID and injects ownerReferences into newly created dependent resources before applying them.
Proposed resolution:
1. Forward-port the relevant ownerReference handling from `release-v5.1` to `main` without mixing in the unrelated unit-conversion changes from #6623.
2. Add regression tests covering recreated ClusterIP Service/Ingress resources and a recreated NodePort Service.
3. Verify that deleting the App Store Instance removes the complete ownership chain.
Maintainer question: Is the ownerReference implementation from `release-v5.1` expected to be forward-ported to `main`, or is there another planned branch synchronization path for this code?
Sealos Version
main @ 13d3350
How to reproduce the bug?
What is the expected behavior?
What do you see instead?
Operating environment
Additional information