Custom Apps
A custom app is an app your organization publishes to its own catalog. It installs the same way as the apps Edka ships, on any cluster of your organization and in any namespace.
The files of a custom app are its package. A package is a directory that holds
everything Edka needs to show the app in the catalog, ask for its settings,
and install it on a cluster: a template.yaml, a small
Helm chart, a README.md, and test answers.
memos/ template.yaml catalog entry, settings form, manifests chart/ the Helm chart the template installs README.md icon.svg optional test/answers.yamlThe format is documented in the package format and platform fields reference.
Prerequisites
Section titled “Prerequisites”- The Edka CLI, signed in with
edka login. - The Admin role in your organization, to publish. The Developer role is enough to validate a package and to install a published app.
- For the app itself: its container image, the port it listens on, where it keeps its data, and the environment variables it needs.
Package an app with an AI agent
Section titled “Package an app with an AI agent”A coding agent can write the package from the repository of the app.
-
Copy the
edka-appskill into the skills directory of your agent, such as~/.claude/skills/for Claude Code. -
Ask the agent to package the app, and name the repository:
Package https://github.com/usememos/memos as an Edka app and install iton the cluster staging. -
The agent reads the repository, writes the package, validates it until it is clean, publishes it, and installs it. It reports what the app runs and what you still have to provide, such as a database user or a hostname.
An agent without a local shell can do the same through the Edka MCP server,
with the tools custom_app_init, custom_app_validate,
custom_app_publish, app_install, and app_update. See
Claude for how to connect it.
Package an app with the CLI
Section titled “Package an app with the CLI”-
Write the starting files:
Terminal window edka apps init memos --name "Memos" --image ghcr.io/usememos/memos --tag 0.25.1 --port 5230 --with access,storage--withadds parts to the app:accessfor a hostname on the gateway,storagefor a data volume (with--data-path), andpostgresfor a PostgreSQL database on your cluster. The files pass validation as written. -
Edit
chart/templates/deployment.yamlfor what the app needs: environment variables, probes, command, and volumes. Intemplate.yaml, add a field underinputs_schemafor each setting an installer chooses, and pass it to the chart undervalues. Thestandardblock gives the app its namespace, image, resources, placement, storage, access, and PostgreSQL settings, so leave those out. -
Validate the package:
Terminal window edka apps validate ./memosEach finding names the file, the line, and a fix. An error (
✗) stops the publish. A warning (!) does not:✗ chart/Chart.yaml:2 chart.api-versionChart.yaml must set apiVersion: v2.! template.yaml:41 chart.unknown-valueThe template passes "persistence.sizee" to the chart, but chart/values.yaml does not declare it. Helm would ignore it.Fix: Declare persistence.sizee in values.yaml, or fix the name. -
Publish it to the catalog of your organization:
Terminal window edka apps publish ./memos -
Install it on a cluster:
Terminal window edka apps install memos --cluster staging --waitIn a terminal, the command asks for what the app needs, such as whether to expose it and on which hostname. It then shows the settings and asks to go ahead. To set a value without a question, pass
--set key=value.edka apps catalog memoslists the settings.When the installation finishes, the command prints the app with the status
installed.
To install from the console instead, open Apps on a cluster. The catalog lists your organization’s apps first, under Your organization.
The page of an installed custom app shows its workloads, logs, metrics, endpoints, and storage, like every other app.
Publish from the console
Section titled “Publish from the console”- Open Custom Apps in the sidebar and select New app.
- Select Pick a folder and choose the package directory, or Pick an
archive for a
.tgzof it. - The page lists the findings of the validation. When none is an error, select Publish.
The page of a custom app lists its instances and the clusters they run on, its versions, what each version runs and creates, and its README. Download returns the files of a version. Select the app’s name in the catalog to open this page.
Secrets
Section titled “Secrets”A field of type password, or one with secret: true, is a secret.
- A secret has no default in the package. Set
generate: trueon a field for a value Edka creates at install. - The template writes each secret as one key of a Secret named after the instance, and the chart reads that Secret. Edka keeps the stored value when a later edit leaves the field blank.
retrievable: truelets an authorized user read the value on the page of the app. Use it for a password a person signs in with.
Versions and updates
Section titled “Versions and updates”A published version never changes. To change a custom app, raise version in
template.yaml and publish again. Edka gives the chart the same version.
An installed app stays on the version it was installed with. When a newer version exists, the page of the app shows it:
- Select Review update. Edka lists what the update changes: images, kinds of objects, endpoints, storage, databases, secrets, and settings.
- Review the settings. A setting you changed keeps its value. The other settings take the defaults of the new version, which is how the app gets a new image tag.
- Apply the update.
From the CLI:
edka apps update memos --waitThe command lists the same changes and asks for confirmation before it applies the update.
Share with the community
Section titled “Share with the community”Every Edka organization can install an app from the community catalog. The catalog has rules of its own, checked before an app is listed. A community app:
- installs one chart, the one it ships, into one namespace
- runs only the images it lists, each pinned to a tag and its digest
- creates workloads, Services, ConfigMaps, Secrets, volume claims, and routes, and nothing at the level of the cluster
- runs its pods within the Kubernetes baseline Pod Security Standard
- names the upstream repository, its license, and the maintainers of the package
To offer a custom app:
-
List your GitHub handle under
maintainersintemplate.yaml. -
Check the package against the rules of the community catalog:
Terminal window edka apps validate ./memos --community -
Open the pull request:
Terminal window edka apps share ./memosThe command opens a pull request to edkadigital/apps from the GitHub account the GitHub CLI is signed in to. It asks for confirmation first.
-
The pull request runs two checks: a chart check and an install on a fresh cluster. An Edka maintainer reviews the package.
A merged app appears in the catalog with a following Edka release, under Community. Its card shows the maintainers, the license, and the platforms. Select its name to see the upstream repository, the package files at the reviewed commit, what the app runs and creates, and its README. The install page shows the same facts.
Withdrawn apps
Section titled “Withdrawn apps”Edka withdraws a community app that has an unfixed security problem or that nobody maintains. A withdrawn app leaves the catalog. Its installed instances keep running, and their page and a notification give the reason. A withdrawn app cannot be installed again or updated.
Troubleshooting
Section titled “Troubleshooting”The install waits a minute, then the page shows no workloads. A workload
of the chart does not carry the label app.kubernetes.io/instance. Add
app.kubernetes.io/instance: {{ .Release.Name }} under metadata.labels of
every Deployment, StatefulSet, and DaemonSet.
A changed secret does not reach the app. The pods read the Secret when
they start, and restart when the checksum/secrets pod annotation changes. A
package with standard passes it. In a template without standard, pass
{{{ secrets_checksum }}} to the chart, and put podAnnotations on the pod
template of the chart:
valuesContent: |- podAnnotations: checksum/secrets: "{{{ secrets_checksum }}}"The hostname has no certificate. A hostname under a domain of the cluster
uses the wildcard certificate of that domain. For any other hostname, turn on
Request a certificate in the access tab. A package has that setting when
standard lists access under with.
Publishing answers that the version is not newer. A version is published
once. Raise version in template.yaml.
The app is stuck after an install failed. Read why, fix the package, publish a new version, and update the app:
edka apps get memosedka apps logs memos