Easiest way to copy a single file from host to Vagrant guest?
Asked Answered
P

20

308

I have a use case where I occasionally want to copy a single file from my host machine to the Vagrant guest.

I don't want to do so via traditional provisioners (Puppet / Chef) because this is often a one-off -- I just want something quick to add to my Vagrantfile.

I don't want to share an entire directory, possibly because I want to overwrite an existing file without nuking an entire directory on the guest.

It also seems a bit overkill to write a shell provisioning script, and deal with potential escaping, when all I want to do is copy a file.

So, what's the easiest way to copy a single file from host to guest?

Pyxis answered 23/5, 2013 at 1:7 Comment(4)
note that the accepted answer is based on Vagrant 1.x--using a file provisioner is the standard Vagrant 2 approach, although changing the mount point of /vagrant as mentioned here can also be a good optionFremd
The answer from @jouell really merits more votes for the simple use case of a one-off copy of a single file: vagrant upload /path/to/my/file...Forrester
vagrant scp file.txt :~/.Photoluminescence
https://mcmap.net/q/99357/-easiest-way-to-copy-a-single-file-from-host-to-vagrant-guest by stackoverflow.com/users/3462494/jouell should be the accepted answer. It is an inbuilt command to the Vagrant CLI to copy a file or directory to a host vagrant upload SOURCE [DESTINATION] [NAME|ID]. I missed that initially because it is buried too far down.Solander
M
141

Instead of using a shell provisioner to copy the file, you can also use a Vagrant file provisioner.

Provisioner name: "file"

The file provisioner allows you to upload a file from the host machine to the guest machine.

Vagrant.configure("2") do |config|
  # ... other configuration

  config.vm.provision "file", source: "~/.gitconfig", destination: ".gitconfig"
end
Marquismarquisate answered 25/4, 2014 at 20:15 Comment(4)
This is definitely the best way to do this in Vagrant 2! However, Vagrant 2 was not available at the time I needed to do this... :)Pyxis
This solution sounds nice, but i can't copy any file due to permission errors.Oscilloscope
@Oscilloscope I had the same problem, but not if I copied it to /tmpLadanum
this is not what the OP asked. the question was how to occasionally transfer files; having to run provisioning is overkill.Smithson
C
303

Since you ask for the easiest way, I suggest using vagrant-scp. It adds a scp command to vagrant, so you can copy files to your VM like you would normally do with scp.

Install via:

vagrant plugin install vagrant-scp

Use it like so:

vagrant scp <some_local_file_or_dir> [vm_name]:<somewhere_on_the_vm>
Corves answered 6/2, 2015 at 5:57 Comment(10)
This didn't work for me. I installed the plugin, but kept getting an error that said "The plugin "vagrant-scp" could not be found. Please make sure that it is properly installed via vagrant plugin."Loose
Hi Rod, vagrant-scp works with Vagrant 1.7+. From the bug you opened, you are running 1.4.3. If you need this plugin, I'm afraid you'll have to upgrade (which is quick and painless).Corves
Hi Abram, please have a look at the readme, it'll show you how to upgrade your Vagrant version.Corves
I tried this command to copy files but didn't work and giving error vagrant scp /vagrant/www/koushik.php ubuntu/trusty64:/usr/share/nginx/html I am trying to copy files into the nginx root directory. It says, The machine with the name 'C' was not found configured for this Vagrant environment. The directory and everything is fine.Cussed
One thing to add: You have to use the ID of the machine that you can get with vagrant global-status in the first column. Nontheless, this is the best solution imho.Walachia
This did not work for me as I have multiple VMS and for some reason there were issues even after specifying the VM name. What I wound up doing is hosting the file as a URL and downloading it.Sharpeyed
@KoushikDas Doesn't work out of the box on windows. You have to enable the Ubuntu subsystem on windows 10, and then instead of putting C:/.. for the path to the file, you put /mnt/c/... And works hooray! Also note the other comment, use vagrant global-status to get the id of the vagrant machine.Zusman
I had a "Conflicting dependency" fog-core issue, solution: wget -c https://releases.hashicorp.com/vagrant/2.0.3/vagrant_2.0.3_x86_64.deb then sudo dpkg -i vagrant_2.0.3_x86_64.deb, I found the solution here: tutorials.technology/solved_errors/…Araxes
vagrant 2.2.6 works fine with this command it automatically adds localhost ip on port 2222 in the lists of known hosts: $ vagrant scp mongod.config mongod-m103:~/ Warning: Permanently added '[127.0.0.1]:2222' (ECDSA) to the list of known hosts. mongod.config 100% 331 512.2KB/s 00:00 Brannen
worked best for me. my use case was not to rebuild the VM, it was to get stuff in and out of it easily once it was running, so a file provisioner.... no. and /vagrant/ wasn't mounted for whatever reason. this does the trick and is bi-directional: host 2 guest, guest to host, but is running from the host command line. nifty.Maggio
N
170

