Skip to content
Latchkey

rsync: Deploying Build Artifacts to a Server

A safe artifact deploy is rsync -a with a trailing-slash source, --delete to prune stale files, and protect rules for runtime data.

Deploying a built site to a server is the canonical rsync CI job. The pieces that matter are the trailing slash, --delete safety, and not clobbering server-side state.

What it does

rsync ships only the files that changed since the last deploy, so a 200 MB site that changed two files transfers two files. With -a for fidelity, a trailing-slash source for correct placement, and --delete to remove old assets, you get a clean, fast, idempotent deploy.

Common usage

Terminal
# Build, then deploy the contents of dist/ as a mirror
rsync -avz --delete --max-delete=200 \
  --filter='P uploads/***' \
  -e "ssh -i ~/.ssh/deploy_key" \
  dist/ deploy@host:/var/www/app/

Deploy building blocks

FlagWhy it is here
-aPreserve modes/times so incrementals work
-zCompress over a non-local link
--deleteRemove stale assets from the server
--max-delete=NAbort if a broken build would delete too much
--filter='P uploads/***'Protect runtime data from --delete
dist/Trailing slash: copy contents, not the dir

In CI

For near-atomic deploys, rsync into a fresh release directory (releases/<sha>/) and then flip a symlink: ssh host "ln -sfn /var/www/releases/$SHA /var/www/current". That avoids serving a half-synced tree and gives you instant rollback by repointing the symlink.

Common errors in CI

Two land repeatedly: a missing trailing slash nests dist/ inside the target (404s), and a bare --delete after a failed build wipes the site (guard with --max-delete). Run a --dry-run in the pipeline first and fail on unexpected "deleting" lines.

Related guides

Run this faster and cheaper on Latchkey managed runners. Start free →