Skip to content

GitHub Actions

Griffen Fargo edited this page Jul 1, 2026 · 1 revision

GitHub Actions

Deploy strut stacks to your VPS straight from CI using the official gfargo/strut-action — a thin wrapper that installs strut, wires up the SSH key and connection config, and runs a strut command against your server. No Kubernetes, no self-hosted runner.

The action lives in its own repo so it can be versioned independently and listed on the GitHub Marketplace.

Quick start

Your repository is the strut project root — it must contain strut.conf and stacks/<stack>/ (create them locally with strut init + strut scaffold).

# .github/workflows/deploy.yml
name: Deploy
on:
  push:
    branches: [main]

jobs:
  deploy:
    runs-on: ubuntu-latest
    steps:
      - uses: actions/checkout@v4
      - uses: gfargo/strut-action@v1
        with:
          stack: my-app
          command: release
          env: prod
          strict: true
          host: ${{ secrets.STRUT_HOST }}
          user: ${{ secrets.STRUT_USER }}
          ssh-key: ${{ secrets.STRUT_SSH_KEY }}

Inputs

Input Required Default Description
stack Stack name (a directory under stacks/).
command release release | deploy | ship | health | stop | status | exec.
env '' Environment name; reads .<env>.env (e.g. prod.prod.env).
services '' Service profile passed as --services (e.g. full).
strict false Pass --strict (fail the release if migrations fail).
dry-run false Pass --dry-run to preview without executing.
args '' Extra raw arguments appended to the command.
ssh-key Private SSH key authorized on the VPS. Always pass via a secret.
host '' VPS host/IP → VPS_HOST.
user '' VPS SSH user → VPS_USER.
port 22 VPS SSH port → VPS_PORT.
known-hosts '' known_hosts entries. If empty, the host key is fetched via ssh-keyscan.
env-file '' Full contents of .<env>.env. Always pass via a secret. Optional.
strut-version latest latest | main | vX.Y.Z.
working-directory . Project root containing strut.conf.

Required secrets

Add these under Settings → Secrets and variables → Actions:

Secret Purpose
STRUT_SSH_KEY Private SSH key authorized on the VPS.
STRUT_HOST VPS host or IP.
STRUT_USER VPS SSH user (e.g. root, deploy).

Optionally store the full env file as STRUT_PROD_ENV and pass it via env-file.

How connection config works

The action writes the VPS connection variables (VPS_HOST, VPS_USER, VPS_PORT, VPS_SSH_KEY) into the target env file (.<env>.env). If you pass env-file, its contents are written first and the connection variables are appended last (so they win). strut sources this file before connecting.

If your repo already defines hosts via Multi-Host Topology in strut.conf, you can omit host/user and just provide ssh-key.

release vs deploy in CI

  • release runs on the VPS over SSH (sync repo → migrate → deploy → verify) and is the usual choice for CI. It requires the VPS to be bootstrapped once with Remote Host Setup (strut remote:init).
  • deploy runs locally on the runner. Use it only when the runner itself is the target or has a remote Docker context configured.

Security

  • Pass ssh-key and env-file only as GitHub secrets — never inline.
  • Secret values are written with 0600 perms on the ephemeral runner and are never echoed to logs.
  • Use a dedicated deploy key scoped to the one VPS; rotate with Key Rotation (strut keys ssh:rotate) or regenerate with strut <stack> ssh:keygen.

Versioning

Pin @v1 to ride the moving major tag (automatic patch/minor updates), or pin an exact release (@v1.0.0) for full reproducibility.

See also

Clone this wiki locally