Install a new node dependency inside a Docker container

Viewed 2814

Considering the following development environment with Docker:

# /.env
CONTAINER_PROJECT_PATH=/projects/my_project

# /docker-compose.yml
version: '2'
services:
  web:
    restart: always
    build: ./docker/web
    working_dir: ${CONTAINER_PROJECT_PATH}
    ports:
      - "3000:3000"
    volumes:
      - .:${CONTAINER_PROJECT_PATH}
      - ./node_modules:${CONTAINER_PROJECT_PATH}/node_modules

# /docker/web/Dockerfile
FROM keymetrics/pm2:latest-alpine
FROM node:8.11.4

ENV NPM_CONFIG_PREFIX=/home/node/.npm-global

RUN mkdir -p /projects/my_project
RUN chown node:node /projects/my_project

# If you are going to change WORKDIR value, 
# please also consider to change .env file
WORKDIR /projects/my_project

USER node
RUN npm install pm2 -g
CMD npm install && node /projects/my_project/src/index.js

How do I install a new module inside my container? npm install on host won't work because of node_module belongs to the root user. Is there any way to run it from the container?

Edit: Is there something "one-liner" that I could run outside the container to install a module?

3 Answers

Assuming you don't mean to edit the Dockerfile, you can always execute a command on a running container with the -it flag:

$ docker run -it <container name> /usr/bin/npm install my_moduel

First access inside container:

$ docker exec -it <container name> /bin/bash

Then inside container:

$ npm install pm2 -g

You either

  • a) want to install pm2 globally, which you need to run as root, so place your install before USER node so that you instead run at the default user (root), or
  • b) you just want to install pm2 to use in your project, in which case just drop the -g flag which tells npm to install globally, and it will instead be in your project node_modules, and you can run it with npx pm2 or node_modules/.bin/pm2, or programmatically from your index.js (for the latter I'd suggest adding it to your package.json and no manually installing it at all).
Related