Reputation: 513
I'm trying trying to run my project with all dependencies inside docker but I got stuck with grunt dependency, for some reason grunt fails with an error that it can't find local grunt.
I created an example of how to reproduce this:
.
├── 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 ...
after installation, it fails when tries to run the grunt
command I specified in my docker-compose.yml
file with this error:
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
actually does include grunt
as a dependency so it should be installed after RUN npm install
.
Upvotes: 6
Views: 4085
Reputation: 513
I think I found the reason why node_modules
and bower_components
are not created in the docs.
Note: If any build steps change the data within the volume after it has been declared, those changes will be discarded.
While I don't have VOLUME
declared in my dockerfile, I do have volumes
in my docker-compose.yml
so I suspect this note is affecting me because both npm install
& bower install
build steps do touch data within the volume.
I removed those build steps from the dockerfile and did them manually after build is complete:
$ docker-compose build
$ docker-compose run --rm frontend npm install
$ docker-compose run --rm frontend bower install
However, I encountered problem with permissions when running those commands above, since my newly created user did not have permissions to write to host and I didn't want to run as root inside container (bower for example will not like it without --allow-root)
The solution is to create user with the same UID and GID as the host.
I found that docker allows variable substitution and build arguments that means you don't have to hardcode UID and GID inside docker-compose.yml
, instead, they can be taken from host env variables like so and can be accessed during the build.
$ 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
Upvotes: 1
Reputation: 13109
Do a docker exec -it <nameofyourcontainer> bash
and look into node_modules
if grunt is installed locally.
Did you set NODE_ENV
to production
somewhere?
This causes npm
to not install devDepedencies
.
Upvotes: 3