pier_

Add Postgres to an app

Declare a Postgres instance, link it into an app as DATABASE_URL, and verify from inside the app

Goal. api reads a main Postgres in the same environment through DATABASE_URL, with no credentials in pier.yaml.

Declare the instance

pier.yaml
environments:
  prod:
    postgres:
      - name: main
        targets:
          - name: primary
            version: "17"
            plan: pg-s
            bootstrap_default_database: app

pier apply provisions it; pier ls pg shows provisioning for about a minute, then running. From the CLI instead: pier add pg --name main --plan pg-s --default-db app.

pier ls pg
output
                                   
 NAME VERSION PLAN STATUS  UPDATED 
                                   
 main 17      pg-s running 1m ago  
                                   
pier vars set DATABASE_URL --from postgres.main.url --app api
output
→  Updated pier.yaml

  Changes:
    + create env_var "DATABASE_URL" in prod (from: postgres.main.url)

OK  Set DATABASE_URL on api in prod

--from stores a reference, not a value. The URL is resolved when the target starts, so a password rotation or a plan change does not change the configuration. Deploy the app so the running container receives it; the link is a variable, so no rebuild is needed:

pier deploy api
output
→  Comparing prod environment against platform state...

  Changes:
    ~ update app "api" in prod
      env_version: 2 → 3  (env var — next deploy)

  Deploy:
    app "api"    deploy (deployed inline)

  Env vars:
    app "api"    1 pending

OK  Applied 1 config change(s) to prod
→  Waiting for infrastructure provisioning...
OK  Infrastructure ready

OK  Summary: 1 deployed

Verify

From inside the app:

pier ssh api -- env | grep ^DATABASE_URL=
output
DATABASE_URL=postgres://app:…@4b5nx4s2r4a.pg.pier.run:5432/app?sslmode=require

From your laptop:

pier psql main -- -c 'select version()'
output
→  Connecting as cli_admin_e9187807 (role: pier_admin, expires 15:32 UTC)
                                                          version                                                           
----------------------------------------------------------------------------------------------------------------------------
 PostgreSQL 17.9 (Debian 17.9-1.pgdg11+1) on x86_64-pc-linux-gnu, compiled by gcc (Debian 10.2.1-6) 10.2.1 20210110, 64-bit
(1 row)

What changed

pier.yaml
 environments:
   prod:
     apps:
       - name: api
         build_context: ./api
+        env:
+          DATABASE_URL:
+            from: postgres.main.url
+    postgres:
+      - name: main
+        targets:
+          - name: primary
+            version: "17"
+            plan: pg-s
+            bootstrap_default_database: app

Variations

  • Individual fields instead of a URL: from: postgres.main.host, .port, .user, .password, .database.
  • A separate instance for staging: repeat the postgres entry under environments.staging; environments never share an instance.
  • Schema: Run database migrations.

See also

Postgres · pier pg · pier vars · Use Postgres from your laptop

On this page