Deployments

Clicking Deploy kicks off a queued pipeline: analyze the repository, collect environment variables, deploy the backend to your Render workspace, wire its live URL into the frontend, deploy the frontend to your Vercel account. This page explains each stage in detail.

Stage 1: Repository analysis#

Analysis is deterministic first. deplo.ai fetches your repository's full recursive git tree once, then runs a layered, evidence-scored pipeline over it — it is tree-driven, not filename-guessing, so monorepos, nested apps, and Python/Go repos are all seen correctly:

  • Structure analysis classifies the repo as single, frontend-backend (e.g. client/ + server/ folders), or monorepo — Turborepo, Nx, and pnpm/npm/yarn workspaces are all recognized.
  • Framework detection scores each candidate against weighted signatures: dependencies, config files, content patterns, and package scripts, each with its own weight. No single indicator is ever trusted on its own, and a meta-framework (Next.js) outranks its base library (React) via priority.
  • Language and runtime detection identifies JavaScript/TypeScript, Python, Go, Java, or static HTML, plus the language version and package manager.
  • Environment variable scanning reads your source for the variables the code actually uses — see Environment Variables.

The result is shown before anything deploys: the detected frontend and backend, where each lives in the repo, and the commands that will run.

Confidence and the AI fallback#

The signature scores are normalised to a 0–1 confidence value per component. High confidence means several independent signals agree — a next.config.ts, a next dependency, and a next build script all pointing the same way.

AI fallback
When deterministic confidence falls below 0.5, the pipeline escalates to a bounded AI reasoning step (Groq). It receives the folder tree (≤200 paths), key config files and small top-level source files, and the deterministic evidence — never the whole repository. Its answer is constrained to a strict JSON schema with framework enums, and its corrections are merged only when they are more confident than the deterministic result. AI is capped at two calls per deployment — this one, plus one failure diagnosis if the deployment fails — and if AI is unavailable the deterministic result is used as-is, never an error.

Stage 2: Build command resolution#

Commands are read from your repository's real files — never guessed:

RuntimeHow commands are resolved
Node.jsBuild and start come from the backend's own package.json scripts, read at deploy time. The package manager is detected from lockfiles (bun.lockb, pnpm-lock.yaml, yarn.lock, else npm). A build script becomes install && run build; a start script is used verbatim. If no start script exists, the entry point is located from main and the actual file tree.
PythonInstall from requirements.txt / pyproject. The app module is detected from source: uvicorn module:var from an X = FastAPI() assignment, gunicorn --bind 0.0.0.0:$PORT module:var for Flask, and pkg.wsgi:application for Django. PYTHON_VERSION is set when a fully-qualified version is detected.
GoBuild target from the repo layout: a root main.go becomes go build -o app .; the cmd/<name>/main.go convention builds that package. Start is ./app; the Go version in go.mod is honoured by Render.

Stage 3: Environment variables#

If any required variable has no value, the deployment parks in WAITING_FOR_ENV and you get an email listing exactly which keys are missing. Provide values in the dashboard (or pre-fill them on the Configure step to skip this state entirely) and the pipeline resumes. Environment Variables covers detection, scoping, and the auto-injected wiring keys in depth.

Stage 4: Deploy order — backend first#

The backend always deploys first, because the frontend build needs its live URL. There is one clever exception to the ordering: the frontend's Vercel domain is predictable (deplo-<repo>-web.vercel.app), so the backend can be configured with FRONTEND_URL for CORS before the frontend exists — no chicken-and-egg problem.

  • A Render web service (deplo-<repo>-api, free plan) is created in your Render workspace using your own API key, with the resolved build/start commands, the correct rootDir for monorepos, and backend-scoped env vars.
  • deplo.ai waits for the Render build; when the service is live, the deployment moves to BACKEND_READY and the backend URL is recorded.
  • Frontend files are fetched from GitHub and deployed to a project in your Vercel account. The live backend URL is injected into every frontend key that references it (NEXT_PUBLIC_API_URL, VITE_API_URL, and friends).
  • After the frontend is live, deplo.ai verifies the domain Vercel actually assigned. If it differs from the predicted one, the backend's FRONTEND_URL is corrected and a backend redeploy is triggered automatically so CORS stays right.
Note
Vercel credentials are only required when a frontend exists — backend-only repositories deploy with Render alone.

Live logs#

Every stage appends to a live log you can watch on the deployment page, fetch via GET /api/v1/deployments/:id, or stream with deplo logs from the CLI:

deployment log
Analyzing repository structure…
Stack detected: frontend=Next.js, backend=Express.js (client/) (server/)
Deploying backend to Render…
Using package.json scripts — build: "npm install && npm run build", start: "npm start"
Reusing existing Render service (srv-abc123) — updating configuration and redeploying…
Backend live at https://deplo-my-app-api.onrender.com
Wiring frontend → backend: NEXT_PUBLIC_API_URL = https://deplo-my-app-api.onrender.com
Deploying frontend to Vercel (214 files)…
Frontend live at https://deplo-my-app-web.vercel.app
Deployment completed successfully.

Status meanings#

A deployment moves through PENDINGANALYZING WAITING_FOR_ENV (only if values are missing) → DEPLOYING_BACKEND BACKEND_READYDEPLOYING_FRONTENDCOMPLETED, with FAILED and CANCELLED as the other terminal states. Every state is defined in Deployment Lifecycle.

Redeploys#

Redeploys are idempotent. Deploying the same repository again reuses the existing Render service (found by stored ID, or by name in your workspace) and the existing Vercel project — services are never duplicated. On reuse, the service configuration is repaired if an earlier attempt left it wrong (e.g. a missing rootDir), and env vars are re-applied as the full intended set, so values you provided earlier carry forward.

After the first successful deployment, deplo.ai also registers a GitHub push webhook (best-effort — a registration failure never fails the deploy). From then on, pushes to the deployed branch trigger an automatic redeploy that reuses the previous configuration and skips straight to the deploy phase.

Rollbacks Planned#

Rollbacks are not implemented yet. Today the way back is forward: revert the commit and redeploy, or use your provider dashboards directly — both Vercel and Render keep their own deployment history, and since the services live in your accounts you have full access to their native rollback tools.

Cancelling a deployment#

Cancel from the deployment page or with DELETE /api/v1/deployments/:id. Cancellation is only valid while the deployment is active — a COMPLETED, FAILED, or already CANCELLED deployment returns a conflict error. The deployment is marked CANCELLED and the pipeline stops progressing it; note that a build already handed to Vercel or Render may still finish on the provider's side.

If it fails#

A failure sets the deployment to FAILED, runs the one bounded AI failure diagnosis (likely cause, suggested corrected commands) which is appended to the log, and emails you the diagnosis together with a copy-paste fix prompt for Cursor, Claude Code, or Copilot. See Troubleshooting for the common failure modes and their fixes.