Connect apps to databases and services

Wiring dependencies

Apps rarely run alone — they talk to a database, a search engine, a cache. Flicker models those connections as dependency edges, and keeps the connection config wired correctly through every deploy and every branch, automatically.

Dependency edges

An edge says "this app depends on that resource, and the connection should land in this environment variable." There are two kinds of target:

  • Database edge — points at a Flicker database. The edge's env_var (usually DATABASE_URL) is set to the branch's own connection string. A pooled edge uses the branch's PgBouncer pooler endpoint instead of the direct one.
  • App edge — points at another app (a search engine, a broker). The edge carries one env_var, resolved from the depended-on app's connection map.

Which database an app auto-wires to

Creating an app in a project that owns a database wires the edge for you. When the project owns several databases, Flicker does not guess: it wires nothing, and the app starts with no database edge until you say which one. The project setting that answers the question is its primary database — the one a bare DATABASE_URL means.

A project with one database never has to think about this — there is nothing to choose between, and flicker wires that database. Add a second and the choice becomes real, and yours: flicker will not answer it for you, because "the one that happens to be older" is a guess that looks like a working setup. Record the answer from the CLI, or in Properties on the project page:

$ flicker project set-primary my-app-db --project my-app
# apps created in my-app now auto-wire DATABASE_URL to my-app-db

The database must already belong to the project. Changing the primary affects apps wired afterwards — it does not silently repoint an existing edge, which would move a running app onto different data. Repoint one deliberately with flicker app attach-db.

i

Why Flicker refuses to guess

Picking one of several databases for you is a coin toss that looks like a working setup: the app deploys, the connection resolves, and the data is somebody else's. Refusing is noisy but honest — and this setting is how you resolve it.

Auto-rewire: why connections never go stale

The connection an edge produces is Flicker-owned and wins over everything else. When composing an app's environment, Flicker layers:

  1. the parent branch's env (inherited),
  2. your user overrides, then
  3. auto-rewired dependency keys — applied last.

That last-wins ordering is deliberate. On a branch, the database edge points DATABASE_URL at this branch's forked database — not the parent's. Because auto-rewire is applied after your overrides, a stale DATABASE_URL copied from the parent can never shadow the branch's own database. The same holds for an app edge: the connection always targets the branch's resolved instance.

i
Auto-rewire only touches keys that are the target of a dependency edge. Your other env vars and overrides behave exactly as you set them — inheritance and overrides win as usual.

One-click services with templated keys

Flicker ships curated one-click service templates — Meilisearch, ClickHouse, Typesense, Qdrant, MinIO, and more. Deploy one and Flicker generates its credentials and exposes a canonical set of connection keys that a dependent app can attach to without you typing a URL or a secret.

For example, an app depending on a Meilisearch service receives:

MEILI_URL         = http://<service>.<namespace>.svc.cluster.local:7700
MEILI_MASTER_KEY  = <generated at create time>

Each template publishes its own keys:

Service Connection keys
Meilisearch MEILI_URL, MEILI_MASTER_KEY
ClickHouse CLICKHOUSE_URL, CLICKHOUSE_USER, CLICKHOUSE_PASSWORD
Typesense TYPESENSE_URL, TYPESENSE_API_KEY
Qdrant QDRANT_URL, QDRANT_API_KEY
MinIO S3_ENDPOINT, S3_ACCESS_KEY, S3_SECRET_KEY

The attach-dependency UI offers these keys even before the service has finished deploying, so you can wire the edge up front. Once both apps are running, the URL resolves to a private internal address — co-located traffic stays inside Flicker instead of routing out to the internet and back.

Shared vs. forked on a branch

When you branch a project, each dependency either forks with the branch or stays shared. A forked service gets its own instance per branch. A shared service is reused — so the branch namespaces itself inside it (an index prefix, a key prefix) to avoid colliding with other branches pointing at the same instance. Either way, the connection keys are rewired so the app talks to the right place.

The relationship map

The dashboard renders these edges as a live relationship map: each app and service is a node, each dependency an edge, annotated with the env_var it injects. It's the at-a-glance answer to "what is wired to what, and how" across a project — and it updates as you add or remove edges.