Optional CLI | Canopy Docs - Canopy
Documentation

Migrated user-facing app documentation, including screenshots and the same step-by-step document flow.

Optional CLI

If you prefer terminal workflows, Canopy offers a CLI (if installed on your system).

Install the CLI

Canopy can install the prebuilt CLI directly from the app bundle:

  1. During first-run onboarding, click Install CLI when prompted.
  2. Any time later, open Settings → Canopy CLI and click Install CLI (or Update CLI).

This path does not require building from source or installing Swift/Xcode.

If you are running Canopy from source as a developer, you can install the CLI manually:

bash scripts/install-cli.sh
canopy --help

If the installer uses ~/.local/bin, add it to your PATH:

export PATH="$HOME/.local/bin:$PATH"

Common commands

  • canopy add /path/to/my-app — create a new site from any project folder (Canopy links it internally)
  • canopy link /path/to/my-app — link an existing nginx.conf from any project folder
  • canopy edit my-app.test — edit a site config
  • canopy remove my-app.test — remove a site
  • canopy restart — restart nginx + PHP

Run commands inside containers (Swift CLI)

The modern Swift CLI also provides shortcuts for running project commands directly in containers.

When you run PHP shortcuts (canopy artisan, canopy composer) from a project directory, Canopy uses the PHP version configured for that site in the app. For example, if the site is set to PHP 8.4, these commands run in the php84 container.

# Laravel / PHP
canopy artisan migrate
canopy composer install

# Frontend tooling (auto-detects pnpm/yarn/npm from lockfiles)
canopy npm run dev
canopy npx vitest

# Generic container access
canopy shell php83
canopy exec php83 "php -v"

Run these from inside your project directory for automatic path mapping. If you're elsewhere in the terminal, use --project <name> to pick a project explicitly.

Template variable examples

Use --var KEY=VALUE to customize templates without editing nginx manually:

# Serve SPA assets from /build instead of /dist
canopy add my-spa app.test spa --var SPA_ROOT=build

# Proxy a Node dev server running on port 3000
canopy add my-app app.test node-dev --var UPSTREAM=host.docker.internal:3000

# Generic reverse proxy to another local service
canopy add my-api api.test proxy --var UPSTREAM=host.docker.internal:8080

You can repeat --var to pass multiple template variables when needed.

Tips

  • The GUI and CLI share the same underlying config.
  • If a command fails, check the Activity Log (Cmd+Opt+L) for details.

Next up

Find answers in Troubleshooting.