How to copy files over SSH with rsync

A release directory, backup bundle, or project tree often needs to land on a remote host without replacing unrelated paths. rsync over SSH fits that job when the sender has a known source directory, a dedicated destination directory, and an SSH login that can create and write to that destination.

The remote target uses the standard user@host:path rsync form, and rsync starts a remote-side process through OpenSSH rather than through an rsync daemon. A trailing slash on the source directory copies the directory's contents into the destination, while leaving the slash off copies the directory itself as a child under the destination.

Both systems need rsync installed, and the destination account needs permission to create the target path and write the copied files. Verify the remote side after the transfer with a listing and at least one checksum when the copy is feeding a deployment, handoff, or backup process.

Steps to copy files over SSH with rsync:

  1. Confirm rsync is available on the sending host.
    $ rsync --version
    rsync  version 3.4.1  protocol version 32
    ##### snipped #####
  2. Confirm SSH can reach the destination account and that rsync is available there.
    $ ssh deploy@server.example.com 'rsync --version'
    rsync  version 3.4.1  protocol version 32
    ##### snipped #####

    If the destination uses a custom port, key, or jump host, put those settings in /.ssh/config or pass them through rsync with -e 'ssh -p 2222'.

  3. Choose the source directory and remote destination path before transferring.
    Source directory: ./release/
    Remote destination: deploy@server.example.com:/home/deploy/releases/current/

    The trailing slash on ./release/ means rsync copies the contents of the directory into current/. Use ./release only when the remote destination should receive a top-level release directory.

  4. Create the destination directory through SSH so rsync writes into the intended path.
    $ ssh deploy@server.example.com 'mkdir -p /home/deploy/releases/current'
  5. Copy the source directory contents to the remote destination.
    $ rsync -avz ./release/ deploy@server.example.com:/home/deploy/releases/current/
    sending incremental file list
    ./
    app.tar.gz
    config.ini
    static/
    static/index.html
     
    sent 346 bytes  received 84 bytes  860.00 bytes/sec
    total size is 48  speedup is 0.11

    This command updates matching files and creates missing files; it does not remove old destination-only files. Add --delete only for a mirror workflow after a dry run.

  6. List the remote directory to confirm the expected files arrived.
    $ ssh deploy@server.example.com 'ls -R /home/deploy/releases/current'
    /home/deploy/releases/current:
    app.tar.gz
    config.ini
    static
     
    /home/deploy/releases/current/static:
    index.html
  7. Calculate a checksum for one representative source file.
    $ sha256sum ./release/app.tar.gz
    961b5aa69c7085fd5a3e03cce2b38d3ab1506da3f8302ce2f3a5d6d8cfd4a745  ./release/app.tar.gz
  8. Calculate the checksum for the remote copy and confirm it matches the source hash.
    $ ssh deploy@server.example.com 'sha256sum /home/deploy/releases/current/app.tar.gz'
    961b5aa69c7085fd5a3e03cce2b38d3ab1506da3f8302ce2f3a5d6d8cfd4a745  /home/deploy/releases/current/app.tar.gz