在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_modules
和bower_components
不是在文档中创build的原因。
注意:如果任何构build步骤在声明之后更改了卷中的数据,则这些更改将被丢弃。
虽然我没有在我的dockerfile中声明VOLUME
但是我在docker docker-compose.yml
有volumes
,所以我怀疑这个注释正在影响我,因为npm install
& bower 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