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.
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.
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
Mint an API token in the web UI under Settings → API Keys — the plaintext is shown once, so copy it now. Then log in. The CLI asks the server which organization the key belongs to, so you never type an org slug:
$ flicker auth login flk_live_xxx # org resolved from the key; stored in ~/.config/flicker/config.toml (0600)
In CI, set FLICKER_TOKEN
as an environment variable instead —
it takes priority over the stored file. See
the CLI reference
for the full resolution order.
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.
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.