Push Workflow
The CLI-based path from code to marketplace listing.
Prefer the GitHub App? The recommended way to ship on Kyper is to
connect the GitHub App
and push a semver tag — no CLI needed for releases.
This page covers the manual kyper push path, which is fully supported and useful for initial setup and local testing.
Overview
kyper push is a single command that handles the entire deployment pipeline: validating your config, archiving your source, syncing metadata, uploading your version, and streaming the build log.
Before you push
Three commands let you gain confidence at increasing levels of fidelity before submitting for review.
kyper check
Validates kyper.yml and confirms the Dockerfile exists. No Docker required — instant feedback.
kyper build
Runs docker build locally using the same Dockerfile as the remote pipeline. Catches build failures in seconds instead of minutes. Add --scan to also run the Trivy security gate.
kyper test
Deploys your app on Kyper's real K8s infrastructure with full dep support. Gives you a live HTTPS URL for end-to-end verification. Auto-destroys after 1 hour. If you're using the GitHub App, push a pre-release tag instead (v1.0.0-rc.1) — same result, no CLI needed.
# Quick sanity check (no Docker needed) kyper check # Full local build test kyper build # Build + security scan (same gate as remote pipeline) kyper build --scan # End-to-end test on real infrastructure kyper test
Build pipeline
-
1
Validate — the CLI runs a full validation of your
kyper.ymllocally. If there are errors, push stops immediately. Warnings are shown but don't block the push. -
2
Archive — your source code is zipped, respecting
.kyperignoreand.dockerignorepatterns. Default excludes:.git/,*.log,tmp/,node_modules/. -
3
Sync metadata — the CLI creates your app on Kyper (first push) or updates its metadata (subsequent pushes). Title, description, category, pricing, and tech stack are synced.
-
4
Upload — the archive and raw
kyper.ymlare uploaded as a new version via multipart form to the API. -
5
Docker build — Kyper extracts your source and builds the Docker image from your Dockerfile.
-
6
Port validation — the built image is inspected for
EXPOSE 3000. If missing, a prominent warning is shown in the build log (the build still succeeds). Kyper routes all traffic to port 3000, so your web process must listen on$PORT. -
7
Security scan — Trivy scans the image for known vulnerabilities. Results are stored and displayed in your developer portal.
-
8
Submit for review — after a successful build, the CLI prints a link to your submission page. Visit it to provide demo credentials (for apps with required env vars) and any review notes — test accounts, known limitations, or setup instructions. Click "Submit for review" to send your version to the review queue. The Kyper team is notified only after you submit. Credentials are stored encrypted and never shared.
-
9
Review — the Kyper team reviews your submission. Reviewers may deploy a live test instance using your demo credentials to verify everything works. You'll receive an email when it's approved or if changes are needed.
Version status lifecycle
Tailing build logs
After uploading, the CLI automatically streams your build log in real-time. If you disconnect, you can resume with:
kyper push logs
The log uses cursor-based polling (every 2 seconds) with a 30-minute timeout. In --json mode, a spinner replaces the log output.
Debugging build failures
Reproduce the failure locally with kyper build — it runs the same
docker build command as the remote pipeline, so you can iterate
on fixes in seconds instead of waiting for a remote build.
# Reproduce locally kyper build
Common causes of build failures:
- Dockerfile syntax errors or missing dependencies
- Missing files referenced in COPY/ADD instructions (check your
.kyperignore) - Build commands that require network access (e.g.,
npm installshould run during the build, not after) - Out-of-memory during build (contact support if this happens)
To retry after a failure:
# Retry the same build without changes kyper push retry # Fix your code and push again (same version number is fine) kyper push
The security gate
Kyper scans every image with Trivy for HIGH and CRITICAL vulnerabilities in your app's dependencies (gems, npm packages, pip packages, go modules, etc.). Only CRITICAL library vulnerabilities with an available fix will block your build.
Gemfile, package.json, etc. to pick up the patch.
You can scan locally before pushing with kyper build --scan to see exactly what the build gate will flag:
# Build + security scan — same gate logic as the remote pipeline kyper build --scan # Show only CRITICAL blocking vulnerabilities (hides HIGH advisory) kyper build --scan --fix
Ignoring a CRITICAL CVE
In rare cases, a CRITICAL fixable CVE may not apply to your app (e.g., a library you ship but never call). You can declare it as accepted risk in kyper.yml:
security:
ignore_cves:
- id: "CVE-2025-68121"
reason: "Affects OpenSSL DTLS which this app does not use"
Guidelines
- Each
idmust match the formatCVE-YYYY-NNNNN - Each
reasonmust be at least 10 characters — explain why the CVE is acceptable - Maximum 25 ignored CVEs per app
ignore_cvesis for CRITICAL fixable library CVEs — HIGH vulns, unfixed CVEs, and OS-level base image packages are automatically advisory and never need to be ignored- Reviewers may reject submissions with poorly justified or excessive ignores
- Remove entries once they're no longer needed — stale ignores look bad in review
Test on Kyper's infrastructure
Once your Dockerfile builds cleanly, kyper test lets you deploy your app
to Kyper's real K8s infrastructure before submitting for review. Your declared deps (Postgres, Redis, etc.) are
provisioned alongside your app, and you get a live HTTPS URL to poke around in.
kyper test
The deployment auto-destroys after 1 hour. Tear it down early with:
kyper test destroy
Check status at any time (useful if you disconnected mid-provision):
kyper test status
Limits
- 1 active test deploy at a time (a new
kyper testautomatically destroys the previous one for the same app) - 3 test builds per day across all your apps
See the Best Practices guide
for a full pre-submission checklist and common gotchas caught by kyper test.
Using the GitHub integration?
You can set test env vars directly on the repo link instead of passing them via the CLI — they're encrypted, scoped to test deploys only, and visible in your GitHub Check Run if anything goes wrong. See GitHub integration → Env vars for test deploys.
Submission details
After a successful build, the CLI will print a submission URL. Visit it to provide:
- Demo environment variables — if your app declares required env vars in
kyper.yml, provide demo values so the reviewer can test your app. These are stored encrypted and never shared. - Review notes — test accounts, demo data instructions, known limitations, or anything else the reviewer should know.
When you click Submit for review, your version moves from built to in_review and the Kyper team is notified. You can also access the submission form from the "Submit for review" link on your version in the developer portal. After submission, you can still update your details via the "Edit submission" link.
Migrations & the release hook
Most webapps need their database schema in place before the web process can start. Kyper provides
hooks.release for this: a one-shot command that runs
after your declared deps (postgres, redis, etc.) are ready, and before
your app pods are created. It's the standard "release migration" pattern, modelled on Helm's pre-install hooks.
The release hook runs as a dedicated Kubernetes Job using the same image, the same env vars, and the same registry credentials as your web process. If it fails, the deploy is marked failed with the Job's pod logs attached, and your app pods never start. On a version update the release hook runs against the new image before the rolling update begins, so a failing release leaves the previous version untouched.
Write temporary files through your framework's standard temp-file APIs or
TMPDIR. App pods and release hooks run with a
read-only image filesystem, so paths baked into your image, such as
/rails, are not safe places to write runtime data.
Put durable uploads, SQLite databases, and other persistent files in storage paths declared in
kyper.yml.
# kyper.yml — Rails hooks: release: "bundle exec rails db:prepare" # kyper.yml — Prisma / Node hooks: release: "prisma migrate deploy" # kyper.yml — Drizzle hooks: release: "npm run db:migrate" # kyper.yml — Goose / Atlas / etc. hooks: release: "/usr/local/bin/migrate"
Don't put migrations in hooks.on_deploy.
on_deploy runs after your pods are healthy by exec'ing into a running web pod.
If your app crashes on first boot waiting for its schema, your web pod will never become healthy and the
hook can never fire. hooks.release exists specifically for this case.
Don't inline secrets in your hook command.
The hook command string is logged verbatim into the deployment's provision log,
which the consumer can view in their dashboard. If you do
release: API_KEY=xxx prisma migrate deploy,
the key lands in the visible log. Put secrets in env:
instead — they're encrypted at rest and injected as env vars into the release Job's
container, never logged.
Why this matters for kyper test:
every kyper test deploy starts with a brand-new, empty database — even if your app has
deployed successfully before as a subscription. Subscription deploys keep their database between version updates;
test deploys do not. So an app whose web process needs schema-at-boot will reliably fail under
kyper test until hooks.release is set,
even after months of healthy production deploys.
Review process
Every version goes through manual review. Reviewers check:
- Dockerfile builds correctly and follows best practices
- No critical vulnerabilities flagged by Trivy
- App functions as described in the listing (reviewers may spin up a live test instance)
- No prohibited content (malware, illegal activity, license violations)
- Environment variables are properly documented
You'll receive an email notification when your version is approved or rejected. Rejected versions include reviewer notes explaining what needs to change.
Need to fix something while in review? Just push again with the same version number — Kyper automatically replaces the in-review submission with your new build and restarts the review queue. No need to withdraw first.
# Fix an issue flagged in review — no withdraw needed # edit your code... kyper push # same version number is fine