Skip to content

CLI & environment

cartapel is one binary with three subcommands:

bash
cartapel serve --db postgres://… --config ./admin      # run the panel
cartapel user add [email protected] --role support       # create/update a user (offline)
cartapel check --config ./admin --db postgres://…      # validate config — CI-ready

Every serve and check flag has a matching environment variable, so in a container you can drive them entirely from the environment.

cartapel serve

Runs the admin server.

bash
cartapel serve \
  --db postgres://user:pass@host:5432/mydb \
  --schema public \
  --config ./admin \
  --data ./cartapel-data \
  --listen 0.0.0.0:8686
# → panel on http://0.0.0.0:8686/admin  (the default mount path)
FlagEnv varDefaultDescription
--dbCARTAPEL_DBPostgres connection URL. Falls back to the URL of the primary source in config/cartapel.hcl (which supports env:NAME / ${NAME} interpolation).
--schemaCARTAPEL_SCHEMApublicSchema to introspect. Falls back to the primary source's schemas list.
--configCARTAPEL_CONFIGDirectory of HCL config files. Optional — without it, no tables are exposed.
--dataCARTAPEL_DATA./cartapel-dataDirectory for cartapel's own SQLite state (users, sessions, audit, config history).
--base-pathCARTAPEL_BASE_PATH/adminURL prefix the panel is served under. Injected into the SPA at runtime, so one build serves any prefix. A trailing slash is trimmed; pass '' (or /) to serve at the domain root.
--listenCARTAPEL_LISTEN127.0.0.1:8686Address and port to bind.
--secure-cookiesCARTAPEL_SECURE_COOKIEStrueSets the Secure attribute on session cookies. Keep on behind HTTPS; pass --secure-cookies=false for local plain-HTTP development.

The connection URL and schema resolve in this order: CLI flag → environment variable → config file.

When more than one schema is introspected, a table name that is unique across them keeps its bare key; a name that collides is keyed as schema.table.

cartapel user add

Create or update a panel user without the server running. Useful for provisioning and password resets.

bash
cartapel user add <email> [--role <role>] [--password <pw>] [--data <dir>]
Argument / flagEnv varDefaultDescription
<email>The user's email (lowercased on save). Positional, required.
--roleadminRole(s) to assign — comma-separate for several (support,billing; permissions union). Not validated offline: a name with no matching role in auth.hcl simply grants nothing.
--passwordCARTAPEL_PASSWORDgeneratedThe password. When omitted, a strong random password is generated and printed once.
--dataCARTAPEL_DATA./cartapel-dataThe state directory to write to.

Running user add for an existing email updates that user's role and/or password.

cartapel check

Validate a config directory without running the server. Exit 0 = valid; exit 1 with the errors printed — ready for CI.

bash
cartapel check --config ./admin                    # parse + validate the bundle
cartapel check --config ./admin --db postgres://…  # + verify every configured
                                                  #   table/column against the
                                                  #   live schema
FlagEnv varDefaultDescription
--configCARTAPEL_CONFIGThe config directory to validate. Required.
--dbCARTAPEL_DBWhen given, every configured table is verified to exist, and list/search/sort/readonly columns are verified to be real columns.
--schemaCARTAPEL_SCHEMAprimary source's schemasNarrows the live check to one schema.

Run it in CI next to your migrations: config drift against a schema change becomes a red build instead of a silently broken panel.

Environment variables

Beyond the per-flag variables above, cartapel reads:

VariableRequiredPurpose
CARTAPEL_SECRET_KEYYesThe app signing root for session cookies. cartapel refuses to start if this is unset and [cartapel].secret_key is also unset. See Security.
CARTAPEL_ADMIN_EMAILNoEmail for the bootstrap admin created on first run. Defaults to admin@localhost.
CARTAPEL_ADMIN_PASSWORDNoPassword for the bootstrap admin. When unset, a random one is generated and logged.
CARTAPEL_ADMIN_ROLENoRole(s) for the bootstrap user (comma-separate for several). Defaults to admin; a public demo can bootstrap a restricted role (e.g. a read-mostly demo role from auth.hcl) instead.
CARTAPEL_WEBHOOK_SECRETNoHMAC secret for signing outbound webhook actions (X-Cartapel-Signature).
CARTAPEL_DB_TX_POOLNoSet to 1 to force transaction-pooler mode (disables sqlx's prepared-statement cache). Auto-detected for Supabase's port 6543 pooler.
RUST_LOGNoStandard tracing filter. Defaults to cartapel=info,tower_http=warn.

Config values can read the environment

Anywhere config accepts a value, env:NAME or ${NAME} is replaced with the environment variable NAME. This is how you keep secrets — the DB URL, the secret key — out of committed HCL. See Configuration overview.

Health check

serve exposes an unauthenticated health endpoint for load balancers at {base-path}/api/health, returning {"ok": true}.

Released under the MIT License.