There is actually a much simpler solution. See https://gist.github.com/colindean/5213685/#comment-882885:

"please note that unless you specifically want scp for some reason, the easiest way to transfer files from the host to the VM is to just put them in the same directory as the Vagrantfile - that directory is automatically mounted under /vagrant in the VM so you can copy or use them directly from the VM."

Nore answered 21/3, 2014 at 15:33 Comment(5)
This is exactly what my answer does... it runs a shell provisioner to copy the file from /vagrant/.Pyxis
Its better to use vagrant provisioning as LeexGreen have used.Rambo
Ensure that config.vm.synced_folder ".", "/vagrant", disabled: false and then vagrant reloadYakka
this does not work on the centos/7 vagrant box if trying to do the reverse operation (vagrant box to local machine).Mollescent
This works perfectly for me when copying a file from my Ubuntu 14 vagrant VM to my host. Thanks!!Mileage
M
141

Instead of using a shell provisioner to copy the file, you can also use a Vagrant file provisioner.

Provisioner name: "file"

The file provisioner allows you to upload a file from the host machine to the guest machine.

Vagrant.configure("2") do |config|
  # ... other configuration

  config.vm.provision "file", source: "~/.gitconfig", destination: ".gitconfig"
end
Marquismarquisate answered 25/4, 2014 at 20:15 Comment(4)
This is definitely the best way to do this in Vagrant 2! However, Vagrant 2 was not available at the time I needed to do this... :)Pyxis
This solution sounds nice, but i can't copy any file due to permission errors.Oscilloscope
@Oscilloscope I had the same problem, but not if I copied it to /tmpLadanum
this is not what the OP asked. the question was how to occasionally transfer files; having to run provisioning is overkill.Smithson
D
111

Introducing a method that does not require installing any plugins and eliminates the need to provide the private key (which can easily be forgotten):

By default, the first Vagrant instance uses port 2222 for SSH and its IP address is 127.0.0.1. (Please adjust the port if you have created multiple virtual hosts.)

==> default: Forwarding ports...
default: 22 (guest) => 2222 (host) (adapter 1)

With this setup, you can use the following command to copy your local file to the Vagrant instance in any desired path, not just the /vagrant folder. The password is the same as the username, which is vagrant

scp -P 2222 your_file [email protected]:.

You can also copy files back to your local host using the following command:

scp -P 2222 [email protected]:/PATH/filename
Dynasty answered 14/10, 2014 at 3:32 Comment(6)
I had to do this and disable strict key checking: scp -P 2222 -o UserKnownHostsFile=/dev/null -o StrictHostKeyChecking=no my-file.txt [email protected]:/tmpErythrism
I will recommend to add these ssh options into ~/.ssh/config as default, which I did it in my environment: StrictHostKeyChecking noDynasty
+1 + If one has more than one virtual machines the value of the port should be taken from the UI of the Oracle VM VirtualBox Manager - select vm on the left , settings , network , port forwardingZeena
This is better than the accepted answer. The /vagrant directory isn't always there.Pendentive
Surprising how much harder it is to get rsync to work in this case compared to scp, given rsync's description as a "faster, flexible replacement for rcp."Latonia
using -i .vagrant/machines/MY_VM/virtualbox/private_key works for meOlympian
B
74
vagrant upload localfile

that will put localfile in the vagrant user's home dir

https://www.vagrantup.com/docs/cli/upload.html

Bort answered 24/12, 2018 at 1:35 Comment(2)
This seems to fit the OPs request for easy one-off usage perfectly.Maracanda
Nice, easy and aligned with standard!Prakrit
A
65

Here is my approach to the problem:

Step 1 - Find the private key, ssh port and IP:

root@vivi:/opt/boxes/jessie# vagrant ssh-config
Host default
  HostName 127.0.0.1
  User vagrant
  Port 2222
  UserKnownHostsFile /dev/null
  StrictHostKeyChecking no
  PasswordAuthentication no
  IdentityFile /root/.vagrant.d/insecure_private_key
  IdentitiesOnly yes
  LogLevel FATAL

Step 2 - Transfer file using the port and private key as parameters for scp:

  scp -P 2222 -i /root/.vagrant.d/insecure_private_key \
  someFileName.txt [email protected]:~

I hope it helps,

Agha answered 1/8, 2015 at 18:10 Comment(4)
This is the simplest way. Thank you.Despond
Using the key allowed me to transfer the file. The higher answer without this information didn't work, so thank you!Ostrander
Easy and complete solution.Radie
I found that most of the vagrant config could be copied to ~/.ssh/config. So it can be put under an alias for future use. E.g. scp someFileName.txt vagrant_box:~Vaso
P
27

