在docker中运行grunt时出错:致命错误:无法find本地grunt

我试图运行我的项目与泊坞子内的所有依赖关系,但我坚持与咕噜依赖,出于某种原因咕噜声失败,它无法find本地咕噜声的错误。

我创build了一个如何重现这个例子:

. ├── code │  ├── bower.json │  ├── Gruntfile.js │  └── package.json ├── docker-compose.yml └── frontend.dockerfile 

docker-compose.yml

 version: "2" services: frontend: build: context: . dockerfile: frontend.dockerfile ports: - "8585:8000" volumes: - ./code:/srv/frontend command: grunt 

frontend.dockerfile

 FROM node:wheezy ADD code /srv/frontend WORKDIR /srv/frontend RUN npm install -g grunt-cli bower RUN npm install RUN groupadd -r usergroup && useradd -m -r -g usergroup user RUN chown -R user:usergroup /srv/frontend USER user RUN bower install 

bower.json

 { "name": "code", "description": "", "main": "index.js", "authors": [ "Mr. No One" ], "license": "ISC", "homepage": "", "ignore": [ "**/.*", "node_modules", "bower_components", "test", "tests" ], "dependencies": { "angular": "^1.5.8" } } 

Gruntfile.json

 module.exports = function(grunt) { grunt.initConfig({}); // tasks grunt.registerTask('default', []); }; 

package.json

 { "name": "code", "version": "1.0.0", "description": "", "main": "index.js", "scripts": { "test": "echo \"Error: no test specified\" && exit 1" }, "author": "", "license": "ISC", "devDependencies": { "grunt": "^1.0.1" } } 

$ docker-compose up ... installing all dependencies ...安装后,尝试运行我在docker-compose.yml文件中指定的grunt命令时失败,

 frontend_1 | grunt-cli: The grunt command line interface (v1.2.0) frontend_1 | frontend_1 | Fatal error: Unable to find local grunt. frontend_1 | frontend_1 | If you're seeing this message, grunt hasn't been installed locally to frontend_1 | your project. For more information about installing and configuring grunt, frontend_1 | please see the Getting Started guide: frontend_1 | frontend_1 | http://gruntjs.com/getting-started 

package.json实际上确实包含了grunt作为依赖,所以它应该在RUN npm install之后RUN npm install

如果grunt本地安装,请docker exec -it <nameofyourcontainer> bash并查看node_modules

您是否将NODE_ENV设置为某个地方的产品? 这会导致npm不能安装devDepedencies

我想我find了为什么node_modulesbower_components不是在文档中创build的原因。

注意:如果任何构build步骤在声明之后更改了卷中的数据,则这些更改将被丢弃。

虽然我没有在我的dockerfile中声明VOLUME但是我在docker docker-compose.ymlvolumes ,所以我怀疑这个注释正在影响我,因为npm installbower install构build步骤都是在卷内部触摸数据。

我从dockerfile中删除了这些构build步骤,并在构build完成后手动完成:

 $ docker-compose build $ docker-compose run --rm frontend npm install $ docker-compose run --rm frontend bower install 

但是,我在运行上面的这些命令时遇到了权限问题,因为我新创build的用户没有写入主机的权限,而且我也不想在容器内以root身份运行(例如,bower不会在没有–allow -根)

解决scheme是使用与主机相同的UID和GID创build用户。

我发现docker允许variablesreplace和构build参数 ,这意味着您不必在docker-compose.yml对UID和GID进行硬编码,而是可以从主机envvariables中获取这些variables,并且可以在构build过程中访问这些variables。

 $ export HOST_UID=$(id -u) $ export HOST_GID=$(id -g) 

frontend.dockerfile

 FROM node:wheezy ARG hostuid ARG hostgid ADD code /srv/frontend WORKDIR /srv/frontend RUN npm install -g grunt-cli bower RUN groupadd -g "$hostgid" devgroup && useradd -m -u "$hostuid" -g devgroup developer RUN chown -R developer:devgroup /srv/frontend USER developer 

docker-compose.yml

 version: "2" services: frontend: build: context: . dockerfile: frontend.dockerfile args: - hostuid=${HOST_UID} - hostgid=${HOST_GID} ports: - "8585:8000" volumes: - ./code:/srv/frontend command: grunt