Development
May 21, 2026 · View on GitHub
This guide covers running kubeseal-webgui on your laptop: API in Python, UI in Node, plus an end-to-end loop on a local KinD cluster.
If you only want to install the released images on a real cluster, see installation.md instead.
Prerequisites
- Python 3.12 (the API targets 3.12 exactly).
- Poetry for managing the API's Python dependencies.
- Node.js — version
^20.19.0or>=22.12.0(matchesui/package.json). - Docker for building images.
- kubectl and Helm 3.8+.
- KinD (optional, for the end-to-end loop).
API (Python / FastAPI)
Setup
cd api
python3 -m venv .venv
source .venv/bin/activate
pip install poetry
poetry install
poetry install installs both runtime and development dependencies declared
in pyproject.toml (including pytest, ruff, mypy, and httpx for
tests).
Run locally
MOCK_ENABLED=true \
poetry run uvicorn kubeseal_webgui_api.app:app \
--port 5000 \
--log-config config/logging_config.yaml
MOCK_ENABLED=true replaces the Kubernetes client and kubeseal invocations
with in-memory mocks, so you can develop without a cluster. See
architecture.md for details.
The API is then available at http://localhost:5000. Swagger UI is at
http://localhost:5000/docs.
Tests
poetry run pytest
Markers defined in pyproject.toml:
cluster: tests that need a real Kubernetes cluster.container: tests that need to run inside the API container.
Skip both for a fast unit-test run:
poetry run pytest -m "not cluster and not container"
Linting and formatting
poetry run ruff check .
poetry run black --check .
poetry run isort --check .
poetry run mypy .
ruff, black, isort, and mypy are configured in pyproject.toml.
UI (Vue 3 / Vite)
Setup
cd ui
npm install
This project uses npm. There is no yarn.lock; do not use Yarn.
Run locally
npm run dev
Vite serves the SPA on http://localhost:8080 with hot reload. By default it
expects the API at http://localhost:5000 (set in
src/composables/useConfig.js or equivalent — check public/config.json for
the runtime value).
Build for production
npm run build
Outputs the production bundle to ui/dist/, which is what Dockerfile.ui
copies into the nginx image.
Linting and formatting
npm run lint # eslint, auto-fixes where possible
npm run format # prettier, writes to src/
Building the container images
docker build -f Dockerfile.api -t kubeseal-webgui-api:dev .
docker build -f Dockerfile.ui -t kubeseal-webgui-ui:dev .
Both builds are multi-stage:
Dockerfile.apidownloads thekubesealbinary in the first stage (version pinned via theKUBESEAL_VERSIONbuild arg) and installs the Python package in the second.Dockerfile.uirunsnpm run buildin the first stage and serves the output via nginx in the second.
To run the API container against a real cluster's kubeconfig:
docker run --rm -t \
-p 5000:5000 \
-e MOCK_ENABLED=true \
-e KUBESEAL_CERT=/tmp/cert.pem \
kubeseal-webgui-api:dev
End-to-end testing with KinD
A helper script bootstraps a complete local environment:
./kind-setup.sh
The script:
- Creates a KinD cluster named
chart-testing(dual-stack, ingress-ready). - Installs the Sealed Secrets controller into
kube-system. - Installs
ingress-nginx. - Builds the local API and UI images and loads them into the cluster.
- Renders the Helm chart with snapshot tags and applies it.
- Creates several test namespaces and
SealedSecretobjects, then exercises the API to verify the deployment.
After the script finishes, the UI is reachable at
http://$(hostname -f):7180.
Continuous integration
GitHub Actions workflows live under
.github/workflows/. The most relevant ones are:
main.yml: lint, tests, basic builds on every push and PR.frontend-tests.yml: UI test suite.kind.yaml: end-to-end test on a KinD cluster (useskind-setup.sh).codeql-analysis.yml: static analysis.container-security-scan.yml: image vulnerability scan.ghcr-build.yml: build and push container images to GHCR on release.helm-release.yml: package and push the Helm chart to GHCR on release.semantic-release.yml: derive the next version and create a GitHub Release from Conventional Commit messages (see CONTRIBUTING.md).