For people
Doing it by hand
Saasie is designed so a code agent can take someone from a sentence to a running app without them opening a terminal. This page is the other way round: what those steps actually are, in order, for someone who would rather do it themselves.
There is no hidden path here and no reduced version. The CLI an agent drives is this CLI, and the commands below are the same ones it runs. It takes about ten minutes.
1. Install the CLI
One self-contained executable — the runtime is compiled in, so there is nothing to install alongside it and no package manager involved.
curl -fsSL https://saasie.io/install.sh | sh
If piping a script into a shell is not something you do, that is a reasonable position: every build and its checksum is published, and the installer is plain text you can read first.
2. Log in
An account is an email address. There is no password, no browser step, and no card before anything runs. A code arrives in your inbox; you hand it back.
saasie otp you@example.com saasie token 123456
The token is stored on this machine from then on.
saasie whoami says who you are;
saasie logout revokes it.
3. Write the blueprint
One file, saasie.yaml, at the root of your repository.
It declares what runs — and nothing about where, because every
deployment of it gets its own hostnames and its own databases with
their own generated passwords.
version: 1
databases:
db:
engine: postgres
services:
web:
dockerfile: Dockerfile
context: .
port: 3000
health:
path: /health
env:
PORT: { service: web, property: port }
DATABASE_URL: { database: db, property: url }
Two things there catch nearly everyone. PORT is not
injected — nothing is — so a framework that reads it and falls back
to a default will listen somewhere else and never become ready. And
your process must bind 0.0.0.0, not
127.0.0.1, or it is unreachable from outside its own
container and reads as dead.
Check it before you push:
saasie validate. The full schema, with every reference
type, is on the blueprint page.
4. Claim a name
The name is global and permanent — it becomes the repository, the hostname and the URL.
saasie new acme
5. Push
A push to main builds every service in the blueprint
and rolls it out. Any other branch is accepted and starts nothing.
git remote add saasie "$(saasie app acme git get-url)" git push saasie main
So that HTTPS pushes authenticate themselves without putting a live
token in .git/config, register the credential helper
once:
git config --global credential.helper '!saasie git-credential'
6. Check it from outside
This is the step worth arguing about, so it gets its own section.
A green build does not mean your app runs. The build log ends when the image is pushed — your server has not executed at that point. And because a rollout only replaces the old version once the new one answers its health path, a new version that cannot start leaves the old one serving happily. Nothing 500s, nothing restarts, and the app simply does not change.
So read the running code, not the log. The cheapest reliable check is to make the app state its own version — an endpoint returning the commit, or any value you changed in the same commit — and fetch it over the public URL.
saasie app acme build list # did it build saasie app acme status # is it running, and if not why saasie app acme logs # what it has said lately curl -s https://acme.saasie.app/version
status reads the cluster rather than our records, which
is the point: it names a failing health path, and prints
Kubernetes' own reason when a container is up and not answering.
What happens next is where it gets sharp
Everything above is the easy half. The two that bite are both about the second deploy, not the first:
| Migrations | Your old and new code run against the same database simultaneously during every rollout. Add columns, do not rename them. And if you serialise with a Postgres advisory lock through a connection pool, you can deadlock every future deploy in a way that never throws. |
| Deploying |
Adding a second service moves the first one's URL, because a
multi-service Saasie has no bare
<name>.saasie.app at all.
|
And if you would rather not
Entirely fair. Hand this to a code agent — point it at saasie.io/agent.txt — and it will do all of the above. The only step it cannot do for you is step 2, because the login code goes to your inbox and not its.