I have been encountering an issue with Vagrant machines and npm
. Files within the file-system suddenly become read-only
. In all cases, a synced directory, that contained a Git
repository, was involved.
The following is a provisioning setup that enables me to encounter the issue with. Both files are located in the root of a node-oriented Git
repository like the one found here.
# Vagrantfile API/syntax version. Don't touch unless you know what you're doing!
VAGRANTFILE_API_VERSION = "2"
Vagrant.configure(VAGRANTFILE_API_VERSION) do |config|
# Use host's SSH keys
config.ssh.forward_agent = true
# Get current directory name (presumably, repo dirname)
repo_dirname = File.basename(Dir.getwd)
# Set US locale
ENV['LC_ALL']="en_US.UTF-8"
# Ensures virtualbox can create symlinks in shared folders
config.vm.provider "virtualbox" do |vb|
vb.customize ["setextradata", :id,
"VBoxInternal2/SharedFoldersEnableSymlinksCreate/vagrant", "1"]
end
# Forward usual dev port through to host machine
config.vm.network :forwarded_port, guest: 3000, host: 3000
# Also forward production port just in case
config.vm.network :forwarded_port, guest: 80, host: 8080
# Forward a folder for the repo so that code can be worked on from outside the
# VM as usual
config.vm.synced_folder ".", "/home/ubuntu/#{repo_dirname}", create: true
config.vm.define "#{repo_dirname}-vm" do |repo_vm|
repo_vm.vm.box = "ubuntu/xenial64"
repo_vm.vm.host_name = "#{repo_dirname}-vm"
repo_vm.vm.provision :shell do |sh|
sh.path = "vagrant_provision.sh"
sh.privileged = false
sh.env = {
REPO_DIR: repo_dirname
}
end
end
end
#!/usr/bin/env bash
function set_locale() {
sudo locale-gen en.US
}
function get_builds() {
sudo apt-get update &&
sudo apt-get upgrade -y &&
sudo apt-get install -y curl build-essential
}
function get_n_installer() {
if [ -f n-install ]
then
echo "n installer already exists. Not downloading."
return 0
else
echo "n installer not found. Downloading..."
wget -L https://git.io/n-install
fi
}
function install_n() {
if [ -d "n" ]
then
echo "n install directory already exists. Not installing."
return 0
else
echo "n install directory not found. Installing..."
yes | bash n-install
fi
}
function add_github_keys() {
# Adds the github server key to known hosts
ssh-keyscan github.com >> ~/.ssh/known_hosts &&
return 0 || return 1
}
function add_n_to_path() {
# Added by n-install, but ignored by vagrant
export N_PREFIX="$HOME/n";
[[ :$PATH: == *":$N_PREFIX/bin:"* ]] || PATH+=":$N_PREFIX/bin"
}
function get_repo() {
if [ -d "$2" ]
then
echo "Destination directory $2 already exists. Deleting contents..."
rm -rfv ./$2
fi
echo "Cloning $1 into $2..."
git clone $1 $2
}
function install_npm_deps() {
echo "Installing npm dependencies..."
npm install
}
function rebuild_node_sass() {
# Needed because of https://github.com/sass/node-sass/issues/1579
npm rebuild node-sass
}
# . ~/.bashrc &&
set_locale &&
add_github_keys &&
get_builds &&
get_n_installer &&
install_n &&
add_n_to_path &&
cd $REPO_DIR &&
install_npm_deps &&
rebuild_node_sass &&
echo "Provisioned user is: $USER" &&
echo "Frontend provisioned. To run, type 'vagrant ssh'."
The main step that seems to cause a problem is the execution of npm install
by the unprivileged provisioner. Sometimes an archive unpacking error occurs, but other times, npm fails with ENOENT errors.
Upon logging in with vagrant ssh
to finish the job, read-only filesystem errors appear. Despite this, there is plenty of space on the system (say, 7 out of 8GB remaining).
Read-only filesystem errors also appear when the webpack server is running under the same circumstances.
There are questions and tickets floating around that quote similar errors, but I haven't seen any exploration into what the underlying mechanism is. What's the deal?
I managed to fix this issue by symlinking node_modules outside /vagrant shared folder i.e. /home/vagrant/node_modules:
mkdir /home/vagrant/node_modules
ln -sf /home/vagrant/node_modules /vagrant/
The downside of this is that you can't npm install anymore outside vagrant, only from inside (unless you mkdir /vagrant on your host machine).
I have been experiencing similar issues with Vagrant 1.8.7 and Virtualbox 5.1.10. I was able to fix the filesystem readonly problematic by reducing the number of cpu cores to 1:
config.vm.provider "virtualbox" do |v|
v.cpus = 1
end
Build issues are still occuring for me (npm modules not being found, ENOENT, ELIFECYCLE,...) but at a lesser rate. Unfortunately I have not been able to locate the root cause of these errors.
In my setup npm is not writing into the shared directory. If the write location is the shared folder you can try a different syncing mechanism that gets around some limitations of the virtualbox shared folder implementation.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With