CLI
Use the pullpreview binary for local debugging, manual deployments, and provider validation outside GitHub Actions.
The pullpreview binary runs the same deployment engine as the GitHub Action, but from your own machine. Use it for local debugging, manual deployments, and validating provider credentials before wiring them into CI.
This is primarily for power users and contributors. Day-to-day previews are driven by the GitHub Action on labelled pull requests; reach for the CLI when you need to iterate locally or troubleshoot a deployment in isolation.
Install
Download a release binary from GitHub Releases ↗ and add it to your PATH, or build from source with the repo toolchain:
mise exec -- go run ./cmd/pullpreview --helpmise exec -- go build -o pullpreview ./cmd/pullpreviewBasic commands
The CLI exposes four subcommands: up, down, list, and github-sync.
# Deploy a local projectpullpreview up ./path/to/app --name pullpreview-local --instance-type small --region us-east-1# List deployments created by PullPreviewpullpreview listpullpreview list my-org/my-repo# Destroy a deployment by instance namepullpreview down --name pullpreview-localup accepts either a local path or a Git URL as app_path. list optionally accepts an org/repo argument to scope the results. down accepts normalized instance names or existing pullpreview-* context-style names.
The --region, --image, and --instance-type flags are the provider sizing and location knobs exposed by both the CLI and the GitHub Action. See Providers for the values each provider accepts.
github-sync
github-sync reconciles deployments against the state of a repository, the same way the Action does on each run. You can force a specific action instead of letting it infer one:
pullpreview github-sync ./path/to/apppullpreview github-sync ./path/to/app --force-action uppullpreview github-sync ./path/to/app --force-action downDeployment targets
Use --deployment-target to choose the deployment engine. compose is the default; helm bootstraps k3s and deploys a Helm chart. See Deployment targets for the full comparison.
Compose
pullpreview up ./examples/workflow-smoke \ --name pullpreview-local-compose \ --deployment-target compose \ --compose-files docker-compose.yml \ --compose-options=--build \ --proxy-tls web:8080The --registries flag and custom --compose-files / --compose-options are compose-only.
Helm
pullpreview up ./examples/openproject \ --name pullpreview-local-helm \ --deployment-target helm \ --chart ./chart \ --chart-values values-preview.yaml \ --chart-set 'baseUrl={{pullpreview_url}}' \ --proxy-tls-hosts 'nextcloud.{{pullpreview_public_dns}},keycloak.{{pullpreview_public_dns}}' \ --proxy-tls '{{release_name}}-web:80'Helm rules:
--chartis required.--proxy-tlsis required.--proxy-tls-hostsis optional and helm-only — it adds extra public hostnames to the Helm Caddy gateway.--registriesis not supported.- Custom
--compose-files/--compose-optionsare not supported.
Hetzner locally
To target Hetzner from the CLI, set PULLPREVIEW_PROVIDER=hetzner along with HCLOUD_TOKEN and HETZNER_CA_KEY:
PULLPREVIEW_PROVIDER=hetzner \HETZNER_CA_KEY="$(cat ~/.ssh/hetzner_ca_key)" \HCLOUD_TOKEN=... \pullpreview up ./path/to/app \ --deployment-target helm \ --chart ./charts/my-app \ --proxy-tls '{{release_name}}-web:80' \ --region nbg1 \ --image ubuntu-24.04 \ --instance-type cpx22HETZNER_CA_KEY is an SSH CA private key. Generate a compatible one with:
ssh-keygen -t rsa -b 3072 -m PEM -N "" -f ~/.ssh/hetzner_ca_keyIf you keep these values in a .env file, load them into your shell with:
set -a; . ./.env; set +aSee Providers for more on configuring Hetzner credentials.