I have the following Dockerfile for a React app:
# base image FROM node:11.12.0-alpine # set working directory WORKDIR /usr/src/app # add `/usr/src/app/node_modules/.bin` to $PATH ENV PATH /usr/src/app/node_modules/.bin:$PATH # install and cache app dependencies COPY package.json /usr/src/app/package.json COPY package-lock.json /usr/src/app/package-lock.json RUN npm install email@example.com -g --silent RUN chown -R node:node . USER node RUN npm ci # start app CMD ["npm", "start"]
After setting up the work directory I copy the
package-lock.json to Docker. Then I install a global package (
react-scripts). After that, I switch the owner of the working directory to the non-root user
Then I install the rest of the packages with
npm ci as a normal user and start the app.
What happens when I want to add another package to my dependencies?⌗
When I try to install a package locally, I get permission errors:
Missing write access to services/client/node_modules errno -13 Error: EACCESS: permission denied, access 'services/client/node_modules'
What happens when I update
package.json and then run
npm ERR! cipm can only install packages when your package.json and package-lock.json or npm-shrinkwrap.json are in sync. Please update your lock file with `npm install` before continuing.
npm ci installs packages from a clean slate and relies on
This command is similar to npm-install, except it’s meant to be used in automated environments such as test platforms, continuous integration, and deployment – or any situation where you want to make sure you’re doing a clean install of your dependencies. It can be significantly faster than a regular npm install by skipping certain user-oriented features. It is also more strict than a regular install, which can help catch errors or inconsistencies caused by the incrementally-installed local environments of most npm users.
Install the npm package via Docker/docker-compose. For example:
docker-compose run --rm client sh -c 'npm install'
(You can see my
docker-compose.yml file on GitHub.)
Then rebuild the docker images and run them:
docker-compose up -d --build