Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How to keep node_modules inside container while using docker-compose and a non-root user?

I'm looking for a way to achieve these goals at the same time:

  • using a non-root user inside the container
  • keeping node_modules inside container (to not to "pollute" the working directory on the host)
  • not using a Dockerfile

I'm not sure if these goals are considered "best practice". For example, keeping node_modules inside the container has its disadvantages.

Currently my compose file is like this:

services:
  # ...

  node:
    image: "node:9"
    user: "node"
    working_dir: /home/node/app
    environment:
      # - NODE_ENV=production
      - NPM_CONFIG_PREFIX=/home/node/.npm-global
      - PATH=$PATH:/home/node/.npm-global/bin
    volumes:
      - ./proj/:/home/node/app
      - /home/node/app/node_modules # mark1
    ports:
      - "3001:3001"
    command: >
      bash -c "echo hello
      && ls -lh /home/node/app/ 
      && npm install
      && npm i -g babel-cli
      && npm i -g flow-bin
      && npm start"
    depends_on:
      - redis

but there's

"Error: EACCES: permission denied, access '/home/node/app/node_modules'".

If I comment out the #mark1 line, the container runs, however node_modules will be written onto the host (since ./proj is mounted)

I have read these two articles on the topic:

  • https://blog.getjaco.com/jaco-labs-nodejs-docker-missing-manual/
  • http://jdlm.info/articles/2016/03/06/lessons-building-node-app-docker.html

but neither meets my goal.

Update:

I added a line of ls -lh /home/node/app/ and found node_modules is owned by root. This could be the problem.

like image 648
LShi Avatar asked Apr 20 '18 12:04

LShi


People also ask

Where are node modules installed Docker?

yml. When I run docker-compose build , everything works as expected and all npm modules are installed in /worker/node_modules as I'd expect. Turns out none of the modules are present in /worker/node_modules (on host or in the container). If on the host, I npm install , then everything works just fine.

Does Docker compose run as root?

By default that Unix socket is owned by the user root and other users can only access it using sudo. The Docker daemon always runs as the root user .


1 Answers

I ended up using a Dockerfile. It's minimum. (I keep some commented out lines for anyone may find them useful.)

We need to change the owner of node_modules inside the container. It seems the node:9 image doesn't require this. So this is only for node:9-alpine. (update: Sorry. I forgot to remove the built container with docker system prune. Both images need this. Here is a discussion on permissions/ownership of named volumes`)

FROM node:9-alpine

#ENV NPM_CONFIG_PREFIX=/home/node/.npm-global
#ENV PATH=$PATH:/home/node/.npm-global/bin

RUN mkdir -p /home/node/app/node_modules
RUN chown -R node:node /home/node/app

#USER node

#WORKDIR /home/node/app

#RUN npm install --silent --progress=false ; \
#    npm i -g babel-cli --silent --progress=false ;\
#    npm i -g flow-bin --silent --progress=false

The docker-compose.yml ended up being like:

services:
  # ...
  node:
    # image: "node:9-alpine"
    build: ./proj
    user: "node"
    working_dir: /home/node/app
    environment:
      # - NODE_ENV=production
      - NPM_CONFIG_PREFIX=/home/node/.npm-global
      - PATH=$PATH:/home/node/.npm-global/bin
    volumes:
      - ./proj/:/home/node/app
      - /home/node/app/node_modules/
    ports:
      - "3006:3001"
    command: >
      /bin/sh -c "echo hello
      && ls -lh /home/node/app/
      && npm install
      && npm i -g babel-cli
      && npm i -g flow-bin
      && npm start"
    depends_on:
      - redis
like image 106
LShi Avatar answered Oct 14 '22 14:10

LShi