Skip to content
Cyril Rohr edited this page Mar 13, 2026 · 22 revisions

Basic Compose workflow

Unless stated otherwise, examples below use the default lightsail provider.

name: PullPreviewon:
schedule:
- cron: "30 */4 * * *"pull_request:
types: [labeled, unlabeled, synchronize, closed, reopened, opened]permissions:
contents: readpull-requests: writejobs:
deploy:
if: github.event_name == 'schedule' || github.event.label.name == 'pullpreview' || contains(github.event.pull_request.labels.*.name, 'pullpreview')runs-on: ubuntu-slimtimeout-minutes: 30steps:
- uses: actions/checkout@v6
- uses: pullpreview/action@v6with:
deployment_target: composeapp_path: .admins: "@collaborators/push"instance_type: microttl: 1henv:
AWS_ACCESS_KEY_ID: ${{ secrets.AWS_ACCESS_KEY_ID }}AWS_SECRET_ACCESS_KEY: ${{ secrets.AWS_SECRET_ACCESS_KEY }}AWS_REGION: us-east-1

schedule is optional and only handles dangling deployment cleanup. For v6, create and update flows are driven by labeled pull request events, not direct branch pushes. See Migrating from v5 to v6 if you previously used always_on.

Hetzner Compose workflow

Generate an SSH CA key once:

ssh-keygen -t rsa -b 3072 -m PEM -N "" -f hetzner_ca_key

Store the private key contents as HETZNER_CA_KEY.

- uses: pullpreview/action@v6with:
provider: hetznerdeployment_target: composeregion: nbg1image: ubuntu-24.04instance_type: cpx21ttl: 1henv:
HCLOUD_TOKEN: ${{ secrets.HCLOUD_TOKEN }}HETZNER_CA_KEY: ${{ secrets.HETZNER_CA_KEY }}

Compose with automatic HTTPS

- uses: pullpreview/action@v6with:
deployment_target: composeproxy_tls: web:8080dns: rev1.clickenv:
AWS_ACCESS_KEY_ID: ${{ secrets.AWS_ACCESS_KEY_ID }}AWS_SECRET_ACCESS_KEY: ${{ secrets.AWS_SECRET_ACCESS_KEY }}

Compose with private registry images

- uses: pullpreview/action@v6with:
deployment_target: composeregistries: docker://${{ secrets.GHCR_PAT }}@ghcr.ioenv:
AWS_ACCESS_KEY_ID: ${{ secrets.AWS_ACCESS_KEY_ID }}AWS_SECRET_ACCESS_KEY: ${{ secrets.AWS_SECRET_ACCESS_KEY }}

Compose with multiple Compose files

- uses: pullpreview/action@v6with:
deployment_target: composecompose_files: docker-compose.yml,docker-compose.pullpreview.ymlcompose_options: --build,--remove-orphansenv:
AWS_ACCESS_KEY_ID: ${{ secrets.AWS_ACCESS_KEY_ID }}AWS_SECRET_ACCESS_KEY: ${{ secrets.AWS_SECRET_ACCESS_KEY }}

Helm with a local chart on Hetzner

name: PullPreview Helmon:
pull_request:
types: [labeled, unlabeled, synchronize, closed, reopened, opened]jobs:
deploy_helm:
runs-on: ubuntu-slimif: github.event.label.name == 'pullpreview' || contains(github.event.pull_request.labels.*.name, 'pullpreview')timeout-minutes: 45steps:
- uses: actions/checkout@v6
- uses: pullpreview/action@v6with:
provider: hetznerdeployment_target: helmchart: ./charts/my-appchart_values: charts/my-app/values-preview.yamlchart_set: image.tag=${{ github.sha }},baseUrl={{ pullpreview_url }}proxy_tls: "{{ release_name }}-web:80"dns: rev2.clickenv:
HCLOUD_TOKEN: ${{ secrets.HCLOUD_TOKEN }}HETZNER_CA_KEY: ${{ secrets.HETZNER_CA_KEY }}

Helm with a repo chart on Lightsail

name: PullPreview Lightsail Helmon:
pull_request:
types: [labeled, unlabeled, synchronize, closed, reopened, opened]jobs:
deploy_lightsail_helm:
runs-on: ubuntu-slimif: github.event.label.name == 'pullpreview-helm' || contains(github.event.pull_request.labels.*.name, 'pullpreview-helm')timeout-minutes: 45steps:
- uses: actions/checkout@v6
- uses: pullpreview/action@v6with:
label: pullpreview-helmprovider: lightsailregion: us-east-1deployment_target: helmchart: wordpresschart_repository: https://charts.bitnami.com/bitnamichart_set: service.type=ClusterIPproxy_tls: "{{ release_name }}-wordpress:80"instance_type: mediumdns: rev3.clickenv:
AWS_ACCESS_KEY_ID: ${{ secrets.AWS_ACCESS_KEY_ID }}AWS_SECRET_ACCESS_KEY: ${{ secrets.AWS_SECRET_ACCESS_KEY }}

See also:

Clone this wiki locally