From zero to a live app

Getting started

This walkthrough takes you from an empty directory to a deployed app on a real custom domain, with a Postgres database wired in automatically. The shape is always the same: create a project, add a database to it, create an app in it, deploy. About five minutes. You'll need the flicker CLI and an API token.

✦

A new organization has no hosting plan yet

Creating an organization does not grant a hosting membership, and there is no self-serve upgrade yet. Until one is granted you can use projects, secrets, tickets and memory, but not apps, databases or buckets. A platform admin grants one from Admin → Organizations (/admin/organizations): edit the organization and pick its tier.

Concepts: project, database, app, environment

Four nouns carry the whole model. Learn them once and the rest of the flow is obvious.

  • Project — the umbrella. A project owns your databases and apps (plus their environments and secrets) and ties them together. It is not a Postgres instance — it's the container that holds them. Creating a project takes a name and nothing else.
  • Database — a real, isolated Postgres instance you can branch in seconds (flicker database). A project can own one, several, or none.
  • App — a running container: your Phoenix app, a Meilisearch service, a worker. Apps live inside a project.
  • Environment — a branchable slice of a project. Each project has a main environment (its root, ≈ production); staging, preview/pr-42, and dev/<you> branch off it. Branching an environment forks the project's database(s) copy-on-write and its apps in sync, so a preview gets its own data and its own running copies.
✦

The wiring is automatic — never hand-set DATABASE_URL

When an app and a database live in the same project and you connect them, Flicker injects DATABASE_URL (and pooler URLs) into the app for you, pointed at the right database branch for the current environment. You should never set DATABASE_URL by hand — a hand-set value can shadow the one Flicker manages and point your app at the wrong data. Read more under Wiring dependencies.
i

Internal vs public connection strings

Each database branch has two connection strings to the same data. Your app uses the internal one — a private address reachable only from inside Flicker, no TLS hop — that's what Flicker injects. You (your laptop, flicker branch sql, external clients) use the public one (<id>.db.flickercloud.com, sslmode=require), which is what the dashboard and flicker branch list show. They are not interchangeable.
i

Databases, apps and buckets come with a membership

Flicker is not open for signup yet. Creating a database, an app or a bucket needs an organization membership that includes them. An organization without one can still use projects, secrets, tickets and memory. The web UI does not offer create actions an organization cannot use, and the CLI and API refuse them with quota_exceeded. No organization is exempt: the platform operator's own organization holds a membership too.

1. Install the CLI

The flicker CLI is a single static binary — no runtime, no dependencies. Drop it on your PATH and check it:

$ curl -fsSL https://flickercloud.com/install.sh | sh
$ flicker help
i
The installer detects your OS and architecture and installs to /usr/local/bin (override with FLICKER_INSTALL_DIR). Prefer a direct download? macOS Apple silicon / Intel, Linux x86-64 / arm64, or the Windows .exe.

2. Authenticate

Sign in with a browser. The CLI prints a one-time code, opens the verification page, and waits while you approve it — no key to copy, and the resulting login covers every organization you belong to. Over SSH or in a container it prints the URL and code for you to enter elsewhere instead of launching anything:

$ flicker auth login
# stored in ~/.config/flicker/config.toml (0600); `flicker org set <slug>` picks the org

For CI and anything else without a person at the keyboard, mint an organization API key under Settings → API Keys — the plaintext is shown once, so copy it now — and set FLICKER_TOKEN as an environment variable, or pass it to flicker auth login <key>. Those two credential kinds stay separate on purpose; see the CLI reference for the full resolution order.

i

There is a second kind of credential

A personal CLI token (flk_usr_, minted under Account Settings → CLI tokens) acts as you rather than as the organization, and exists only so that personal agent config has an identity. It reaches /whoami and the agent-config routes and nothing else — so it cannot deploy, read a secret, or touch a database. Everything on this page, and everything in CI, wants the org API key above.

3. Create a project

The project is the umbrella that will own your database and your app. Creating one takes a name and nothing else — resources are added to it in the next steps. Set it as the default for this directory so you don't repeat --project on every command:

$ flicker project create my-app
# name only — a project owns databases + apps, it is not a Postgres instance
$ flicker project use my-app
# writes project = "my-app" to ./flicker.toml

A fresh project starts with one main environment (its root, ≈ production). You branch from it later for staging, previews, and personal dev — see Environments & secrets.

4. Add a database

A database is an isolated Postgres instance with a main branch. Create one inside the project — that membership is what lets Flicker wire it to an app automatically:

$ flicker database create my-app --project my-app
# provisions real Postgres in the project, waits until active (~1–5s)
# (--project is implied once you ran `flicker project use`)

Already have a database elsewhere? Import it into main from a connection URL — Flicker runs pg_dump | pg_restore for you:

$ flicker database import postgresql://user:pw@host/db --database my-app

5. Create the app — DATABASE_URL auto-wires

Now create an app in the same project. Because the app and the database are both in my-app, Flicker connects them and injects DATABASE_URL into the app automatically — you do not write it anywhere.

$ flicker app create web --project my-app --image myorg/web:v2 --port 8080
# app joins the project; DATABASE_URL is injected from the project's database

myorg/web:v2 is a placeholder for a Docker image you've published to a registry — swap in your own ref. No published image? Most people don't when starting out: skip --image, scaffold the app (below), and build straight from your source in step 6 with flicker deploy --from-local, which builds your repo's Dockerfile for you. Pin a [build] table instead when you'd rather CI build it.

