Docs · Get started

Deploy your first app.

Three ways in, same result: your app builds on Canadian infrastructure and goes live at your-project.canner.app with HTTPS. Pick whichever fits how your project lives today.

You need an app that runs locally and a free Canner account — no card required. Canner detects your framework and builds it for you; the three paths below differ only in how your code reaches us.

What you can deploy

Canner detects the framework automatically — you rarely configure anything.

Static sites — plain HTML/CSS/JS — no package.json; just zip it and upload
.zip or .tar.gz archive of any of the above

Option 1 — Upload an archive

No git, no config. Create a project in New project (just a name), then on the project page upload a .zip or .tar.gz of your code under Source. Canner detects the framework, installs, builds, and deploys. Uploads are capped by plan (see Plans & limits) — and remember to include your lockfile (package-lock.json, pnpm-lock.yaml, …) if it’s a Node project.

Option 2 — Connect GitHub

Create a project in New project, then on the project page choose Connect GitHub under Source and install the Canner Deploy app on the repository. Every push to your production branch builds and deploys automatically; every pull request gets its own preview URL at branch--project.canner.app. Build failures are reported back to the PR as a commit status.

Option 3 — The CLI

Best for deploying from a terminal, a CI pipeline, or an AI coding tool’s integrated shell:

npm install -g @canner-ca/cli

canner login            # paste an API token from Dashboard → Identity → API keys
canner init             # creates the project + writes canner.json
canner deploy --follow  # uploads, builds, streams the log

--follow streams the build log and exits with the build’s status code, so it slots into CI as the last step. Full command reference on the CLI page.

Running a server? Two rules

Static sites and standard frameworks (Next.js, Astro, Vite) need no changes — Canner handles it. If your app runs its own server:

Listen on $PORT — read the port from the PORT environment variable.
Respond on / within 30 seconds of starting — that health check flips your deploy to live. Set a different path in project settings if your root isn't servable.
const port = process.env.PORT || 3000;
app.listen(port);

What happens next

Your build runs in an isolated sandbox with its own memory budget, then the app starts under its own Linux user and gets a TLS certificate automatically. On the free Starter plan an app sleeps after 3 hours without traffic and wakes on the next request; paid plans keep a set number of projects always on (2 on Live, more with the always-on add-on). From here: