Domains

Every deployed copy of the app is served on a hostname. A project on velastack.dev gets one for free under velastack.app, and can add its own domains on top.

velastack.app hostnames

A linked project that deploys while logged in — with vela login or VELA_API_KEY set — claims a subdomain on its first deploy. The label comes from the project’s slug, so a project called my-shop becomes my-shop.velastack.app; if that label is taken, a short random suffix is added. Every environment of the project is then named from it:

my-shop.velastack.app                  production
my-shop--staging.velastack.app         a named target
my-shop--feature-maps.velastack.app    the preview of feature/maps

The first -- separates the project from the environment, which is why a label may not contain two hyphens in a row. Names are flat rather than nested because one certificate covers everything one level under velastack.app.

Nothing has to be configured on the server. The deploy prints the URL, and a new name goes live within a minute:

Deployed my-shop 20260907T120000Z-8e41

  URL   https://my-shop.velastack.app
  Port  3001 (PocketBase 8091)

my-shop.velastack.app goes live within a minute.

A deploy without a link or a key still works exactly as before; it just serves on whatever --domain you gave it, and nothing is recorded on velastack.dev.

Choosing a label

The label is chosen for you, and can be changed on the project’s Domains page with Change subdomain. Every environment moves to the new name at once, and the old one stops answering within a minute. A label must be:

  • 2 to 40 characters of lowercase letters, digits and hyphens
  • Not starting or ending with a hyphen, and never containing --
  • Not a reserved word — infrastructure names like www, api and cdn, sign-in words like login and billing, mail and DNS names like smtp and ns1, and environment words like staging and prod
  • Not containing velastack or velabase anywhere

The field checks availability as you type.

How managed names are served

Requests to a velastack.app name arrive at the edge, which proxies them to your server over HTTPS. Certificates are issued at the edge, so there is nothing to obtain on the server. Two limits come with that path: uploads are capped at 100 MB, and a realtime connection that stays quiet reconnects after about 100 seconds. A domain of your own has neither limit, because it reaches the server directly.

On its first deploy from a linked project, the server is registered with velastack.dev and given an origin name:

srv-hqnirofzx4yvhcy.origin.velastack.app

That name always points at the server’s public address. It is what the edge proxies to, and what your own DNS records alias to. The registration lives in /etc/vela/origin.json, readable only by root, and is refreshed on every deploy; if the server’s address changes, the origin record follows it.

Your own domain

There are two ways to attach a domain, and they end up in the same place. The first is the one that has always worked — pass it on deploy, or commit it in velastack.config.ts:

$ vela deploy --domain www.example.com

Production hostnames given this way are recorded on the project’s Domains page automatically. The second is to add it there first. Add domain asks for the hostname and what it is for:

  • Production - The hostname production is served on
  • Previews, as a base - Every preview is also served at <branch>. under it, so preview.example.com gives feature-maps.preview.example.com

Once added, the page shows the DNS record to create. A subdomain is an alias of the server’s origin name, so it follows the server if its address ever changes; an apex domain cannot be an alias, so it gets the address instead:

www.example.com        CNAME  srv-hqnirofzx4yvhcy.origin.velastack.app
example.com            A      203.0.113.10
*.preview.example.com  CNAME  srv-hqnirofzx4yvhcy.origin.velastack.app

Check DNS resolves each hostname and confirms it reaches the server. A domain shows as DNS ok, Not reaching the server or DNS unchecked; there is no verification record to add.

A domain added on the dashboard reaches the server on the next deploy of that environment: the deploy picks it up, Caddy on the server obtains its certificate, and traffic to it goes straight to the server. A hostname can belong to one project at a time, and velastack.app names cannot be added this way — change the subdomain instead.

One hostname per environment

An environment is served on one hostname, because SvelteKit’s ORIGIN is a single host. When an environment has a domain of its own, that domain is primary and the managed name redirects to it, keeping the path and query string:

Deployed my-shop 20260907T120000Z-8e41

  URL   https://www.example.com
  Also  https://my-shop.velastack.app (redirects here)

Without a domain of its own, the managed name serves. The Domains page shows which is which: Serving, Redirects to a host, or Not deployed yet.

The Domains page

Each project has a Domains page on velastack.dev with a card per kind of environment:

  • Production - The managed name, its status, and every production domain with its DNS record
  • Previews - One row per deployed preview with its hostnames and branch, plus any preview bases
  • Other environments - Named targets such as staging
  • Pointing your own DNS here - The server’s origin name and address, ready to copy

The team’s Domains page lists every hostname across all of its projects, read-only. Domains are managed per project.