To copy files over SSH, use scp source destination for simple transfers or rsync over SSH when resume, progress, and efficient repeated synchronization matter.
Most transfer mistakes are direction mistakes. Decide which machine owns the source, which owns the destination, and where the command is running before adding flags.
Table of contents
- Read scp from left to right
- Copy directories, ports, and paths safely
- Use rsync for repeatable or interrupted transfers
- Protect authentication and host identity
- Verify the result
- How this fits the rest of the stack
- FAQ
Read scp from left to right
A remote path has the shape user@host:/path. Put it on the right to upload and on the left to download. Run the command from the machine that should initiate the SSH connection.
# Upload
scp ./build.tar.gz [email protected]:/srv/releases/
# Download
scp [email protected]:/var/log/my-api/error.log ./error.log
Use absolute remote paths when possible. Relative remote paths are resolved from the remote user’s home directory, which may not be where a service stores files.
Copy directories, ports, and paths safely
scp -r copies directories recursively. A custom SSH port uses uppercase -P; lowercase -p preserves times and modes. Quote local paths and carefully quote remote paths containing spaces so the correct shell interprets them.
scp -P 2222 -r ./assets [email protected]:/srv/app/
scp '[email protected]:/srv/reports/month end.csv' ./
Avoid copying directly over a live release directory. Transfer to a versioned or temporary location, verify it, then switch the application atomically where the deployment design allows.
Use rsync for repeatable or interrupted transfers
rsync compares files and transfers changes, making it better for large trees and repeated synchronization. --partial keeps partial data for resumption, while --archive preserves common metadata. A trailing slash changes whether the source directory itself or only its contents are copied.
rsync --archive --partial --progress \
-e 'ssh -p 2222' \
./assets/ [email protected]:/srv/app/assets/
Be cautious with --delete; it makes the destination mirror the source by removing extra destination files. Preview with --dry-run and inspect the exact paths before using it on valuable data.
Protect authentication and host identity
Use scoped SSH keys, verify host keys, and keep private keys out of repositories and command output. Do not disable host-key checking to make automation quiet. Manage known hosts explicitly in CI and rotate access when operators or systems change.
Restrict the remote account to the directories and commands it needs. A file-transfer credential does not automatically need an interactive shell or broad sudo access.
Verify the result
Check command exit status, destination size, ownership, permissions, and checksums when integrity matters. For releases, verify the artifact before activation and keep the previous version available for rollback.
sha256sum build.tar.gz
ssh [email protected] 'sha256sum /srv/releases/build.tar.gz'
Log transfer identifiers and outcomes without leaking paths that contain secrets. For frequent production movement, prefer an artifact store or deployment pipeline over a growing collection of manual scp commands.
How this fits the rest of the stack
If those artifacts are moving into a production service, model runtime, persistent storage, databases, and transfer in the RunxBuild hosting calculator. The RunxBuild dashboard provides a repeatable deployment route when manual copying has reached its limit.
Useful related references:
- Send a File Over SSH: Use rsync, Not scp
- What Port is SSH: 22 (Default), How to Change, and Why
- Default Port for SSH: Why 22, and When to Change It
- Services on RunxBuild
FAQ
How do I copy a local file to a remote server?
Run scp local_file user@host:/remote/path/ from the local machine.
How do I copy a remote file to my computer?
Put the remote source first: scp user@host:/remote/file ./local_file.
How do I copy a directory over SSH?
Use scp -r for a simple recursive copy or rsync --archive for efficient, repeatable transfers.
Can scp resume an interrupted transfer?
Not reliably in the way rsync can. Use rsync --partial for large transfers that may need resumption.
How do I use a custom SSH port?
With scp use uppercase -P 2222. With rsync specify the SSH command, such as -e 'ssh -p 2222'.