Creating Projects & Environments (Dashboard)
The Getting Started and
Environments & Services pages cover the canopy CLI.
This page walks the same territory from the web dashboard
(app.canopy.pm) instead, step by step, for anyone who’d rather click
through the UI than run commands.
Concepts, quickly
- A project groups environments together - usually one project per app. Projects belong to a team.
- An environment is the actual deployable unit: its own Dokku app, build, domains, database, storage mounts, and variables, tracked against a specific git branch.
- If your repository is a monorepo (more than one deployable app in one repo - e.g. a frontend and a backend in separate folders), you don’t create two disconnected projects for it. Instead, one environment becomes the root, and each other app in the repo becomes a service underneath it. Both are full environments (their own build, domains, variables) - a service is just linked to its root for grouping, and can be deployed or torn down independently. See Adding a service for a monorepo below.
1. Create a project
- Go to Projects in the dashboard and click New project
(
/projects/create). - Fill in:
- Project name - e.g.
my-app. - Team - which team owns this project.
- Project name - e.g.
- Click Create project. You’re taken to the new project’s page, which starts with zero environments.
2. Create an environment
From the project page, click Add environment
(/projects/[project]/environments/create).
If your team has any templates set up, you’ll first see a gallery step - pick Deploy your own repository to skip templates and go straight to the form below (or pick a template to deploy from a preset instead).
Source
- Repository - pick the repo from the connected-provider picker.
- Branch - the branch this environment tracks (defaults to
main). A push to this branch triggers a deploy automatically.
Advanced options (collapsed by default - a badge shows how many are set once you’ve touched any of them):
- Build path - for a monorepo, the subdirectory containing this
app’s Dockerfile (e.g.
apps/web). Leave blank if the repository only contains one app at its root. - Build steps - extra build commands, if needed.
- Custom domain - point your DNS at the IP shown on this step first; see Domains below for how TLS gets provisioned.
- Database - optionally provision a database alongside this environment.
Click Create environment. You’re redirected to the new environment’s page once it’s created; the first build/deploy kicks off in the background.
Adding a service for a monorepo
Once a root environment exists, open it and find the Services section, then click Add service. This reuses the same repository/branch as the root by default, so you only need to fill in:
- Service name - e.g.
frontendorapi. - Build path - required here, since it’s what tells this service
apart from its siblings (e.g.
frontendvsbackend).
Repeat for each app in the monorepo. Each service gets its own build, domains, variables, and deploy history, and can be redeployed or removed independently of the root and its other services.
3. Environment variables
Open an environment and go to its Variables tab.
Variables are split into two groups:
- System Variables - managed by Canopy itself (shown with a lock icon), not editable here.
- User Variables - yours to add, edit, and delete.
To add one: fill in Name and Value under “Add variable” and submit. Values are encrypted at rest and masked by default in the list - click the eye icon on a row to reveal one, or use the copy icon next to it to copy just that value to your clipboard.
To edit or delete one: use the pencil/trash icons on that variable’s row.
To copy variables from another environment (e.g. bringing staging’s config into production, or seeding a brand-new service from its root): click Copy from another environment above the tabs, pick the source environment from the dropdown, and click Copy variables. Every non-system variable from the source is added here - a variable that already exists under the same name is overwritten with the source’s value, so this is safe to run more than once. System variables are never copied.
A banner will show up automatically if two environments in the same project have drifted apart (one has a variable the other doesn’t) - that’s a hint, not an error, and the copy action above is the fastest way to reconcile it.
Note: a variable that’s read at build time (e.g. a Next.js app’s
NEXT_PUBLIC_* values) needs a fresh deploy to take effect - setting or
copying it doesn’t retroactively change an already-built image.
4. Storage mounts
Open an environment and go to its Resources tab (this is also where database provisioning lives). Under Storage mounts, click Add mount and fill in:
- Host path - a path on the underlying host.
- Container path - where that path is mounted inside your app’s container.
Changes here take effect on the next deploy, not the currently running container - trigger one from the environment’s Pipelines tab (or just push a commit) after adding or removing a mount.
Domains
Open an environment and go to its Domains tab to add a custom domain. Point your DNS at Canopy’s IP first (shown on the create-environment form); TLS is provisioned automatically after the first successful deploy once DNS has propagated. If a certificate doesn’t show up, a retry option is available on the same tab rather than waiting for another deploy.
Deploying
A push to an environment’s linked branch triggers a deploy automatically via webhook - no dashboard action needed. See Deploys & the Staged Pipeline for what happens during a build, and each environment’s Pipelines tab for build history and live logs.