In this article
To upload files to a Google Compute Engine VM, use gcloud compute scp from your computer, or the Upload file option in the browser SSH window for a single small file. This guide covers both directions on Windows, macOS and Linux, plus rsync, Cloud Storage, IAP tunneling for VMs with no public IP, and fixes for common errors.
Key takeaways
- Use gcloud compute scp for regular transfers, with --recurse for folders.
- The old copy-files command is deprecated, so follow current scp instructions.
- For protected folders such as /var/www, upload to your home folder and then move the files with sudo.
- Use IAP tunneling for VMs without a public IP, and never open SSH to the whole internet.
The problem
You have files on your computer, such as a website, a database dump or a build, and you want them on a Google Compute Engine (GCE) virtual machine. The steps are scattered across Google's documentation, and older tutorials use a command that is now deprecated.
This guide shows how to move files in both directions, covers simpler alternatives, and lists fixes for the errors people hit most.
Which method should you use?
| Method | Best for | Needs |
|---|---|---|
| Browser SSH upload | One-off, small files, no setup | A Google Cloud console login |
| gcloud compute scp | Regular or scripted transfers | Google Cloud CLI installed |
| rsync over SSH | Large folders, resuming and syncing changes | SSH set up on your computer |
| Cloud Storage bucket | Very large files, many users or VMs | A bucket and VM access to it |
| IAP tunnel + scp | VMs with no public IP address | IAP firewall rule and permissions |
Prerequisites
- A running virtual machine. The instance must be running to accept files.
- The Google Cloud CLI (previously called the Google Cloud SDK) installed on your computer. Use the official installation page for your operating system.
- Permission to connect to the VM, through OS Login or SSH keys.
- A firewall rule allowing SSH (TCP 22) to the VM. Default networks include one, but custom networks might not.
Step 1: Sign in and set your project
Open a terminal (or the Google Cloud CLI shell on Windows) and run:
gcloud init
You will be asked to sign in and choose a project and a default zone. To do it manually instead:
gcloud auth login
gcloud projects list
gcloud config set project PROJECT_ID
Use the actual project ID (for example my-app-123456), not just the project name.
Step 2: Find your VM name and zone
gcloud compute instances list
The output shows the NAME and ZONE of each instance. To save typing, set a default zone:
gcloud config set compute/zone us-central1-a
Step 3: Upload a file or folder
Go to the folder that contains your files, then run:
# Upload one file to your home folder on the VM
gcloud compute scp ./report.pdf my-vm:~/ --zone=us-central1-a
# Upload a whole folder
gcloud compute scp --recurse ./my-folder my-vm:~/ --zone=us-central1-a
Replace my-vm with your instance name and the zone with your own. The --recurse flag is required for folders, and ~/ means your home directory on the VM.
About the username. By default gcloud chooses the username for you. To set it explicitly, write USER@my-vm:~/. With OS Login, Google-generated usernames often look like your email address with symbols replaced by underscores, for example test_gmail_com. If you are not sure, connect once with gcloud compute ssh my-vm --zone=us-central1-a and run whoami.
Uploading to /var/www or other protected folders
An ordinary user cannot write directly into directories owned by root, such as /var/www. You will get a "Permission denied" error. Do it in two stages:
# 1. Upload to your home folder
gcloud compute scp --recurse ./my-site my-vm:~/ --zone=us-central1-a
# 2. Connect and move it into place
gcloud compute ssh my-vm --zone=us-central1-a
sudo mv ~/my-site /var/www/
sudo chown -R www-data:www-data /var/www/my-site
www-data is the usual owner for Apache and Nginx on Debian and Ubuntu. Other distributions use a different owner (such as nginx or apache), so check which user your web server runs as.
Check that it worked
gcloud compute ssh my-vm --zone=us-central1-a --command='ls -l ~'
Step 4: Download files from the VM
Swap the source and destination:
# Download one file to the current folder
gcloud compute scp my-vm:~/backup.sql ./ --zone=us-central1-a
# Download a folder
gcloud compute scp --recurse my-vm:~/logs ./logs --zone=us-central1-a
Windows, macOS and Linux notes
- macOS and Linux: gcloud uses the OpenSSH tools already on your computer. On the first connection it generates and installs an SSH key for you.
- Windows: use PowerShell or the Google Cloud CLI shell. gcloud uses an SSH client such as OpenSSH, and in some cases sets up PuTTY on first use. Follow its prompts.
- Windows paths: scp tools can read a drive letter like C: as a hostname. The simplest fix is to change to the folder and use relative paths such as ./my-folder.
- Slow or interrupted transfers: compress first, for example tar -czf site.tar.gz ./site, upload the single file, then unpack it on the VM with tar -xzf site.tar.gz.
Easier alternatives
Browser SSH upload (no installation)
This is the fastest way to move a single file. In the Google Cloud console, open Compute Engine, then VM instances, and click SSH next to your VM. In the terminal window that opens, the settings menu has Upload file and Download file options.
Cloud Storage as a staging area
If the file is big, or several people and VMs need the same files, upload it to a Cloud Storage bucket and download it on the VM:
# On your computer
gcloud storage cp ./big-file.zip gs://my-bucket/
# On the VM
gcloud storage cp gs://my-bucket/big-file.zip ~/
The VM's service account needs read permission on the bucket, and you should check the cost of moving data into Google Cloud first. Many tutorials still use the old gsutil command, but Google recommends the gcloud storage commands instead.
rsync for large folders and repeat syncs
rsync sends only what has changed and can resume interrupted transfers. gcloud can write SSH settings for your instances so ordinary SSH tools work with them:
gcloud compute config-ssh
rsync -avz ./my-folder my-vm.us-central1-a.PROJECT_ID:~/
Check the exact host name config-ssh created in your ~/.ssh/config file and use that in the rsync command.
VMs with no public IP: use IAP tunneling
Many production VMs have no external IP address. You can still connect through Identity-Aware Proxy (IAP):
gcloud compute scp --tunnel-through-iap ./my-folder my-vm:~/ --zone=us-central1-a
This requires:
- A firewall rule that allows SSH from Google's IAP address range. Check Google's documentation for the current range, which was 35.235.240.0/20 at the time of writing.
- The IAP-secured Tunnel User role for your account.
Troubleshooting common errors
| Error or symptom | Likely cause | Fix |
|---|---|---|
| You do not currently have an active account selected | Not signed in | Run gcloud auth login or gcloud init |
| The required property [project] is not currently set | No default project | Run gcloud config set project PROJECT_ID |
| Resource not found or Could not fetch instance | Wrong project ID, VM name or zone | Check with gcloud projects list and gcloud compute instances list, and pass --zone |
| Unable to fetch a list of zones | Project not set or wrong | Set the correct project ID |
| Permission denied (publickey) | SSH key not accepted or OS Login permission missing | Run gcloud compute ssh my-vm once to create and push your key, and check your OS Login roles |
| Connection timed out or refused | VM stopped, firewall blocks port 22, or no public IP | Start the VM, add a rule for TCP 22, or use IAP |
| Permission denied when writing a file | Destination folder is owned by root | Upload to ~/, then sudo mv |
| IAP error such as failed to connect to backend | IAP firewall rule or role missing | Add the IAP range rule and the tunnel user role |
| Command not found, or a deprecation warning for copy-files | You are following an older tutorial | Use gcloud compute scp |
| Source path rejected on Windows | Drive letter confused with a host name | Run the command from the folder and use relative paths |
Security tips
- Do not open port 22 (SSH) to 0.0.0.0/0. Open it only for your IP range, or use IAP.
- Use SSH keys or OS Login instead of passwords.
- Delete old SSH keys and accounts you no longer need.
- Do not leave sensitive files such as database backups and .env files on the VM or in a bucket longer than necessary.
- Give the VM service account the least privilege it needs.
Need help with cloud hosting or server setup?
Uploading files is only the start. Production environments also need security, backups, monitoring and deployment. Ucodice specialists deploy and manage applications on Google Cloud, AWS and other platforms.
Talk to our server support team | Contact us
Frequently asked questions
Does gcloud compute copy-files still exist?
Google's command reference marks it as deprecated and replaced by gcloud compute scp. Use scp for everything new, and check the Google Cloud CLI release notes before relying on copy-files in scripts.
How do I upload a whole folder?
Add the --recurse flag: gcloud compute scp --recurse ./my-folder my-vm:~/ --zone=ZONE.
How do I download files from the VM to my computer?
Put the VM path first and your local path second: gcloud compute scp my-vm:~/file.txt ./ --zone=ZONE.
Should I allow port 22 access for file uploads?
Yes, SSH on port 22 must be reachable on the VM, either directly or through the IAP tunnel. Limit it to trusted sources.
What is the difference between project ID and project name?
The name is a friendly label. The ID is the unique string that gcloud commands need. Run gcloud projects list to see both.
What is the easiest way to upload one small file?
Use the Upload file option in the browser SSH window in the Google Cloud console.
Can I upload very large files?
Yes. Compress them first, or use Cloud Storage or rsync, which cope better with large files and interrupted transfers.



