Skip to content

Folders and files

NameName
Last commit message
Last commit date

Latest commit

History

2 Commits

Repository files navigation

Deploy via rsync

A composite GitHub Action that deploys a release to a remote server using rsync and SSH. It handles the full release lifecycle: syncing files, symlinking shared resources, running remote commands, activating the release, and cleaning up old releases.

How it works

  1. Release naming — Generates a release name based on the git ref (e.g., prod-v1.2.0, staging-2025.03.08-abc1234, staging-pr-42-abc1234)
  2. Rsync — Syncs the working directory to a new release directory on the server
  3. Shared resources — Symlinks shared files (e.g., .env.local) and directories (e.g., var/log) from the project root into the release
  4. Remote commands — Runs arbitrary shell commands inside the release directory (e.g., composer install, cache clearing, migrations)
  5. Activation — Points the docroot symlink to the new release's public/ directory
  6. Cleanup — Optionally removes old releases in the same release group, keeping only the current and previous release

Inputs

InputRequiredDefaultDescription
project_pathRemote project base path (e.g., /var/www/project)
docrootRemote docroot symlink path (e.g., /var/www/html)
release_groupRelease group prefix to isolate releases (e.g., staging, prod)
cleanupfalseRemove old releases in the same release group after activation
rsync_switchesFlags and options passed to rsync
rsync_debugtrueEnable rsync debug output
shared_filesNewline-separated list of shared files to symlink into the release
shared_dirsNewline-separated list of shared directories to symlink into the release
remote_commandsShell commands to run inside the release directory after symlinking (before activation)
ssh_hostRemote SSH host
ssh_userRemote SSH user
ssh_keySSH private key
ssh_passphraseSSH key passphrase

Usage

Minimal example

steps:
- uses: actions/checkout@v4
- uses: ckrack/deploy-ssh-actionwith:
project_path: /var/www/myappdocroot: /var/www/htmlrelease_group: prodcleanup: truersync_switches: -avzr --deleteshared_files: | .envshared_dirs: | var/log public/uploads/mediassh_host: ${{ secrets.SSH_HOST }}ssh_user: ${{ secrets.SSH_USER }}ssh_key: ${{ secrets.SSH_KEY }}

Full example with build step and remote commands

steps:
- uses: actions/checkout@v4
- uses: actions/setup-node@v4with:
node-version-file: '.nvmrc'cache: 'yarn'
- run: | yarn install --frozen-lockfile yarn build - uses: ckrack/deploy-ssh-actionwith:
project_path: /var/www/myappdocroot: /var/www/htmlrelease_group: prodcleanup: truersync_switches: -avzr --deleteshared_files: | .envshared_dirs: | var/log public/uploads/mediaremote_commands: | composer install --no-dev --optimize-autoloader --no-interaction --no-progress php bin/console cache:clear php bin/console doctrine:migrations:migrate --no-interactionssh_host: ${{ secrets.SSH_HOST }}ssh_user: ${{ secrets.SSH_USER }}ssh_key: ${{ secrets.SSH_KEY }}ssh_passphrase: ${{ secrets.SSH_PASS }}

With additional rsync excludes

 - uses: ./.github/actions/deploy-rsyncwith:
project_path: /var/www/myappdocroot: /var/www/htmlrelease_group: prodcleanup: truersync_switches: -avzr --delete --exclude='extra-dir/'ssh_host: ${{ secrets.SSH_HOST }}ssh_user: ${{ secrets.SSH_USER }}ssh_key: ${{ secrets.SSH_KEY }}

Release directory structure

/var/www/project/
├── .env # shared file
├── .env.local # shared file
├── var/
│ ├── uploads/media/ # shared directory
│ └── log/ # shared directory
├── public/
│ └── uploads/media/ # shared directory
└── releases/
├── prod-v1.0.0/ # old release (cleaned up)
├── prod-v1.1.0/ # previous release (kept)
└── prod-v1.2.0/ # current release (active)
/var/www/html -> /var/www/project/releases/prod-v1.2.0/public

About

Opinionated deployment action using rsync, ssh and symlinks for minimal downtime deployments

Resources

Stars

0 stars

Watchers

0 watching

Forks

Releases

Packages

Contributors