What I ended up doing was to keep the file within my vagrant directory (automatically mounted as /vagrant/) and copy it over with a shell provisioner:

command = "cp #{File.join('/vagrant/', path_within_repo)} #{remote_file}"
config.vm.provision :shell, :inline => command
Pyxis answered 23/5, 2013 at 5:3 Comment(4)
I'd recommend using coreutils install e.g. install -D -m644 -C ... src dest. instead of cp, because you can do things like specify the permissions, ownership, automatically create leading directories, only do the copy if the file needs to be updated, etc... instead of cp, which is simple and fine if that's all you need to do.Ivett
@LeeXGreen. I'm trying to to do the same thing you were trying to do but I don't quite get your answer. Did you type that line of code in the terminal? Where exactly did you place that?Womera
The code snippet from my answer goes in your Vagrantfile alongside your other provisioners. You'll need to replace path_within_repo and remote_file with things that make sense, for your application, of course :)Pyxis
Works but I get " default: stdin: is not a tty" errorSopher
H
22

If you are restrained from having the files in your directory, you can run this code in a script file from the Host machine.

#!/bin/sh
OPTIONS=`vagrant ssh-config | awk -v ORS=' ' '{print "-o " $1 "=" $2}'`

scp ${OPTIONS} /File/To/Copy vagrant@YourServer:/Where/To/Put/File

In this setup, you only need to change /File/To/Copy to the file or files you want to copy and then /Where/To/Put/File is the location on the VM you wish to have the files copied to.

If you create this file and call it copyToServer.sh you can then run the sh command to push those files.

sh ./copyToServer.sh

As a final note, you cannot run this code as a provisioner because that runs on the Guest server, while this code runs from the Host.

Hanfurd answered 24/4, 2014 at 20:43 Comment(4)
This is probably the best solution outside of installing the vagrant-scp plugin. It uses the SSH configuration that Vagrant uses so it can handle the different network setups provided by different providers.Clackmannan
Nice! I suggest you also note that people can simply take the output of vagrant ssh-config and paste it into their ~/.ssh/config file, to make this even easier in the future. I.e. combining this with chf's answerLoney
I have found it necessary to skip the first line of the ssh-config output to avoid the error "Host directive not supported as a command-line option" -- caused by the header for the ssh-config section: "Host default". So, my script has OPTIONS=`vagrant ssh-config | tail -n +2 | awk -v ORS=' ' '{print "-o " $1 "=" $2}'` to omit using that first line of ssh-config output.Vonvona
Alternatively, to remove the "Host directive not supported" error you can use OPTIONS=`vagrant ssh-config | grep -v '^Host ' | awk -v ORS=' ' 'NF{print "-o " $1 "=" $2}'` as documented here: gist.github.com/geedew/11289350Pung
D
13

All the above answers might work. But Below is what worked for me. I had multiple vagrant host: host1, host2. I wanted to copy file from ~/Desktop/file.sh to host: host1 I did:

    $vagrant upload ~/Desktop/file.sh host1

This will copy ~/Desktop/file.sh under /home/xxxx where xxx is your vagrant user under host1

Dexterous answered 25/10, 2020 at 17:54 Comment(0)
S
12

Vagrant provides a way to execute a command over ssh instead of logging in, so for Linux host and guest you can use:

  • from host to guest:

cat ~/file_on_host.txt | vagrant ssh -c 'cat - > ~/file_on_guest.txt'

  • from guest to host:

vagrant ssh -c 'cat ~/file_on_guest.txt' > ~/file_on_host.txt

No need for plugins or guest reloads. Just make sure to provide vagrant box ID to 'vagrant ssh' if you are not in the same dir as the Vagrantfile. Tested on Vagrant v1.8.1.

Salute answered 4/5, 2017 at 10:53 Comment(1)
From guest to host approach doesn't preserve special symbols in filesBoykins
Q
9

You can add entry in ~/.ssh/config:

Host vagrant
    User vagrant
    HostName localhost
    Port 2222
    IdentityFile /home/user_name/.vagrant.d/insecure_private_key

and the simplescp file vagrant:/path/. You can find path to identity file using the vagrant ssh-config command.

Quinquefid answered 30/1, 2015 at 13:26 Comment(2)
Very helpful, and helps clarify what is going on. This lets you copy both directions, do recursive copies, etc. and leverages existing knowledge of scp / ssh nicelyLoney
I just re-read the answers above and discovered by playing wiht geedew's answer that vagrant ssh-config gives you an even more complete and convenient config snipped that you can put in your ~/.ssh/config. But thanks again!Loney
C
8

Go to the directory where you have your Vagrantfile
Then, edit your Vagrantfile and add the following:

