zenith up uploads your local project and launches a temporary deployment for testing. It builds your app on Zenith and returns a public URL. It does not submit your app for publication or create a subscription.
Install the CLI and sign in first. Run the commands below from your app’s root directory.
Prepare the app
Dockerfile and zenith-compose.yml. The preview policy supports:
- Exactly one app service built with
build: .and the rootDockerfile. Do not also setimageon this service. - Dependencies using public container images.
- An HTTP app listening on
0.0.0.0, exposed through a primaryx-zenith.exposeentry withweb: trueand nolabel. The Dockerfile can omitEXPOSE. - Named volumes and dependencies declared with
depends_on.
privileged: true and inline secret content. Use .env.local for private test credentials.
Use x-zenith.env, x-zenith.storage, and x-zenith.configs in previews as well as published apps. Compose interpolation uses an empty host environment. Write $$ for a literal dollar sign.
Use platform mappings for generated values, SMTP, and OIDC credentials. Keep other test secrets in .env.local.
Use the Compose reference for the shared contract and preview constraints. Run zenith check before uploading. Zenith validates the project again after upload.
Supply test secrets
Put local test secrets in a gitignored.env.local at the project root. Do not put them in the Compose file, Dockerfile, or committed source.
.env.local
zenith check validates .env.local separately. zenith up sends the values separately from the source archive. The file must be valid UTF-8 and can contain up to 64 variables and 32 KiB of data. Reserved variable names are rejected. Other environment files are not loaded as test secrets.
Launch a temporary deployment
Lifetime and replacement
A preview lasts20 minutes from readiness by default. Use the teardown time printed by the CLI because the service can limit the lifetime. Queue and build time do not consume the ready lifetime. Treat preview data as temporary.
Each account has one live preview. A new preview of the same repository replaces the old one only after the new one is ready. To replace a preview from another repository, pass its session ID explicitly:
zenith down.
Upload limits
Uploads are limited to100 MiB compressed and 200 MiB expanded. File selection combines .gitignore with Dockerfile.dockerignore, or .dockerignore when no Dockerfile-specific ignore file exists. Required build and ignore files are retained.
Git metadata, node_modules, private-key patterns, and environment files are excluded. The templates .env.example, .env.sample, and .env.template remain eligible for upload.
Review your project before uploading. Ignore rules are not a substitute for checking that source files contain no secrets.
Inspect logs and failures
logs uses the last session for the current project and Zenith address. The default source is all. The default runtime tail is 200 lines. Pass a session ID to inspect a specific deployment:
0.0.0.0.
up stops waiting after 300 seconds without new build output by default. To allow a longer idle period:
Stop the deployment
down selects the last session for the current project. To stop a specific session:
zenith down with the same session ID.
Testing is complete when the app’s required flows work at the returned URL, you have checked the runtime logs, and you have requested cleanup or recorded the expiry time. Keep the tested commit and any local changes in your test notes.
Next: publish your app
Submit a public GitHub commit and marketplace listing for review.