Concepts
Workspace, project, environment, resource, target — what each one is and how they nest
Pier organises everything in this tree. Every command and every line of pier.yaml is an
operation on one of these levels.
Workspace acme-inc billing and access
└── Project acme one system, one pier.yaml
├── Environment prod a complete, isolated set of resources
│ ├── App api ├── target primary https://k7f2m9.app.pier.run
│ │ └── target canary https://q2d8xa.app.pier.run
│ ├── Site www └── target primary https://m3p1zr.site.pier.run
│ ├── Postgres main one instance
│ ├── Bucket uploads
│ └── Volume data
└── Environment staging its own api, www, main — nothing shared with prod| Level | Is | Boundary of | You pick it with |
|---|---|---|---|
| Workspace | the account: members, roles, subscription, overage cap | billing and access | -w, pier workspaces use |
| Project | one system — an API, its site, its database; one pier.yaml | configuration and history | the pier.yaml in the directory, -p, pier projects use |
| Environment | a complete declaration of resources and variables — prod, staging | isolation: network, data, variables | pier use, -e |
| Resource | an app, site, Postgres, bucket or volume declared in an environment | the thing you name in pier.yaml | its name: api, main |
| Target | a running instance of an app or site: its own hostname, plan, deploy history, logs | what runs | a ref: api, api/canary |
Workspace
A workspace holds billing, members and roles, and nothing else: one subscription, one
overage cap, one set of members (owner, admin, developer, viewer). Most accounts have one
workspace, so its name is rarely typed. pier whoami shows which workspace a session is in.
Project
A project is one system and one pier.yaml. The file links a directory to the project:
pier finds the project by walking up from the current directory to the nearest
pier.yaml and reading its project: key, so commands run inside the repository need no
project flag. A project contains environments and nothing else.
Environment
The environment is the unit of work. Every command that reads or changes something
does so in the current environment. pier use staging sets it; -e staging overrides it
for one command. pier ls lists what the environment contains; pier deploy rolls what
changed in it.
An environment is a complete, independent declaration. staging does not inherit
from prod: each environments.<name> block in pier.yaml lists every app, site,
Postgres, bucket, volume and variable it has. This repeats configuration between
environments, and in return the block is a complete description of what runs in that
environment. Environments do not share a network, a database or a variable.
environments:
prod:
env: { LOG_LEVEL: { value: info } }
apps: [{ name: api, build_context: ., targets: [{ name: primary, plan: app-m }] }]
postgres: [{ name: main, targets: [{ name: primary, plan: pg-s }] }]
staging:
env: { LOG_LEVEL: { value: debug } }
apps: [{ name: api, build_context: ., targets: [{ name: primary, plan: app-s }] }]
postgres: [{ name: main, targets: [{ name: primary, plan: pg-s }] }]Resource
A resource is what you declare and name inside an environment: apps (containers Pier
builds or pulls), sites (static files served from the edge), Postgres (instances),
buckets (objects), volumes (block storage mounted into an app). Custom domains
attach to an app or site target. Resources in one environment can reference each other,
for example an app variable declared as { from: postgres.main.url }. A resource cannot
reference another environment.
Target
An app or site is a declaration; its targets are what run. A target is a named running
instance inside one environment, with its own hostname (https://<id>.app.pier.run), plan,
replicas, deploy history, logs and metrics. Most apps have one target, named primary,
and are addressed by the app name alone: pier logs api. A second target is a second
running copy of the same app, addressed as api/canary: for example a canary that
tracks a branch, or a worker built from a different Dockerfile.
- Every app and site has exactly one primary target. It is what
pier info apiand the console show when no target is named.pier promote api/canarymakes another target the primary; hostnames and variables are unchanged. - Previews are targets Pier creates automatically. With
previews:on an app, each push to a matching branch runs its own target against the environment's Postgres, and the target is removed when the branch is deleted. A preview is a target inside the environment, not a new environment. - Postgres has one target per environment (the instance). Buckets and volumes have none.
Ref
The grammar every runtime command accepts:
| Ref | Means |
|---|---|
api | the app; for a single-target app, its only target |
api/canary | one target |
api/canary/2 | one instance of that target (pier logs, pier ssh) |
--type pg main | breaks a name shared across kinds |
Apply, deploy, staged
pier.yaml is the source of truth; two verbs move the platform toward it.
pier applyconverges declarations: creates, changes and removes resources so the environment matches the file. It never rolls a workload.pier deploybuilds and rolls the targets whose source changed. It impliesapply.--stageonpier add,pier setandpier rmwrites the change topier.yamlonly. Nothing reaches the platform until the nextapplyordeploy, so several edits can be reviewed and applied as one change.
Trash
pier rm removes a resource from the environment and keeps its data for 30 days. pier trash lists what is recoverable, pier trash restore restores it, and pier trash purge
(or --purge on the removal) deletes the data before the window ends.
When you say…
| You want | In Pier that is |
|---|---|
| a staging copy of production | a second environment block in pier.yaml; pier copy app api --to staging seeds it |
| a preview for every pull request | previews: on the app or site: ephemeral targets in the same environment |
| a canary next to production | a second target on the app: pier add target api canary --branch main |
| separate databases for prod and staging | a postgres entry in each environment; environments never share an instance |
| a worker and an API from one repo | two targets with different dockerfile: values, or two apps |
| one bill for several products | one workspace, one project per product |