npm 的 Vagrant 文件系统问题

Vagrant filesystem issues with npm

我经常遇到 Vagrant 机器和 npm 的错误,其中文件系统突然变为只读。在所有情况下,都涉及包含 git 回购的同步目录。

这是我遇到过问题的配置设置。这两个文件都位于面向节点的 git 存储库的根目录中,例如 this one.

Vagrantfile

# 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

vagrant_provision.sh

#!/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 "" ]
    then
        echo "Destination directory  already exists. Deleting contents..."
        rm -rfv ./
    fi
    echo "Cloning  into ..."
    git clone  
}

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'."

似乎导致问题的主要步骤是由非特权提供者执行 npm install。有时 an archive unpacking error 会发生,但其他时候,npm 会因 ENOENT 错误而失败。

使用 vagrant ssh 登录完成作业后,出现只读文件系统错误。尽管如此,系统上仍有大量 space(例如,剩余 8GB 中的 7 个)。

同样情况下webpack server 运行也会出现只读文件系统错误

有很多问题和票据引用了类似的错误,但我还没有看到任何关于底层机制是什么的探索。怎么回事?

我在使用 Vagrant 1.8.7 和 Virtualbox 5.1.10 时遇到了类似的问题。我能够通过将 cpu 内核的数量减少到 1:

来解决文件系统只读问题
config.vm.provider "virtualbox" do |v|
  v.cpus = 1
end

我仍然会遇到构建问题(未找到 npm 模块、ENOENT、ELIFECYCLE 等),但发生率较低。不幸的是,我无法找到这些错误的根本原因。

在我的设置中,npm 没有写入共享目录。如果写入位置是共享文件夹,您可以尝试 a different syncing mechanism 来绕过 virtualbox 共享文件夹实现的一些限制。

我设法通过在 /vagrant 共享文件夹外链接 node_modules 来解决这个问题,即 /home/vagrant/node_modules:

mkdir /home/vagrant/node_modules
ln -sf /home/vagrant/node_modules /vagrant/

这样做的缺点是您不能再在 vagrant 外部安装 npm,只能从内部安装(除非您在主机上安装 mkdir /vagrant)。