✦

You did not set DATABASE_URL — and you shouldn't

The app→database connection comes from the two living in one project. Flicker keeps that DATABASE_URL (the internal connection string) correct across every deploy and every environment branch. Setting it by hand is the most common way to point an app at the wrong data — don't.

Your app spec is described by an [app] table in flicker.toml — the deploy manifest. Scaffolding writes one you can commit and tune (point it at an image or a [build] table for source builds, and a domain):

$ flicker app scaffold web
flicker.toml
project = "my-app"
 
[app]
name   = "web"
port   = 8080
domain = "web.flicker.dev"     # routed with automatic HTTPS
 
# Give it code one of two ways:
image = "myorg/web:v2"          # (a) a registry image you publish, OR
# [build]                        # (b) build from your own source:
#   dockerfile = "Dockerfile"
 
# No DATABASE_URL here — Flicker injects it from the project's database.

Commit flicker.toml to your repo — the whole team and CI share one context, and the deploy is reviewable in a pull request.

6. Deploy and see it live

From your working directory, --from-local tars the current source, ships it to the host, and builds it there — including uncommitted changes:

flicker
$ flicker deploy --from-local
Build    Dockerfile · build secrets
Release  release_command · run migrations
Cutover  rolling update · new version up · old removed
Live     https://web.flicker.dev — running

Flicker builds the image, runs your release step (migrations, asset prep), then rolls out the new version, which only takes traffic once it's up — so a failed release leaves the current version serving. Your domain gets automatic Let's Encrypt HTTPS.

✦

That's the whole loop

Edit code, flicker deploy, done. Every deploy is recorded in history with its image and status — see Deploys.

7. Put it on your own domain

Every app gets a platform hostname. To serve it from a domain you own, register the domain, publish one ownership TXT record, attach it to the app after Flicker verifies it, and redeploy:

flicker
$ flicker domains add app.acme.com
# prints the TXT record to publish at _flicker-challenge.app.acme.com
# Flicker checks automatically; this command checks immediately
$ flicker domains verify app.acme.com
$ flicker domains attach app.acme.com --app web
$ flicker deploy

The same flow lives under Settings → Domains in the web UI. Pending ownership and mail DNS are rechecked automatically. Sending email from the domain is separate — see flicker mail domains.

Or in the browser: from a GitHub repo to a software factory

Everything above works from the CLI. The same first run also works entirely in the web UI, starting from a GitHub repository. Each step below says what you will see, including where it stops you.

  1. Have a membership first. A new organization has no hosting plan, so it cannot create apps or databases (see the note at the top of this page). A platform admin grants one from Admin → Organizations. Until then the web UI hides those create actions rather than offering ones that would fail.
  2. Connect GitHub (once per organization). An organization manager opens Services and chooses Connect GitHub. That only reads your GitHub identity; sign-in to Flicker is unchanged. Then Add GitHub organization opens GitHub's own chooser to grant the Flicker GitHub App access to an account and its repositories; each pass adds one account. The page lists each connected repository and whether it is public or private. If the server has no GitHub App configured, the card says so instead of offering the button.
  3. Create a project from a repo. New project asks for a name. When the organization has repositories not yet attached to a project, an Import from GitHub select lists them (and prefills an empty name with the repository's); with none, the page links to Services instead. The project is created even if the attach fails, and the error says so. A repository belongs to one project at a time; detach it under Project settings → Repository to move it. Attaching a repository also queues it for indexing, which is what Ask reads.
  4. Add a database, then an app from the project's repo. From the project page, add a database (it lives in the project, so DATABASE_URL is injected automatically), then New app. When the project has an attached repository the source defaults to Project repo: pick the repository and branch, optionally a Dockerfile and build context, and Flicker builds it. Private repositories build too, using a read-only GitHub token scoped to that one repository for the duration of the build. A project with no attached repository offers a prebuilt image or a raw Git URL instead.
  5. Fork staging. On the project page, New environment with kind Staging forks from main what its forking rule lists: the project's databases and apps. A staging fork takes secret keys only: set the values yourself before anything deploys. The database clone is the slow part and can take several minutes; the environment page shows each step, its state and the elapsed time, and the project page shows a chip for a fork in flight. A failed step is shown as failed, with a fixed explanation, rather than left looking like it is still running.
  6. Size the factory pool. Open the project's Factory page (or Provision Factory pool on the project page). Each slot is a reusable environment forked from staging, so staging has to exist first. Managers can add a slot, set the size, or remove slots; shrinking only removes free slots (never one a run is using, never staging or main), together with the apps and database branches forked into them. See Capacity pool for running work on them.
  7. Tearing down. Deleting an environment from its page removes what was forked into it, and confirms the impact first. Archive in Project settings only hides the project: its apps, databases, environments and secrets are kept and it can be restored. There is no one-click project delete in the web UI; delete the apps, databases and environments you no longer want first.

Where to next

Now that your app is live, wire up the rest of the stack:

  • Environments & secrets — move config out of flicker.toml into governed, versioned secrets that every deploy resolves.
  • Wiring dependencies — attach a search engine or cache in one click; Flicker injects the connection keys.
  • Volumes — give a service persistent storage that survives deploys.