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
/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
mainenvironment (its root, ≈ production);staging,preview/pr-42, anddev/<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
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.
Internal vs public connection strings
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.
Databases, apps and buckets come with a membership
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
/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.
There is a second kind of credential
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
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
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 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
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 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.
- 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.
- 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.
- 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.
-
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_URLis 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. -
Fork staging.
On the project page, New environment
with kind Staging
forks from
mainwhat 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. -
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, neverstagingormain), together with the apps and database branches forked into them. See Capacity pool for running work on them. - 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.tomlinto 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.