If you work with remote servers, sooner or later you’ll need to move files between your local machine and a server or between two servers. One of the simplest, most reliable tools for this is SCP (Secure Copy Protocol).
SCP rides on top of SSH, which means every transfer is encrypted and authenticated the same way an SSH login is. No extra setup, no separate credentials, if you can SSH into a machine, you can SCP files to and from it.
Below are the three most common SCP operations you’ll use day to day.
1. Copying a Local File to a Remote Server
scp file.txt user@host:/path
This uploads file.txt from your current directory to /path on the remote machine.
user@hostis the username and address (or hostname) of the remote server/pathis the destination directory on that server- If you omit the filename in the destination path, SCP keeps the original filename
Example: scp report.txt deploy@192.168.1.10:/home/deploy/reports/
The file doesn’t have to be a .txt
This example uses file.txt, but SCP doesn’t care what kind of file you’re copying, it works exactly the same way for a .zip, .tar.gz, .jpg, .pdf, or any other file type. The command structure never changes :
scp file.zip user@host:/path
scp backup.tar.gz user@host:/path
scp image.jpg user@host:/path
So which approach should you use?
- If you’re copying a single file that’s already there (of any type txt, zip, jpg, etc.), just use the command above as-is.
- If you’re copying a whole folder and it’s not zipped, skip straight to Section 3 (Copying an Entire Directory) and use
scp -r. There’s no need to zip something first just to move it, recursive copy handles folders directly. - If you want to zip the folder first (useful for faster transfers, fewer files to track, or archiving), keep reading below.
If You Want to Zip Before Transferring
Zipping a directory before sending it can be worth it when you have many small files (each file adds transfer overhead) or when you want a single compressed archive as a backup. To do this, both your local machine and the production/remote server need the zip and unzip utilities installed.
Step 1 Install zip/unzip locally
On Debian/Ubuntu:
sudo apt update
sudo apt install zip unzip -y
On macOS (via Homebrew):
brew install zip unzip
Step 2 Install zip/unzip on the remote/production server
SSH into the server first, then run the same install command that matches its OS:
ssh user@host
sudo apt update && sudo apt install zip unzip -y # Debian/Ubuntu
Step 3 Zip the folder locally
zip -r archive.zip dir/
This compresses everything inside dir/ into a single file called archive.zip.
Step 4 Transfer the zip file with SCP
scp archive.zip user@host:/path
Step 5 Unzip it on the remote server
SSH into the server and extract the archive:
ssh user@host
unzip archive.zip -d /path
The -d flag tells unzip where to extract the contents. If you skip it, the files extract into your current directory.
Quick summary of the zip workflow:
zip -r archive.zip dir/ # 1. Compress locally
scp archive.zip user@host:/path # 2. Transfer
ssh user@host # 3. Log in
unzip archive.zip -d /path # 4. Extract remotely
2. Copying a Remote File to Your Local Machine
scp user@host:/path/file.txt .
This is the reverse: it pulls file.txt from the remote server down to your local machine. The . at the end means “save it in my current directory”, you can replace it with any local path.
Example: scp deploy@192.168.1.10:/var/log/app.log ./logs/
This is especially handy for grabbing log files or config files off a server without logging in and manually copying content.
3. Copying an Entire Directory
scp -r dir/ user@host:/path
The -r flag stands for recursive, and it’s required whenever you’re copying a folder instead of a single file. Without -r, SCP will simply refuse to copy a directory.
This command copies the entire dir/ folder including all subfolders and files inside it to /path on the remote server.
Example: scp -r ./website-build/ user@host:/var/www/html/
The same -r flag works in reverse too, if you want to pull a whole directory from a remote server to your local machine:
scp -r user@host:/path/dir/ .