with one click
add-app
Scaffold a new app-template application for this home-ops repository
Install with Codex or Claude Copy this prompt, paste it into Codex, Claude, or another assistant, and let it review the skill page and install it for you.
Menu
Scaffold a new app-template application for this home-ops repository
Install with Codex or Claude Copy this prompt, paste it into Codex, Claude, or another assistant, and let it review the skill page and install it for you.
Based on SOC occupation classification
| name | add-app |
| description | Scaffold a new app-template application for this home-ops repository |
This skill scaffolds a new application for this repository's Flux layout.
kubernetes/apps/base/<namespace>/<app>/kubernetes/apps/<cluster>/<namespace>/kubernetes/apps/<cluster>/<namespace>/<app>.yamlkubernetes/components/namespaceOCIRepository in ocirepository.yaml; app-template apps point spec.chartRef.name at that per-app repo (named after the app)external-secrets with the onepassword ClusterSecretStoreUse the question tool to gather:
downloads, media, or self-hostedmain, utility, and/or testExternalSecretdependsOn entries for the cluster overlay manifestAlways ask for confirmation before writing files.
Before generating files:
Create:
kubernetes/apps/base/<namespace>/<app>/
At minimum, create:
kustomization.yamlhelmrelease.yamlocirepository.yamlOptionally create:
externalsecret.yamlprometheusrule.yaml, configmap.yaml, or pvc.yamlkubernetes/apps/base/<namespace>/<app>/kustomization.yaml---
# yaml-language-server: $schema=https://json.schemastore.org/kustomization
apiVersion: kustomize.config.k8s.io/v1beta1
kind: Kustomization
resources:
- ./helmrelease.yaml
- ./ocirepository.yaml
Add ./externalsecret.yaml only if secrets are needed. Add other resource files only when required. Keep the resource list alphabetized.
kubernetes/apps/base/<namespace>/<app>/helmrelease.yaml---
# yaml-language-server: $schema=https://raw.githubusercontent.com/bjw-s-labs/helm-charts/main/charts/other/app-template/schemas/helmrelease-helm-v2.schema.json
apiVersion: helm.toolkit.fluxcd.io/v2
kind: HelmRelease
metadata:
name: <app>
spec:
chartRef:
kind: OCIRepository
name: <app>
dependsOn: []
interval: 15m
values:
controllers:
<app>:
containers:
app:
image:
repository: <image-repository>
tag: <image-tag-or-digest>
probes:
liveness:
enabled: true
readiness:
enabled: true
resources:
requests:
cpu: 10m
securityContext:
allowPrivilegeEscalation: false
capabilities:
drop:
- ALL
readOnlyRootFilesystem: true
defaultPodOptions:
securityContext:
fsGroup: 1000
fsGroupChangePolicy: OnRootMismatch
runAsGroup: 1000
runAsNonRoot: true
runAsUser: 1000
service:
app:
ports:
http:
port: <port>
Adjust the template to match local patterns in the same namespace. Add route, persistence, env, envFrom, or extra manifests only when needed.
kubernetes/apps/base/<namespace>/<app>/ocirepository.yamlFor an app-template app, point at the shared chart with a per-app source named after the app:
---
# yaml-language-server: $schema=https://k8s-schemas.home-operations.com/source.toolkit.fluxcd.io/ocirepository_v1.json
apiVersion: source.toolkit.fluxcd.io/v1
kind: OCIRepository
metadata:
name: <app>
spec:
interval: 5m
layerSelector:
mediaType: application/vnd.cncf.helm.chart.content.v1.tar+gzip
operation: copy
ref:
tag: 5.0.1
url: oci://ghcr.io/bjw-s-labs/helm/app-template
For a non-app-template chart, set url and ref.tag to that chart's OCI source instead. spec.chartRef.name in the HelmRelease must match this metadata.name.
kubernetes/apps/base/<namespace>/<app>/externalsecret.yaml---
# yaml-language-server: $schema=https://k8s-schemas.home-operations.com/external-secrets.io/externalsecret_v1.json
apiVersion: external-secrets.io/v1
kind: ExternalSecret
metadata:
name: <app>
spec:
refreshInterval: 5m
secretStoreRef:
kind: ClusterSecretStore
name: onepassword
target:
name: <app>
dataFrom:
- extract:
key: <app>
If the app needs templated secret data, mirror patterns from similar existing apps instead of forcing a generic template.
For each selected cluster, create:
kubernetes/apps/<cluster>/<namespace>/<app>.yaml
Template:
---
# yaml-language-server: $schema=https://k8s-schemas.home-operations.com/kustomize.toolkit.fluxcd.io/kustomization_v1.json
apiVersion: kustomize.toolkit.fluxcd.io/v1
kind: Kustomization
metadata:
name: &app <app>
spec:
interval: 1h
path: ./kubernetes/apps/base/<namespace>/<app>
postBuild:
substitute:
APP: *app
CLUSTER: ${CLUSTER}
prune: true
sourceRef:
kind: GitRepository
name: flux-system
namespace: flux-system
wait: false
Only include components or dependsOn when the app needs them. Follow nearby overlay manifests in the same namespace for exact patterns.
For each selected cluster, update:
kubernetes/apps/<cluster>/<namespace>/kustomization.yaml
Add:
resources:
- ./<app>.yaml
Keep the resource list alphabetized.
Verify that:
kustomization.yaml references the new app.ocirepository.yaml (named after the app), it is listed in kustomization.yaml, and the HelmRelease's spec.chartRef.name matches it.ocirepository.yaml (named after the app), including app-template apps. There is no shared/injected app-template OCIRepository.OCIRepository inline in helmrelease.yaml; it lives in its own ocirepository.yaml.app-template, stop and ask the user before continuing.