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.

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.

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

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

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.

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.