简体   繁体   中英

NPM install in Vagrant shared folder leads to filesystem issues

A Vagrant VM is mandatory to have the project environment. In this VM, a Docker repository provides all the containers we need to make the API I work on operational. No issues until I installed the frontal Angular app.

This app is using NPM, Bower, Gulp... So the CLI container implements NVM, NodeJS and NPM. The container successfully builds, but when I launch a npm install , I experience hardware issues.

The outputs I get during modules installation tell things such as :

gyp WARN install got an error, rolling back install
gyp ERR! configure error
gyp ERR! stack Error: EROFS: read-only file system, mkdir '/root/.node-gyp'
gyp ERR! stack     at Error (native)
gyp ERR! System Linux 4.4.0-59-generic
gyp ERR! command "/usr/local/nvm/versions/node/v6.9.5/bin/node" "/srv/apps/my-angular-app/node_modules/.bin/node-gyp" "rebuild"
gyp ERR! cwd /srv/apps/my-angular-app/node_modules/ttf2woff2
gyp ERR! node -v v6.9.5
gyp ERR! node-gyp -v v3.5.0
gyp ERR! not ok

or

PhantomJS not found on PATH
/tmp/phantomjs is not writable: EROFS: read-only file system, mkdir '/tmp/phantomjs'

After the npm install command , the Docker container and the VM filesystems are completely blown up. Whatever action I try to do, I have a filesystem error. A simple ls outputs the following :

bash: /bin/ls: Input/output error

And when i try to autocomplete a command with tab:

-bash: cannot create temp file for here-document: Read-only file system

To make it work again I have to perform a VM reboot.