config.vm.synced_folder ".", "/vagrant", :mount_options => ['dmode=774','fmode=775']

"." means the directory you are currently in on your host machine
"/vagrant" refers to "/home/vagrant" on the guest machine(Vagrant machine).

Copy the files you need to send to guest machine to the folder where you have your Vagrantfile Then open Git Bash and cd to the directory where you have your Vagrantfile and type:

vagrant scp config.json XXXXXXX:/home/vagrant/

where XXXXXXX is your vm name. You can get your vm name by running

vagrant global-status
Cahilly answered 3/11, 2016 at 18:59 Comment(0)
P
8

if for some reasons you don't have permission to use

vagrant plugin install vagrant-scp

there is an alternative way :

First vagrant up yourVagrantProject, then write in the terminal :

vagrant ssh-config

you will have informations about "HostName" and "Port" of your virtual machine.

In some case, you could have some virtual machines in your project. So just find your master-machine (in general, this VM has the port 2222 ), and don't pay attention to others machines informations.

write the command to make the copy :

scp -P xxPortxx  /Users/where/is/your/file.txt  vagrant@xxHostNamexx:/home/vagrant

At this steep you will have to put a vagrant password : by default it's "vagrant"

after that if you look at files in your virtual machine:

vagrant ssh xxVirtualMachineNamexx
pwd
ls

you will have the "file.txt" in your virtual machine directory

Pendragon answered 3/3, 2017 at 11:2 Comment(2)
after putting in vagrant password I'm getting "Permission denied"Factual
but this was due to permissions on the target dir. I copied to /home/vagrant and that did work.Factual
A
5

vagrant scp plugin works if you know your vagrant box name. check vagrant global-status which will provide your box name then you can run:

vagrant global-status
id       name    provider   state   directory
------------------------------------------------------------------------
13e680d  **default** virtualbox running /home/user

vagrant scp ~/foobar "name in my case default":/home/"user"/

Aubreyaubrie answered 11/8, 2016 at 8:25 Comment(1)
this worked for me. the edit is also helpful, i would also include the command to install the vagrant scp plugin.Transhumance
E
2

An alternative way to do this without installing anything (vagrant-scp etc.) Note that the name default needs to be used as is, since vagrant ssh-config emits that.

vg_scp() {
  tmpfile=$(mktemp /tmp/vagrant-ssh-config.XXXX)
  vagrant ssh-config > $tmpfile
  scp -F $tmpfile "$@"
  rm $tmpfile
}

# Copy from local to remote
vg_scp somefile default:/tmp

# Copy from remote to local
vg_scp default:/tmp/somefile ./

# Copy a directory from remote to local
vg_scp -r default:/tmp ./tmp

The function would not be necessary if scp -F =(vagrant ssh-config) ... would have worked across shells. But since this is not supported by Bash, we have to resort to this workaround.

Ethelind answered 20/7, 2018 at 16:55 Comment(0)
P
2

If someone wants to transfer file from windows host to vagrant, then this solution worked for me.

1. Make sure to install **winscp** on your windows system
2. run **vagrant up** command
3. run **vagrant ssh-config** command and note down below details
4. Enter Hostname, Port, Username: vagrant, Password: vagrant in winscp and select **SCP**, file protocol 
5. In most cases, hostname: 127.0.0.1, port: 2222, username: vagrant, password: vagrant.

You should be able to see directories in your vagrant machine.

Pitts answered 25/10, 2018 at 23:32 Comment(0)
E
1

Try this.. vagrant ubuntu 14.04 This worked for me.

scp -r -P 2222 vagrant@localhost:/home .
Elephant answered 6/12, 2017 at 17:58 Comment(0)
K
1

If you "cd .." enough times you will find the vagrant folder which contains all your host files and folder

Kiel answered 14/7, 2022 at 21:56 Comment(0)
S
0

The best ans for me is to write the file / directory(to be copied) to the vagrant file directory, now any file present there is available to vagrant in path /vagrant.

That's it, no need of scp or any other methods,

similarly you can copy any file from VM to host by pasting in /vagrant directory.

Scripture answered 3/8, 2020 at 8:11 Comment(0)
B
-3

Best way to copy file from local to vagrant, No need to write any code or any thing or any configuration changes. 1- First up the vagrant (vagrant up) 2- open cygwin 3- cygwin : go to your folder where is vagrantfile or from where you launch the vagrant 4- ssh vagrant 5- now it will work like a normal system.

Buhrstone answered 10/8, 2017 at 11:2 Comment(1)
One problem I've discovered with this approach: if vagrant needs to configure your Guest Additions, the /vagrant directory may not actually be mounted when the file provisioner runs.Nottage

© 2022 - 2024 — McMap. All rights reserved.