devstack · Guide › Databases (Postgres)
The db command group manages tenant-scoped databases, login roles and grants
on the shared Postgres engine. Every project gets its own role and database for
free at up; the db verbs are for the extra databases, users and grants a
project needs on top of that.
devstack db list # what this project owns
devstack db create reporting # → acme_reporting, owned by the project role
devstack db user create readonly --role read --db acme_reportingSnapshots, restore, reset and seed-from-store (
db snapshot,db restore,db reset,db pull) are covered separately in data-lifecycle.md — this page is provisioning only.
When you run devstack up, devstack provisions one Postgres role and one
database named after the project on the shared engine (unless you pass
--no-provision). The role owns the database, and both the role name and its
password default to the project name.
Project my-api therefore gets:
- role
my_api(passwordmy_api) - database
my_api
The project name comes from devstack.yaml, where name follows the dsname
rule and may contain hyphens (my-api). Postgres, however, treats a hyphen
as an operator — my-api is only a legal identifier if you double-quote it
everywhere, forever. To keep every generated DSN and every psql session
quote-free, devstack maps hyphens → underscores for Postgres identifiers.
So my-api → role/db my_api. (Buckets and messaging keep the hyphen and use a
<project>-<name> form instead — see object-storage.md.)
Connect from a container over the shared network:
postgres://my_api:my_api@shared-postgres:5432/my_api
...or from the host after devstack shared expose — see
shared-services.md.
devstack db create reporting # → database "acme_reporting" (project "acme")
devstack db create analytics --owner acme
devstack db create legacydb --no-prefix # → literal "legacydb"By default the physical name is <project>_<name> (hyphens in the project
name already normalized to underscores), so acme + reporting → acme_reporting.
This namespaces every project's databases on the one shared engine. The new
database is owned by the project role and creation is idempotent.
| Flag | Default | Description |
|---|---|---|
--project |
single/first project | which project owns it (default: the workspace's only project, else first alphabetically) |
--owner |
project role | owning role for the new database |
--no-prefix |
false | use the literal name (skip the <project>_ prefix) |
devstack db user create readonly --role read --db acme_reporting
devstack db user create svc --role write --db acme_reporting --generate
devstack db user create admin --role admin --password s3cret --db acme_reportingCreates a tenant login role (physical name <project>_<name> unless
--no-prefix), optionally granting it a privilege tier on a database in the same
call.
| Flag | Default | Description |
|---|---|---|
--project |
single/first project | owning project |
--db |
"" | database to grant on (its physical name, e.g. acme_reporting) |
--role |
read |
privilege tier: read | write | admin |
--password |
predictable | explicit password (default: predictable == the role name) |
--generate |
false | generate a random password via crypto/rand |
--no-prefix |
false | use the literal name (skip the <project>_ prefix) |
devstack db grant acme_readonly --on acme_reporting --as read
devstack db grant acme_svc --on acme_reporting --as writeGrants a privilege tier to an existing role on a database.
| Flag | Default | Description |
|---|---|---|
--project |
single/first project | owning project |
--on |
"" (required) | target database (physical name) |
--as |
read |
privilege tier: read | write | admin |
The
--ashere is a local grant tier — unrelated to the global--as <name>binary-branding flag.
devstack db list # databases and roles this project owns
devstack db list --kind db # databases only
devstack db list --kind role # roles onlyLock-free (read-only).
| Flag | Default | Description |
|---|---|---|
--project |
single/first project | scope to a project |
--kind |
"" (both) | db | role |
devstack db drop reporting # drops database "acme_reporting"
devstack db drop acme_readonly --kind role
devstack db drop legacydb --no-prefix --yesDestructive — confirmation is required. Under --json / non-interactively you
must pass --yes.
| Flag | Default | Description |
|---|---|---|
--project |
single/first project | owning project |
--kind |
db |
db | role |
--yes |
false | confirm (required for --json) |
--no-prefix |
false | treat <name> as literal |
devstack db gc --yesDrops databases and roles whose owning project is no longer in the workspace.
Destructive; --yes required for --json.
| Flag | Default | Description |
|---|---|---|
--yes |
false | confirm (required for --json) |
The shared Postgres engine must be running. The
dbverbs connect to a live engine (viapgxfrom the host) — they do not start it. If you see a connection error:
- Run
devstack upfirst. This starts the shared Postgres and provisions the per-project role/database.db createon a cold stack has nothing to connect to.- Check the engine is actually up:
devstack shared statusshould list a runningpostgresinstance with a live ref count. If it's stopped,up(orshared gcmay have stopped an idle one).- Ambiguous
--project. With more than one project in the workspace and no--project, the owner defaults to the first project alphabetically — which may not be the one you meant. Pass--project <name>explicitly so the<project>_prefix and ownership land on the right tenant.- Host-side provisioning needs the engine reachable from the host. devstack handles the ledger-allocated port for this during
up; if you disabled provisioning withup --no-provision, run a plaindevstack upfirst.
- Shared services & host access — reach Postgres from a GUI.
- Object storage — the parallel
s3group on MinIO. - The resource layer — declare databases/users in
devstack.yaml. - Snapshots, restore & reset —
db snapshot/restore/reset/pull. - Command reference — every command, terse.
◀ Shared services & host access · Guide index · Object storage (S3/MinIO) ▶