Search code examples
nginxubuntu-16.04vagrantfile

Vagrant: config.vm.provision does not allow me to copy a file to etc/nginx/conf.d?


I am working with a Nginx server. I want to copy a configuration file to /etc/nginx/conf.d with the Vagrantfile. The command I use is:

config.vm.provision "file", source: "./bolt.local.conf", destination: "/etc/nginx/conf.d/bolt.local.conf"

The error I receive is:

Failed to upload a file to the guest VM via SCP due to a permissions
error. This is normally because the SSH user doesn't have permission
to write to the destination location. Alternately, the user running
Vagrant on the host machine may not have permission to read the file.

I am using the bento/ubuntu-16.04 box.

I tried to search for a way to change the permissions for the provision command but I only found ways to change the owner for the config.vm.share_folder command.

Do you know the answer?


Solution

  • As the error message suggest and also from the documentation:

    The file uploads by the file provisioner are done as the SSH or PowerShell user. This is important since these users generally do not have elevated privileges on their own. If you want to upload files to locations that require elevated privileges, we recommend uploading them to temporary locations and then using the shell provisioner to move them into place.

    So the vagrant user(if not modified) is used to scp the file but you can't access /etc/ with it.

    To make it work you need to upload it to a temporary location and then use a shell provisioner to move it to target directory:

    config.vm.provision "file", 
      source: "./bolt.local.conf", 
      destination: "/tmp/bolt.local.conf"
    
    config.vm.provision "shell",
      inline: "mv /tmp/bolt.local.conf /etc/nginx/conf.d/bolt.local.conf"
    

    This work because the privileged option is true by default on shell provisioners. But it is a bit convoluted to have two provisioners just to copy a configuration file, right ?

    Well if the file is already inside your share folder you can just use a shell provisioner to copy it in the nginx directory so you'll end up with something like this:

    # This is the default and serve just as a reminder
    config.vm.synced_folder ".", "/vagrant"
    config.vm.provision "shell",
      inline: "cp /vagrant/bolt.local.conf /etc/nginx/conf.d/bolt.local.conf"