jean d'arme
jean d'arme

Reputation: 4353

Dockerizing Node.js app - what does: ENV PATH /app/node_modules/.bin:$PATH

I went through one of very few good dockerizing Vue.js tutorials and there is one thing I don't understand why is mandatory in Dockerfile:

# add `/app/node_modules/.bin` to $PATH
ENV PATH /app/node_modules/.bin:$PATH
COPY package.json /usr/src/app/package.json #not sure though how it relates to PATH...

I found only one explanation here which says:

We expose all Node.js binaries to our PATH environment variable and copy our projects package.json to the app directory. Copying the JSON file rather than the whole working directory allows us to take advantage of Docker’s cache layers.

Still, it doesn't made me any smarter. Anyone able to explain it in plain english?

Upvotes: 9

Views: 10174

Answers (4)

winklerrr
winklerrr

Reputation: 14807

Error prevention

I think this is just a simple method of preventing an error where Docker wasn't able to find the correct executables (or any executables at all). Besides adding another layer to your image, there is in general as far as I know no downside in adding that line to your Dockerfile.

How does it work?

Adding node_modules/bin to the PATH environment variable ensures that the executables created during the npm build or the yarn build processes can be found. You could also COPY your locally builded node_modules folder to the image but it's advised to build it inside the Docker container to ensure all binaries are adapted to the underlying OS running in the container. The best practice would be to use multistage builds.

Furthermore, adding the node_modules/bin at the beginning of the PATH environment variable ensures that exactly these executables (from the node_modules folder) are used instead of any other executables which might also be installed on the system inside the Docker image.

Do I need it?

Short answer: Usually no. It should be optional.

Long answer: It should be enough to set the WORKDIR to the path where the node_modules is located for the issued RUN, CMD or ENTRYPOINT commands in your Dockerfile to find the correct binaries and therefore to successfully get executed. But I for example had a case where Docker wasn't able to find the files (I had a pretty complex setup with a so called devcontainer in VSCode). Adding the line ENV PATH /app/node_modules/.bin:$PATH solved my problem.

So, if you want to increase the stability of your Docker setup in order to make sure that everything works as expected, just add the line.

Upvotes: 9

rickyc
rickyc

Reputation: 57

.bin (short for 'binaries') is a hidden directory, the period before the bin indicates that it is hidden. This directory contains executable files of your app's modules.

PATH is just a collection of directories/folders that contains executable files. When you try to do something that requires a specific executable file, the shell looks for it in the collection of directories in PATH.

ENV PATH /app/node_modules/.bin:$PATH adds the .bin directory to this collection, so that when node tries to do something that requires a specific module's executable, it will look for it in the .bin folder.

Upvotes: 2

Richard Oliver Bray
Richard Oliver Bray

Reputation: 1123

So I think the benefit of this line is to add the node_modules path from the Docker container to the list of PATHs on the relevant container. If you're on a Mac (or Linux I think) and run:

$ echo $PATH  

You should see a list of paths which are used to run global commands from your terminal i.e. gulp, husky, yarn and so on.

The above command will add node_modules path to the list of PATHs in your docker container so that such commands if needed can be run globally inside the container they will work.

Upvotes: 5

Mauro Baraldi
Mauro Baraldi

Reputation: 6575

For each command, like FROM, COPY, RUN, CMD, ..., Docker creates a image with the result of this command, and this images are called as layers. The final image is the result of merge of all layers.

If you use the COPY command to store all the code in one layer, it will be greater than store a environment variable with path of the code.

That's why the cache layers is a benefit.

For more info about layers, take a look at this very good article.

Upvotes: 2

Related Questions