My clue is that NPM tries to make symlinks, which makes the system fail due to Windows. Indeed, the project is located in a Vagrant shared folder, and I think making symlinks here is a risky thing. But I do not understand that because my Nginx container does the same (with sites-available/ to sites-enable/ links. I fail to see the problem. I searched for answers but it doesn't seem related to issues such as this

Configurations

Vagrantfile

# -*- mode: ruby -*-
# vi: set ft=ruby :
require './config'
# Specify Vagrant version and Vagrant API version
Vagrant.require_version ">= 1.6.0"
VAGRANTFILE_API_VERSION = "2"

# Create and configure the VM(s)
Vagrant.configure(VAGRANTFILE_API_VERSION) do |config|

  # Forward the ports between the host machine and the box
  config.vm.network "forwarded_port", guest: 80, host: 80
  config.vm.network "forwarded_port", guest: 443, host: 443
  config.vm.network "forwarded_port", guest: 8000, host: 8000
  config.vm.network "forwarded_port", guest: 8082, host: 8082
  config.vm.network "forwarded_port", guest: 8888, host: 8888
  config.vm.network "forwarded_port", guest: 9000, host: 9000
  config.vm.network "forwarded_port", guest: 9001, host: 9001
  # Create a private network, which allows host-only access to the machine
  # using a specific IP.
  config.vm.network "private_network", ip: VAGRANT_CONFIG['ip']

  # Assign a friendly name to this host VM
  config.vm.hostname = "docker-host"

  # Skip checking for an updated Vagrant box
  config.vm.box_check_update = false

  # SSH agent forwarding
  config.ssh.forward_agent = false

  # Spin up a "host box" for use with the Docker provider
  # and then provision it with Docker
  config.vm.box = "ubuntu/xenial64"
  config.vm.provision "docker"

  # Share an additional folder to the guest VM. The first argument is
  # the path on the host to the actual folder. The second argument is
  # the path on the guest to mount the folder. And the optional third
  # argument is a set of non-required options.
  # config.vm.synced_folder "../data", "/vagrant_data"
  # argument is a set of non-required options.
  if VAGRANT_CONFIG['synced_folder'] == true
      if VAGRANT_CONFIG['nfs'] == true
        #config.nfs.map_uid = Process.uid
        #config.nfs.map_gid = Process.gid
        config.vm.synced_folder "share", "/home/ubuntu/data", type: 'nfs', nfs_udp: VAGRANT_CONFIG['nfs_udp']
      else
        config.vm.synced_folder "share", "/home/ubuntu/data"
      end
      #config.vm.synced_folder "www", "/home/vagrant/www", type: 'smb', smb_username: '', smb_password: '', mount_options: [""]
  end

  # Provider-specific configuration so you can fine-tune various
  # backing providers for Vagrant. These expose provider-specific options.
  # Example for VirtualBox:
  #
  config.vm.provider "virtualbox" do |vb|
    # Display the VirtualBox GUI when booting the machine
    # vb.gui = true

    # Customize the amount of memory on the VM:
    vb.memory = VAGRANT_CONFIG['memory']
    vb.cpus = VAGRANT_CONFIG['cpu']
    vb.name = "my-docker-vm"
  end

  config.vm.provider "vmware_fusion" do |v|
    v.vmx["memsize"] = VAGRANT_CONFIG['memory']
    v.vmx["numvcpus"] = VAGRANT_CONFIG['cpu']
    v.name = "my-docker-vm"
  end

  config.vm.provider "vmware_workstation" do |v|
    v.vmx["memsize"] = VAGRANT_CONFIG['memory']
    v.vmx["numvcpus"] = VAGRANT_CONFIG['cpu']
    v.name = "my-docker-vm"
  end

  config.vm.provision "file", source: "data", destination: "/home/ubuntu/install"

  config.vm.provision "shell", path: "scripts/install.sh"

  # Disable synced folders (prevents an NFS error on "vagrant up")
  config.vm.synced_folder ".", "/ubuntu", disabled: true
end

docker-compose.yml (CLI container)

cli:
    container_name: cli_container
    build: cli
    volumes:
        - "./volumes/apps:/srv/apps"
    stdin_open: true
    tty: true
    environment:
        - PHP_EXTRA_CONFIGURE_ARGS=--with-ldap
    links:
        - mysql:mysql
        - redis:redis
        - rabbitmq:rabbitmq
        - mailer:mailer
        - blackfire:blackfire

CLI container Dockerfile

FROM php:cli

RUN rm /bin/sh && ln -s /bin/bash /bin/sh

COPY config/ssh/* /root/.ssh/
RUN chmod 600 /root/.ssh/id_rsa*

COPY config/php.ini /usr/local/etc/php/
COPY config/supervisord.conf /etc/supervisor/conf.d/supervisord.conf
COPY config/symfony_environment.sh /usr/local/etc/symfony_environment.sh
COPY docker-entrypoint.sh /entrypoint.sh

RUN chmod a+x /entrypoint.sh && chown root:root /entrypoint.sh

RUN cat /usr/local/etc/symfony_environment.sh >> /etc/bash.bashrc

RUN apt-get update
RUN apt-get upgrade -y
RUN apt-get install -y wget git python-pip libmcrypt-dev libldb-dev libldap2-dev zlib1g-dev dos2unix build-essential libssl-dev
RUN dos2unix /entrypoint.sh
RUN apt-get --purge remove -y dos2unix
RUN rm -rf /var/lib/apt/lists/*

# nvm environment variables
ENV NVM_DIR /usr/local/nvm
ENV NODE_VERSION 6.9.5

# install nvm
# https://github.com/creationix/nvm#install-script
RUN curl --silent -o- https://raw.githubusercontent.com/creationix/nvm/v0.33.0/install.sh | bash

# install node and npm
RUN source $NVM_DIR/nvm.sh \
    && nvm install $NODE_VERSION \
    && nvm alias default $NODE_VERSION \
    && nvm use default

# add node and npm to path so the commands are available
ENV NODE_PATH $NVM_DIR/v$NODE_VERSION/lib/node_modules
ENV PATH $NVM_DIR/versions/node/v$NODE_VERSION/bin:$PATH

RUN npm install -g gulp bower

RUN pip install --upgrade pip
RUN pip install supervisor

RUN docker-php-ext-configure ldap --with-libdir=lib/x86_64-linux-gnu/
RUN docker-php-ext-install -j$(nproc) mcrypt zip bcmath ldap pdo pdo_mysql

RUN pecl install redis-3.1.0 && docker-php-ext-enable redis
RUN pecl install apcu-5.1.7 \
    && echo extension=apcu.so > /usr/local/etc/php/conf.d/apcu.ini

VOLUME /srv/apps
WORKDIR /srv/apps

ENTRYPOINT ["/entrypoint.sh"]

CMD ["/usr/local/bin/supervisord", "-c", "/etc/supervisor/conf.d/supervisord.conf"]

I did not really understand what fixed it, but now everything is working fine !

I think that it was simply a cache problem for NPM.

In fact, when I installed the Node stack in my container, I took the latest version. And then, later, I changed it to take the LTS version, and removed the container to build it again. I think these problems came from conflicts between the LTS version and the latest version cache.

So the probable solution is :

npm cache clean

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM