Skip to content

Web Applications

Deploy web applications from a Git repository. ZevCloud supports any language or framework that can run in a container.

ZevCloud uses Nixpacks to auto-detect and build your application:

FrameworkAuto-DetectedDefault Port
Next.js3000
React / Vue (Vite)Served as a static site (no port)
Express / Node.js3000
NestJS3000
FastAPI8000
Django / Flask8000
Go8080
Ruby on Rails3000
PHP / Laravel8000
Rust8080
Static HTML80
  1. Add Service → Web Application → Public Repository
  2. Paste the repository URL (e.g., https://github.com/user/repo)
  3. Select the branch
  4. Configure and deploy
  1. Add Service → Web Application → Import from GitHub
  2. If not connected, click “Connect GitHub” to install the ZevCloud GitHub App
  3. Select your repository from the list
  4. Select the branch
  5. Configure and deploy

ZevCloud auto-detects most settings, but you can customize:

SettingDescriptionExample
Build CommandCommand to build your appnpm run build
Install CommandCommand to install dependenciesnpm ci
Start CommandCommand to start your appnpm start
Output DirectoryFor static buildsdist, .next, build
Root DirectoryIf your app is in a subdirectorypackages/web
PortPort your app listens on3000

These can be set during creation or updated in Service Settings. Root Directory is a dropdown of the folders in your repository, so you pick the path rather than typing it — a mistyped one fails the build several minutes in, with an error about the build tool rather than the path.

If your repository has its own Dockerfile, ZevCloud uses it instead of building your app automatically. See Using a Dockerfile.

Client-rendered apps (Vite, React, Vue, plain HTML) don’t need a server process. Their build produces a folder of static files — the right way to serve them is as a static site.

When you create a service from a Vite project, ZevCloud detects this and pre-selects static serving. You can also change it any time in Service Settings → Build & Deploy:

SettingWhat it does
Static siteBuilds your app, then serves the output folder as files. No server process, no port to configure.
SPA (Single Page Application)Serves index.html for unmatched routes, so client-side routing (React Router, Vue Router) works on page refresh and direct links.
Publish DirectoryThe folder your build produces. Vite uses dist; Create React App uses build.

Common symptoms and their fix:

  • Deploy succeeds but the site is blank or 404s — the Publish Directory doesn’t match your build output. Check what folder your build command creates.
  • Pages 404 on refresh or direct links — enable the SPA toggle so unmatched routes fall back to index.html.
  • Deploy fails with a port or health check error on a Vite/React app — enable Static site. A client-rendered app has no server listening on a port, so port-based deploys can’t succeed.

Changes take effect on the next deploy — the dashboard offers a redeploy when you save.

Create one service per app. How you point each service at its app depends on whether the repository is a workspace.

If each app has its own package.json (or requirements.txt, go.mod) and they don’t depend on each other, set each service’s Root Directory to its folder:

repo/
frontend/ → service 1, Root Directory: frontend
backend/ → service 2, Root Directory: backend

Nothing else to configure. This is the common case.

Workspaces (pnpm, Yarn, npm, Turborepo, Nx)

Section titled “Workspaces (pnpm, Yarn, npm, Turborepo, Nx)”

If your repository has a turbo.json, a pnpm-workspace.yaml, an nx.json, or a workspaces field in the root package.json, the apps share dependencies through the repository root. Pointing the Root Directory at the app folder will fail the install, because dependencies declared as workspace:* can only be resolved from the root.

Leave the Root Directory at / and filter the build to one app instead:

# pnpm + Turborepo
pnpm install --frozen-lockfile
pnpm turbo run build --filter=web...
pnpm --filter web start
# npm workspaces
npm ci
npm run build --workspace=web
npm start --workspace=web
# Yarn workspaces
yarn install
yarn workspace web build
yarn workspace web start

The trailing ... in a Turborepo filter builds that app’s own workspace dependencies first. Without it, shared packages the app imports won’t be built.

When you select a repository, ZevCloud detects the workspace and offers these commands filled in with your package name — one click applies them.

For services with a Root Directory set, pushes only redeploy the services whose folder contains changed files. A commit that only touches frontend/ won’t rebuild your backend. Changes to shared files outside every service folder — a root package.json, a shared packages/ directory — redeploy all services from that repository, since they can affect any build.

Set environment variables in the Variables tab of your service:

DATABASE_URL=postgres://user:pass@host:5432/db
NODE_ENV=production
API_KEY=sk_live_...

Variables marked as secret are encrypted at rest and hidden in the UI.

When you push to the configured branch, ZevCloud automatically:

  1. Receives a GitHub webhook
  2. Clones the latest code
  3. Builds using Nixpacks
  4. Deploys with zero-downtime rollout
  5. Sends an email notification (success or failure)

Disable auto-deploy in Service Settings → Build & Deploy.

View real-time build logs in the Deployments tab. Each deployment shows:

  • Git commit message and SHA
  • Build duration
  • Success or failure status
  • Detailed build output

How Deploys Work explains each build phase, what’s cached between deploys, and how to read a failed build back to the step it failed in.

Each plan provides different resource limits:

PlanMemoryCPUBuild Timeout
Free512 MB1 core10 min
Starter2 GB1 core20 min
Pro4 GB2 cores30 min
Business8 GB4 cores60 min

To keep the platform clean for everyone, customer containers are not allowed to make outbound connections on a few specific ports. The host blocks them at the firewall, so any code in your app that tries to reach these ports will time out.

  • SMTP (25, 465, 587, 2525) — direct mail submission. Use a transactional email API (Resend, Mailgun, Postmark, SendGrid) over HTTPS instead. Their REST/HTTP endpoints are not blocked.
  • IRC (6667, 6697) — typical command-and-control channels.
  • Mining-pool stratum (3333, 4444, 5555, 7777, 14444) and Bitcoin RPC (8332, 8333).

Everything else (HTTPS to third-party APIs, your database, Redis, CDNs, webhooks) works normally. If you need to send email, switch to your provider’s HTTPS API.

If a deployment fails or causes issues, you can redeploy a previous version from the Deployments tab.