How to cache the RUN npm install instruction when docker build a Dockerfile
.everyoneloves__top-leaderboard:empty,.everyoneloves__mid-leaderboard:empty,.everyoneloves__bot-mid-leaderboard:empty{ height:90px;width:728px;box-sizing:border-box;
}
I am currently developing a Node backend for my application.
When dockerizing it (docker build .) the longest phase is the RUN npm install
. The RUN npm install
instruction runes on every small server code change, impacting the productivity by making the developer wait for the build to finish each time.
I found that running npm install where the application code lives and adding the node_modules to the container with the ADD instruction solves this issue,
but it is far from best practice. It kind of breaks the whole idea of dockerizing it and it cause the container to weight much more.
Any other solution?
node.js docker dockerfile
add a comment |
I am currently developing a Node backend for my application.
When dockerizing it (docker build .) the longest phase is the RUN npm install
. The RUN npm install
instruction runes on every small server code change, impacting the productivity by making the developer wait for the build to finish each time.
I found that running npm install where the application code lives and adding the node_modules to the container with the ADD instruction solves this issue,
but it is far from best practice. It kind of breaks the whole idea of dockerizing it and it cause the container to weight much more.
Any other solution?
node.js docker dockerfile
add a comment |
I am currently developing a Node backend for my application.
When dockerizing it (docker build .) the longest phase is the RUN npm install
. The RUN npm install
instruction runes on every small server code change, impacting the productivity by making the developer wait for the build to finish each time.
I found that running npm install where the application code lives and adding the node_modules to the container with the ADD instruction solves this issue,
but it is far from best practice. It kind of breaks the whole idea of dockerizing it and it cause the container to weight much more.
Any other solution?
node.js docker dockerfile
I am currently developing a Node backend for my application.
When dockerizing it (docker build .) the longest phase is the RUN npm install
. The RUN npm install
instruction runes on every small server code change, impacting the productivity by making the developer wait for the build to finish each time.
I found that running npm install where the application code lives and adding the node_modules to the container with the ADD instruction solves this issue,
but it is far from best practice. It kind of breaks the whole idea of dockerizing it and it cause the container to weight much more.
Any other solution?
node.js docker dockerfile
node.js docker dockerfile
edited Mar 3 '16 at 14:22
ohadgk
asked Mar 3 '16 at 14:19
ohadgkohadgk
1,2581610
1,2581610
add a comment |
add a comment |
5 Answers
5
active
oldest
votes
Ok so I found this great article about efficiency when writing a docker file.
This is an example of a bad docker file adding the application code before running the RUN npm install
instruction:
FROM ubuntu
RUN echo "deb http://archive.ubuntu.com/ubuntu precise main universe" > /etc/apt/sources.list
RUN apt-get update
RUN apt-get -y install python-software-properties git build-essential
RUN add-apt-repository -y ppa:chris-lea/node.js
RUN apt-get update
RUN apt-get -y install nodejs
WORKDIR /opt/app
COPY . /opt/app
RUN npm install
EXPOSE 3001
CMD ["node", "server.js"]
By dividing the copy of the application into 2 COPY instructions (one for the package.json file and the other for the rest of the files) and running the npm install instruction before adding the actual code, any code change wont trigger the RUN npm install instruction, only changes of the package.json will trigger it. Better practice docker file:
FROM ubuntu
MAINTAINER David Weinstein <david@bitjudo.com>
# install our dependencies and nodejs
RUN echo "deb http://archive.ubuntu.com/ubuntu precise main universe" > /etc/apt/sources.list
RUN apt-get update
RUN apt-get -y install python-software-properties git build-essential
RUN add-apt-repository -y ppa:chris-lea/node.js
RUN apt-get update
RUN apt-get -y install nodejs
# use changes to package.json to force Docker not to use the cache
# when we change our application's nodejs dependencies:
COPY package.json /tmp/package.json
RUN cd /tmp && npm install
RUN mkdir -p /opt/app && cp -a /tmp/node_modules /opt/app/
# From here we load our application's code in, therefore the previous docker
# "layer" thats been cached will be used if possible
WORKDIR /opt/app
COPY . /opt/app
EXPOSE 3000
CMD ["node", "server.js"]
This is where the package.json file added, install its dependencies and copy them into the container WORKDIR, where the app lives:
ADD package.json /tmp/package.json
RUN cd /tmp && npm install
RUN mkdir -p /opt/app && cp -a /tmp/node_modules /opt/app/
To avoid the npm install phase on every docker build just copy those lines and change the ^/opt/app^ to the location your app lives inside the container.
2
That works. Some points though.ADD
is discouraged in favor forCOPY
, afaik.COPY
is even more effective. IMO, the last two paragraphs are not necessary, since they are duplicates and also from the app point-of-view it doesn't matter where on the files system the app lives, as long asWORKDIR
is set.
– eljefedelrodeodeljefe
Jun 3 '16 at 3:15
2
Better-still is to combine all of the apt-get commands onto one RUN, including anapt-get clean
. Also, add ./node_modules to your .dockerignore, to avoid copying your working directory into your built container, and to speed up the build-context copy step of the build.
– Symmetric
Jul 28 '16 at 17:24
For what reason do you execute the copy command in a separate RUN? And does it matter if I move the node_modules package instead of copying it? Because it could get relatively big depending on how much you install
– Marian Klühspies
Feb 20 '17 at 11:20
1
The same approach but just addingpackage.json
to the final resting position works fine as well (eliminating any cp/mv).
– J. Fritz Barnes
Apr 3 '17 at 16:46
17
I don't get it. Why do you install in a temp directory and then move it to the app directory? Why not just install in the app directory? What am I missing here?
– joniba
May 31 '17 at 16:57
|
show 3 more comments
Weird! No one mentions multi-stage build.
# ---- Base Node ----
FROM alpine:3.5 AS base
# install node
RUN apk add --no-cache nodejs-current tini
# set working directory
WORKDIR /root/chat
# Set tini as entrypoint
ENTRYPOINT ["/sbin/tini", "--"]
# copy project file
COPY package.json .
#
# ---- Dependencies ----
FROM base AS dependencies
# install node packages
RUN npm set progress=false && npm config set depth 0
RUN npm install --only=production
# copy production node_modules aside
RUN cp -R node_modules prod_node_modules
# install ALL node_modules, including 'devDependencies'
RUN npm install
#
# ---- Test ----
# run linters, setup and tests
FROM dependencies AS test
COPY . .
RUN npm run lint && npm run setup && npm run test
#
# ---- Release ----
FROM base AS release
# copy production node_modules
COPY --from=dependencies /root/chat/prod_node_modules ./node_modules
# copy app sources
COPY . .
# expose port and define CMD
EXPOSE 5000
CMD npm run start
Awesome tuto here: https://codefresh.io/docker-tutorial/node_docker_multistage/
add a comment |
I've found that the simplest approach is to leverage Docker's copy semantics:
The COPY instruction copies new files or directories from and adds them to the filesystem of the container at the path .
This means that if you first explicitly copy the package.json
file and then run the npm install
step that it can be cached and then you can copy the rest of the source directory. If the package.json
file has changed, then that will be new and it will re-run the npm install caching that for future builds.
A snippet from the end of a Dockerfile would look like:
# install node modules
WORKDIR /usr/app
COPY package.json /usr/app/package.json
RUN npm install
# install application
COPY . /usr/app
3
Instead ofcd /usr/app
you can/should useWORKDIR /usr/app
.
– Vladimir Vukanac
Jan 17 at 15:53
@VladimirVukanac :+1: on using WORKDIR; I've updated the answer above to take that into account.
– J. Fritz Barnes
Jan 25 at 15:17
is npm install run in /usr/app directory or . ?
– user557657
Feb 1 at 19:06
1
@user557657 The WORKDIR sets the directory within the future image from which the command will be run. So in this case, it's running npm install from/usr/app
within the image which will create a/usr/app/node_modules
with dependencies installed from the npm install.
– J. Fritz Barnes
Feb 7 at 14:35
@J.FritzBarnes thanks a lot. isntCOPY . /usr/app
would copypackage.json
file again in/usr/app
with the rest of the files?
– user557657
Feb 8 at 15:20
|
show 2 more comments
I imagine you may already know, but you could include a .dockerignore file in the same folder containing
node_modules
npm-debug.log
to avoid bloating your image when you push to docker hub
add a comment |
you don't need to use tmp folder, just copy package.json to your container's application folder, do some install work and copy all files later.
COPY app/package.json /opt/app/package.json
RUN cd /opt/app && npm install
COPY app /opt/app
so you are executing npm install in container directory /opt/app then copying all files from local machine to /opt/app ?
– user557657
Feb 1 at 19:19
add a comment |
Your Answer
StackExchange.ifUsing("editor", function () {
StackExchange.using("externalEditor", function () {
StackExchange.using("snippets", function () {
StackExchange.snippets.init();
});
});
}, "code-snippets");
StackExchange.ready(function() {
var channelOptions = {
tags: "".split(" "),
id: "1"
};
initTagRenderer("".split(" "), "".split(" "), channelOptions);
StackExchange.using("externalEditor", function() {
// Have to fire editor after snippets, if snippets enabled
if (StackExchange.settings.snippets.snippetsEnabled) {
StackExchange.using("snippets", function() {
createEditor();
});
}
else {
createEditor();
}
});
function createEditor() {
StackExchange.prepareEditor({
heartbeatType: 'answer',
autoActivateHeartbeat: false,
convertImagesToLinks: true,
noModals: true,
showLowRepImageUploadWarning: true,
reputationToPostImages: 10,
bindNavPrevention: true,
postfix: "",
imageUploader: {
brandingHtml: "Powered by u003ca class="icon-imgur-white" href="https://imgur.com/"u003eu003c/au003e",
contentPolicyHtml: "User contributions licensed under u003ca href="https://creativecommons.org/licenses/by-sa/3.0/"u003ecc by-sa 3.0 with attribution requiredu003c/au003e u003ca href="https://stackoverflow.com/legal/content-policy"u003e(content policy)u003c/au003e",
allowUrls: true
},
onDemand: true,
discardSelector: ".discard-answer"
,immediatelyShowMarkdownHelp:true
});
}
});
Sign up or log in
StackExchange.ready(function () {
StackExchange.helpers.onClickDraftSave('#login-link');
});
Sign up using Google
Sign up using Facebook
Sign up using Email and Password
Post as a guest
Required, but never shown
StackExchange.ready(
function () {
StackExchange.openid.initPostLogin('.new-post-login', 'https%3a%2f%2fstackoverflow.com%2fquestions%2f35774714%2fhow-to-cache-the-run-npm-install-instruction-when-docker-build-a-dockerfile%23new-answer', 'question_page');
}
);
Post as a guest
Required, but never shown
5 Answers
5
active
oldest
votes
5 Answers
5
active
oldest
votes
active
oldest
votes
active
oldest
votes
Ok so I found this great article about efficiency when writing a docker file.
This is an example of a bad docker file adding the application code before running the RUN npm install
instruction:
FROM ubuntu
RUN echo "deb http://archive.ubuntu.com/ubuntu precise main universe" > /etc/apt/sources.list
RUN apt-get update
RUN apt-get -y install python-software-properties git build-essential
RUN add-apt-repository -y ppa:chris-lea/node.js
RUN apt-get update
RUN apt-get -y install nodejs
WORKDIR /opt/app
COPY . /opt/app
RUN npm install
EXPOSE 3001
CMD ["node", "server.js"]
By dividing the copy of the application into 2 COPY instructions (one for the package.json file and the other for the rest of the files) and running the npm install instruction before adding the actual code, any code change wont trigger the RUN npm install instruction, only changes of the package.json will trigger it. Better practice docker file:
FROM ubuntu
MAINTAINER David Weinstein <david@bitjudo.com>
# install our dependencies and nodejs
RUN echo "deb http://archive.ubuntu.com/ubuntu precise main universe" > /etc/apt/sources.list
RUN apt-get update
RUN apt-get -y install python-software-properties git build-essential
RUN add-apt-repository -y ppa:chris-lea/node.js
RUN apt-get update
RUN apt-get -y install nodejs
# use changes to package.json to force Docker not to use the cache
# when we change our application's nodejs dependencies:
COPY package.json /tmp/package.json
RUN cd /tmp && npm install
RUN mkdir -p /opt/app && cp -a /tmp/node_modules /opt/app/
# From here we load our application's code in, therefore the previous docker
# "layer" thats been cached will be used if possible
WORKDIR /opt/app
COPY . /opt/app
EXPOSE 3000
CMD ["node", "server.js"]
This is where the package.json file added, install its dependencies and copy them into the container WORKDIR, where the app lives:
ADD package.json /tmp/package.json
RUN cd /tmp && npm install
RUN mkdir -p /opt/app && cp -a /tmp/node_modules /opt/app/
To avoid the npm install phase on every docker build just copy those lines and change the ^/opt/app^ to the location your app lives inside the container.
2
That works. Some points though.ADD
is discouraged in favor forCOPY
, afaik.COPY
is even more effective. IMO, the last two paragraphs are not necessary, since they are duplicates and also from the app point-of-view it doesn't matter where on the files system the app lives, as long asWORKDIR
is set.
– eljefedelrodeodeljefe
Jun 3 '16 at 3:15
2
Better-still is to combine all of the apt-get commands onto one RUN, including anapt-get clean
. Also, add ./node_modules to your .dockerignore, to avoid copying your working directory into your built container, and to speed up the build-context copy step of the build.
– Symmetric
Jul 28 '16 at 17:24
For what reason do you execute the copy command in a separate RUN? And does it matter if I move the node_modules package instead of copying it? Because it could get relatively big depending on how much you install
– Marian Klühspies
Feb 20 '17 at 11:20
1
The same approach but just addingpackage.json
to the final resting position works fine as well (eliminating any cp/mv).
– J. Fritz Barnes
Apr 3 '17 at 16:46
17
I don't get it. Why do you install in a temp directory and then move it to the app directory? Why not just install in the app directory? What am I missing here?
– joniba
May 31 '17 at 16:57
|
show 3 more comments
Ok so I found this great article about efficiency when writing a docker file.
This is an example of a bad docker file adding the application code before running the RUN npm install
instruction:
FROM ubuntu
RUN echo "deb http://archive.ubuntu.com/ubuntu precise main universe" > /etc/apt/sources.list
RUN apt-get update
RUN apt-get -y install python-software-properties git build-essential
RUN add-apt-repository -y ppa:chris-lea/node.js
RUN apt-get update
RUN apt-get -y install nodejs
WORKDIR /opt/app
COPY . /opt/app
RUN npm install
EXPOSE 3001
CMD ["node", "server.js"]
By dividing the copy of the application into 2 COPY instructions (one for the package.json file and the other for the rest of the files) and running the npm install instruction before adding the actual code, any code change wont trigger the RUN npm install instruction, only changes of the package.json will trigger it. Better practice docker file:
FROM ubuntu
MAINTAINER David Weinstein <david@bitjudo.com>
# install our dependencies and nodejs
RUN echo "deb http://archive.ubuntu.com/ubuntu precise main universe" > /etc/apt/sources.list
RUN apt-get update
RUN apt-get -y install python-software-properties git build-essential
RUN add-apt-repository -y ppa:chris-lea/node.js
RUN apt-get update
RUN apt-get -y install nodejs
# use changes to package.json to force Docker not to use the cache
# when we change our application's nodejs dependencies:
COPY package.json /tmp/package.json
RUN cd /tmp && npm install
RUN mkdir -p /opt/app && cp -a /tmp/node_modules /opt/app/
# From here we load our application's code in, therefore the previous docker
# "layer" thats been cached will be used if possible
WORKDIR /opt/app
COPY . /opt/app
EXPOSE 3000
CMD ["node", "server.js"]
This is where the package.json file added, install its dependencies and copy them into the container WORKDIR, where the app lives:
ADD package.json /tmp/package.json
RUN cd /tmp && npm install
RUN mkdir -p /opt/app && cp -a /tmp/node_modules /opt/app/
To avoid the npm install phase on every docker build just copy those lines and change the ^/opt/app^ to the location your app lives inside the container.
2
That works. Some points though.ADD
is discouraged in favor forCOPY
, afaik.COPY
is even more effective. IMO, the last two paragraphs are not necessary, since they are duplicates and also from the app point-of-view it doesn't matter where on the files system the app lives, as long asWORKDIR
is set.
– eljefedelrodeodeljefe
Jun 3 '16 at 3:15
2
Better-still is to combine all of the apt-get commands onto one RUN, including anapt-get clean
. Also, add ./node_modules to your .dockerignore, to avoid copying your working directory into your built container, and to speed up the build-context copy step of the build.
– Symmetric
Jul 28 '16 at 17:24
For what reason do you execute the copy command in a separate RUN? And does it matter if I move the node_modules package instead of copying it? Because it could get relatively big depending on how much you install
– Marian Klühspies
Feb 20 '17 at 11:20
1
The same approach but just addingpackage.json
to the final resting position works fine as well (eliminating any cp/mv).
– J. Fritz Barnes
Apr 3 '17 at 16:46
17
I don't get it. Why do you install in a temp directory and then move it to the app directory? Why not just install in the app directory? What am I missing here?
– joniba
May 31 '17 at 16:57
|
show 3 more comments
Ok so I found this great article about efficiency when writing a docker file.
This is an example of a bad docker file adding the application code before running the RUN npm install
instruction:
FROM ubuntu
RUN echo "deb http://archive.ubuntu.com/ubuntu precise main universe" > /etc/apt/sources.list
RUN apt-get update
RUN apt-get -y install python-software-properties git build-essential
RUN add-apt-repository -y ppa:chris-lea/node.js
RUN apt-get update
RUN apt-get -y install nodejs
WORKDIR /opt/app
COPY . /opt/app
RUN npm install
EXPOSE 3001
CMD ["node", "server.js"]
By dividing the copy of the application into 2 COPY instructions (one for the package.json file and the other for the rest of the files) and running the npm install instruction before adding the actual code, any code change wont trigger the RUN npm install instruction, only changes of the package.json will trigger it. Better practice docker file:
FROM ubuntu
MAINTAINER David Weinstein <david@bitjudo.com>
# install our dependencies and nodejs
RUN echo "deb http://archive.ubuntu.com/ubuntu precise main universe" > /etc/apt/sources.list
RUN apt-get update
RUN apt-get -y install python-software-properties git build-essential
RUN add-apt-repository -y ppa:chris-lea/node.js
RUN apt-get update
RUN apt-get -y install nodejs
# use changes to package.json to force Docker not to use the cache
# when we change our application's nodejs dependencies:
COPY package.json /tmp/package.json
RUN cd /tmp && npm install
RUN mkdir -p /opt/app && cp -a /tmp/node_modules /opt/app/
# From here we load our application's code in, therefore the previous docker
# "layer" thats been cached will be used if possible
WORKDIR /opt/app
COPY . /opt/app
EXPOSE 3000
CMD ["node", "server.js"]
This is where the package.json file added, install its dependencies and copy them into the container WORKDIR, where the app lives:
ADD package.json /tmp/package.json
RUN cd /tmp && npm install
RUN mkdir -p /opt/app && cp -a /tmp/node_modules /opt/app/
To avoid the npm install phase on every docker build just copy those lines and change the ^/opt/app^ to the location your app lives inside the container.
Ok so I found this great article about efficiency when writing a docker file.
This is an example of a bad docker file adding the application code before running the RUN npm install
instruction:
FROM ubuntu
RUN echo "deb http://archive.ubuntu.com/ubuntu precise main universe" > /etc/apt/sources.list
RUN apt-get update
RUN apt-get -y install python-software-properties git build-essential
RUN add-apt-repository -y ppa:chris-lea/node.js
RUN apt-get update
RUN apt-get -y install nodejs
WORKDIR /opt/app
COPY . /opt/app
RUN npm install
EXPOSE 3001
CMD ["node", "server.js"]
By dividing the copy of the application into 2 COPY instructions (one for the package.json file and the other for the rest of the files) and running the npm install instruction before adding the actual code, any code change wont trigger the RUN npm install instruction, only changes of the package.json will trigger it. Better practice docker file:
FROM ubuntu
MAINTAINER David Weinstein <david@bitjudo.com>
# install our dependencies and nodejs
RUN echo "deb http://archive.ubuntu.com/ubuntu precise main universe" > /etc/apt/sources.list
RUN apt-get update
RUN apt-get -y install python-software-properties git build-essential
RUN add-apt-repository -y ppa:chris-lea/node.js
RUN apt-get update
RUN apt-get -y install nodejs
# use changes to package.json to force Docker not to use the cache
# when we change our application's nodejs dependencies:
COPY package.json /tmp/package.json
RUN cd /tmp && npm install
RUN mkdir -p /opt/app && cp -a /tmp/node_modules /opt/app/
# From here we load our application's code in, therefore the previous docker
# "layer" thats been cached will be used if possible
WORKDIR /opt/app
COPY . /opt/app
EXPOSE 3000
CMD ["node", "server.js"]
This is where the package.json file added, install its dependencies and copy them into the container WORKDIR, where the app lives:
ADD package.json /tmp/package.json
RUN cd /tmp && npm install
RUN mkdir -p /opt/app && cp -a /tmp/node_modules /opt/app/
To avoid the npm install phase on every docker build just copy those lines and change the ^/opt/app^ to the location your app lives inside the container.
edited Jul 24 '16 at 11:42
answered Mar 3 '16 at 14:21
ohadgkohadgk
1,2581610
1,2581610
2
That works. Some points though.ADD
is discouraged in favor forCOPY
, afaik.COPY
is even more effective. IMO, the last two paragraphs are not necessary, since they are duplicates and also from the app point-of-view it doesn't matter where on the files system the app lives, as long asWORKDIR
is set.
– eljefedelrodeodeljefe
Jun 3 '16 at 3:15
2
Better-still is to combine all of the apt-get commands onto one RUN, including anapt-get clean
. Also, add ./node_modules to your .dockerignore, to avoid copying your working directory into your built container, and to speed up the build-context copy step of the build.
– Symmetric
Jul 28 '16 at 17:24
For what reason do you execute the copy command in a separate RUN? And does it matter if I move the node_modules package instead of copying it? Because it could get relatively big depending on how much you install
– Marian Klühspies
Feb 20 '17 at 11:20
1
The same approach but just addingpackage.json
to the final resting position works fine as well (eliminating any cp/mv).
– J. Fritz Barnes
Apr 3 '17 at 16:46
17
I don't get it. Why do you install in a temp directory and then move it to the app directory? Why not just install in the app directory? What am I missing here?
– joniba
May 31 '17 at 16:57
|
show 3 more comments
2
That works. Some points though.ADD
is discouraged in favor forCOPY
, afaik.COPY
is even more effective. IMO, the last two paragraphs are not necessary, since they are duplicates and also from the app point-of-view it doesn't matter where on the files system the app lives, as long asWORKDIR
is set.
– eljefedelrodeodeljefe
Jun 3 '16 at 3:15
2
Better-still is to combine all of the apt-get commands onto one RUN, including anapt-get clean
. Also, add ./node_modules to your .dockerignore, to avoid copying your working directory into your built container, and to speed up the build-context copy step of the build.
– Symmetric
Jul 28 '16 at 17:24
For what reason do you execute the copy command in a separate RUN? And does it matter if I move the node_modules package instead of copying it? Because it could get relatively big depending on how much you install
– Marian Klühspies
Feb 20 '17 at 11:20
1
The same approach but just addingpackage.json
to the final resting position works fine as well (eliminating any cp/mv).
– J. Fritz Barnes
Apr 3 '17 at 16:46
17
I don't get it. Why do you install in a temp directory and then move it to the app directory? Why not just install in the app directory? What am I missing here?
– joniba
May 31 '17 at 16:57
2
2
That works. Some points though.
ADD
is discouraged in favor for COPY
, afaik. COPY
is even more effective. IMO, the last two paragraphs are not necessary, since they are duplicates and also from the app point-of-view it doesn't matter where on the files system the app lives, as long as WORKDIR
is set.– eljefedelrodeodeljefe
Jun 3 '16 at 3:15
That works. Some points though.
ADD
is discouraged in favor for COPY
, afaik. COPY
is even more effective. IMO, the last two paragraphs are not necessary, since they are duplicates and also from the app point-of-view it doesn't matter where on the files system the app lives, as long as WORKDIR
is set.– eljefedelrodeodeljefe
Jun 3 '16 at 3:15
2
2
Better-still is to combine all of the apt-get commands onto one RUN, including an
apt-get clean
. Also, add ./node_modules to your .dockerignore, to avoid copying your working directory into your built container, and to speed up the build-context copy step of the build.– Symmetric
Jul 28 '16 at 17:24
Better-still is to combine all of the apt-get commands onto one RUN, including an
apt-get clean
. Also, add ./node_modules to your .dockerignore, to avoid copying your working directory into your built container, and to speed up the build-context copy step of the build.– Symmetric
Jul 28 '16 at 17:24
For what reason do you execute the copy command in a separate RUN? And does it matter if I move the node_modules package instead of copying it? Because it could get relatively big depending on how much you install
– Marian Klühspies
Feb 20 '17 at 11:20
For what reason do you execute the copy command in a separate RUN? And does it matter if I move the node_modules package instead of copying it? Because it could get relatively big depending on how much you install
– Marian Klühspies
Feb 20 '17 at 11:20
1
1
The same approach but just adding
package.json
to the final resting position works fine as well (eliminating any cp/mv).– J. Fritz Barnes
Apr 3 '17 at 16:46
The same approach but just adding
package.json
to the final resting position works fine as well (eliminating any cp/mv).– J. Fritz Barnes
Apr 3 '17 at 16:46
17
17
I don't get it. Why do you install in a temp directory and then move it to the app directory? Why not just install in the app directory? What am I missing here?
– joniba
May 31 '17 at 16:57
I don't get it. Why do you install in a temp directory and then move it to the app directory? Why not just install in the app directory? What am I missing here?
– joniba
May 31 '17 at 16:57
|
show 3 more comments
Weird! No one mentions multi-stage build.
# ---- Base Node ----
FROM alpine:3.5 AS base
# install node
RUN apk add --no-cache nodejs-current tini
# set working directory
WORKDIR /root/chat
# Set tini as entrypoint
ENTRYPOINT ["/sbin/tini", "--"]
# copy project file
COPY package.json .
#
# ---- Dependencies ----
FROM base AS dependencies
# install node packages
RUN npm set progress=false && npm config set depth 0
RUN npm install --only=production
# copy production node_modules aside
RUN cp -R node_modules prod_node_modules
# install ALL node_modules, including 'devDependencies'
RUN npm install
#
# ---- Test ----
# run linters, setup and tests
FROM dependencies AS test
COPY . .
RUN npm run lint && npm run setup && npm run test
#
# ---- Release ----
FROM base AS release
# copy production node_modules
COPY --from=dependencies /root/chat/prod_node_modules ./node_modules
# copy app sources
COPY . .
# expose port and define CMD
EXPOSE 5000
CMD npm run start
Awesome tuto here: https://codefresh.io/docker-tutorial/node_docker_multistage/
add a comment |
Weird! No one mentions multi-stage build.
# ---- Base Node ----
FROM alpine:3.5 AS base
# install node
RUN apk add --no-cache nodejs-current tini
# set working directory
WORKDIR /root/chat
# Set tini as entrypoint
ENTRYPOINT ["/sbin/tini", "--"]
# copy project file
COPY package.json .
#
# ---- Dependencies ----
FROM base AS dependencies
# install node packages
RUN npm set progress=false && npm config set depth 0
RUN npm install --only=production
# copy production node_modules aside
RUN cp -R node_modules prod_node_modules
# install ALL node_modules, including 'devDependencies'
RUN npm install
#
# ---- Test ----
# run linters, setup and tests
FROM dependencies AS test
COPY . .
RUN npm run lint && npm run setup && npm run test
#
# ---- Release ----
FROM base AS release
# copy production node_modules
COPY --from=dependencies /root/chat/prod_node_modules ./node_modules
# copy app sources
COPY . .
# expose port and define CMD
EXPOSE 5000
CMD npm run start
Awesome tuto here: https://codefresh.io/docker-tutorial/node_docker_multistage/
add a comment |
Weird! No one mentions multi-stage build.
# ---- Base Node ----
FROM alpine:3.5 AS base
# install node
RUN apk add --no-cache nodejs-current tini
# set working directory
WORKDIR /root/chat
# Set tini as entrypoint
ENTRYPOINT ["/sbin/tini", "--"]
# copy project file
COPY package.json .
#
# ---- Dependencies ----
FROM base AS dependencies
# install node packages
RUN npm set progress=false && npm config set depth 0
RUN npm install --only=production
# copy production node_modules aside
RUN cp -R node_modules prod_node_modules
# install ALL node_modules, including 'devDependencies'
RUN npm install
#
# ---- Test ----
# run linters, setup and tests
FROM dependencies AS test
COPY . .
RUN npm run lint && npm run setup && npm run test
#
# ---- Release ----
FROM base AS release
# copy production node_modules
COPY --from=dependencies /root/chat/prod_node_modules ./node_modules
# copy app sources
COPY . .
# expose port and define CMD
EXPOSE 5000
CMD npm run start
Awesome tuto here: https://codefresh.io/docker-tutorial/node_docker_multistage/
Weird! No one mentions multi-stage build.
# ---- Base Node ----
FROM alpine:3.5 AS base
# install node
RUN apk add --no-cache nodejs-current tini
# set working directory
WORKDIR /root/chat
# Set tini as entrypoint
ENTRYPOINT ["/sbin/tini", "--"]
# copy project file
COPY package.json .
#
# ---- Dependencies ----
FROM base AS dependencies
# install node packages
RUN npm set progress=false && npm config set depth 0
RUN npm install --only=production
# copy production node_modules aside
RUN cp -R node_modules prod_node_modules
# install ALL node_modules, including 'devDependencies'
RUN npm install
#
# ---- Test ----
# run linters, setup and tests
FROM dependencies AS test
COPY . .
RUN npm run lint && npm run setup && npm run test
#
# ---- Release ----
FROM base AS release
# copy production node_modules
COPY --from=dependencies /root/chat/prod_node_modules ./node_modules
# copy app sources
COPY . .
# expose port and define CMD
EXPOSE 5000
CMD npm run start
Awesome tuto here: https://codefresh.io/docker-tutorial/node_docker_multistage/
answered Apr 30 '18 at 8:54
Abdennour TOUMIAbdennour TOUMI
36.4k15145163
36.4k15145163
add a comment |
add a comment |
I've found that the simplest approach is to leverage Docker's copy semantics:
The COPY instruction copies new files or directories from and adds them to the filesystem of the container at the path .
This means that if you first explicitly copy the package.json
file and then run the npm install
step that it can be cached and then you can copy the rest of the source directory. If the package.json
file has changed, then that will be new and it will re-run the npm install caching that for future builds.
A snippet from the end of a Dockerfile would look like:
# install node modules
WORKDIR /usr/app
COPY package.json /usr/app/package.json
RUN npm install
# install application
COPY . /usr/app
3
Instead ofcd /usr/app
you can/should useWORKDIR /usr/app
.
– Vladimir Vukanac
Jan 17 at 15:53
@VladimirVukanac :+1: on using WORKDIR; I've updated the answer above to take that into account.
– J. Fritz Barnes
Jan 25 at 15:17
is npm install run in /usr/app directory or . ?
– user557657
Feb 1 at 19:06
1
@user557657 The WORKDIR sets the directory within the future image from which the command will be run. So in this case, it's running npm install from/usr/app
within the image which will create a/usr/app/node_modules
with dependencies installed from the npm install.
– J. Fritz Barnes
Feb 7 at 14:35
@J.FritzBarnes thanks a lot. isntCOPY . /usr/app
would copypackage.json
file again in/usr/app
with the rest of the files?
– user557657
Feb 8 at 15:20
|
show 2 more comments
I've found that the simplest approach is to leverage Docker's copy semantics:
The COPY instruction copies new files or directories from and adds them to the filesystem of the container at the path .
This means that if you first explicitly copy the package.json
file and then run the npm install
step that it can be cached and then you can copy the rest of the source directory. If the package.json
file has changed, then that will be new and it will re-run the npm install caching that for future builds.
A snippet from the end of a Dockerfile would look like:
# install node modules
WORKDIR /usr/app
COPY package.json /usr/app/package.json
RUN npm install
# install application
COPY . /usr/app
3
Instead ofcd /usr/app
you can/should useWORKDIR /usr/app
.
– Vladimir Vukanac
Jan 17 at 15:53
@VladimirVukanac :+1: on using WORKDIR; I've updated the answer above to take that into account.
– J. Fritz Barnes
Jan 25 at 15:17
is npm install run in /usr/app directory or . ?
– user557657
Feb 1 at 19:06
1
@user557657 The WORKDIR sets the directory within the future image from which the command will be run. So in this case, it's running npm install from/usr/app
within the image which will create a/usr/app/node_modules
with dependencies installed from the npm install.
– J. Fritz Barnes
Feb 7 at 14:35
@J.FritzBarnes thanks a lot. isntCOPY . /usr/app
would copypackage.json
file again in/usr/app
with the rest of the files?
– user557657
Feb 8 at 15:20
|
show 2 more comments
I've found that the simplest approach is to leverage Docker's copy semantics:
The COPY instruction copies new files or directories from and adds them to the filesystem of the container at the path .
This means that if you first explicitly copy the package.json
file and then run the npm install
step that it can be cached and then you can copy the rest of the source directory. If the package.json
file has changed, then that will be new and it will re-run the npm install caching that for future builds.
A snippet from the end of a Dockerfile would look like:
# install node modules
WORKDIR /usr/app
COPY package.json /usr/app/package.json
RUN npm install
# install application
COPY . /usr/app
I've found that the simplest approach is to leverage Docker's copy semantics:
The COPY instruction copies new files or directories from and adds them to the filesystem of the container at the path .
This means that if you first explicitly copy the package.json
file and then run the npm install
step that it can be cached and then you can copy the rest of the source directory. If the package.json
file has changed, then that will be new and it will re-run the npm install caching that for future builds.
A snippet from the end of a Dockerfile would look like:
# install node modules
WORKDIR /usr/app
COPY package.json /usr/app/package.json
RUN npm install
# install application
COPY . /usr/app
edited Jan 25 at 15:16
answered Apr 3 '17 at 17:01
J. Fritz BarnesJ. Fritz Barnes
44846
44846
3
Instead ofcd /usr/app
you can/should useWORKDIR /usr/app
.
– Vladimir Vukanac
Jan 17 at 15:53
@VladimirVukanac :+1: on using WORKDIR; I've updated the answer above to take that into account.
– J. Fritz Barnes
Jan 25 at 15:17
is npm install run in /usr/app directory or . ?
– user557657
Feb 1 at 19:06
1
@user557657 The WORKDIR sets the directory within the future image from which the command will be run. So in this case, it's running npm install from/usr/app
within the image which will create a/usr/app/node_modules
with dependencies installed from the npm install.
– J. Fritz Barnes
Feb 7 at 14:35
@J.FritzBarnes thanks a lot. isntCOPY . /usr/app
would copypackage.json
file again in/usr/app
with the rest of the files?
– user557657
Feb 8 at 15:20
|
show 2 more comments
3
Instead ofcd /usr/app
you can/should useWORKDIR /usr/app
.
– Vladimir Vukanac
Jan 17 at 15:53
@VladimirVukanac :+1: on using WORKDIR; I've updated the answer above to take that into account.
– J. Fritz Barnes
Jan 25 at 15:17
is npm install run in /usr/app directory or . ?
– user557657
Feb 1 at 19:06
1
@user557657 The WORKDIR sets the directory within the future image from which the command will be run. So in this case, it's running npm install from/usr/app
within the image which will create a/usr/app/node_modules
with dependencies installed from the npm install.
– J. Fritz Barnes
Feb 7 at 14:35
@J.FritzBarnes thanks a lot. isntCOPY . /usr/app
would copypackage.json
file again in/usr/app
with the rest of the files?
– user557657
Feb 8 at 15:20
3
3
Instead of
cd /usr/app
you can/should use WORKDIR /usr/app
.– Vladimir Vukanac
Jan 17 at 15:53
Instead of
cd /usr/app
you can/should use WORKDIR /usr/app
.– Vladimir Vukanac
Jan 17 at 15:53
@VladimirVukanac :+1: on using WORKDIR; I've updated the answer above to take that into account.
– J. Fritz Barnes
Jan 25 at 15:17
@VladimirVukanac :+1: on using WORKDIR; I've updated the answer above to take that into account.
– J. Fritz Barnes
Jan 25 at 15:17
is npm install run in /usr/app directory or . ?
– user557657
Feb 1 at 19:06
is npm install run in /usr/app directory or . ?
– user557657
Feb 1 at 19:06
1
1
@user557657 The WORKDIR sets the directory within the future image from which the command will be run. So in this case, it's running npm install from
/usr/app
within the image which will create a /usr/app/node_modules
with dependencies installed from the npm install.– J. Fritz Barnes
Feb 7 at 14:35
@user557657 The WORKDIR sets the directory within the future image from which the command will be run. So in this case, it's running npm install from
/usr/app
within the image which will create a /usr/app/node_modules
with dependencies installed from the npm install.– J. Fritz Barnes
Feb 7 at 14:35
@J.FritzBarnes thanks a lot. isnt
COPY . /usr/app
would copy package.json
file again in /usr/app
with the rest of the files?– user557657
Feb 8 at 15:20
@J.FritzBarnes thanks a lot. isnt
COPY . /usr/app
would copy package.json
file again in /usr/app
with the rest of the files?– user557657
Feb 8 at 15:20
|
show 2 more comments
I imagine you may already know, but you could include a .dockerignore file in the same folder containing
node_modules
npm-debug.log
to avoid bloating your image when you push to docker hub
add a comment |
I imagine you may already know, but you could include a .dockerignore file in the same folder containing
node_modules
npm-debug.log
to avoid bloating your image when you push to docker hub
add a comment |
I imagine you may already know, but you could include a .dockerignore file in the same folder containing
node_modules
npm-debug.log
to avoid bloating your image when you push to docker hub
I imagine you may already know, but you could include a .dockerignore file in the same folder containing
node_modules
npm-debug.log
to avoid bloating your image when you push to docker hub
answered Jan 25 '17 at 15:42
usrrnameusrrname
15919
15919
add a comment |
add a comment |
you don't need to use tmp folder, just copy package.json to your container's application folder, do some install work and copy all files later.
COPY app/package.json /opt/app/package.json
RUN cd /opt/app && npm install
COPY app /opt/app
so you are executing npm install in container directory /opt/app then copying all files from local machine to /opt/app ?
– user557657
Feb 1 at 19:19
add a comment |
you don't need to use tmp folder, just copy package.json to your container's application folder, do some install work and copy all files later.
COPY app/package.json /opt/app/package.json
RUN cd /opt/app && npm install
COPY app /opt/app
so you are executing npm install in container directory /opt/app then copying all files from local machine to /opt/app ?
– user557657
Feb 1 at 19:19
add a comment |
you don't need to use tmp folder, just copy package.json to your container's application folder, do some install work and copy all files later.
COPY app/package.json /opt/app/package.json
RUN cd /opt/app && npm install
COPY app /opt/app
you don't need to use tmp folder, just copy package.json to your container's application folder, do some install work and copy all files later.
COPY app/package.json /opt/app/package.json
RUN cd /opt/app && npm install
COPY app /opt/app
answered Nov 17 '18 at 4:42
Mike ZhangMike Zhang
101110
101110
so you are executing npm install in container directory /opt/app then copying all files from local machine to /opt/app ?
– user557657
Feb 1 at 19:19
add a comment |
so you are executing npm install in container directory /opt/app then copying all files from local machine to /opt/app ?
– user557657
Feb 1 at 19:19
so you are executing npm install in container directory /opt/app then copying all files from local machine to /opt/app ?
– user557657
Feb 1 at 19:19
so you are executing npm install in container directory /opt/app then copying all files from local machine to /opt/app ?
– user557657
Feb 1 at 19:19
add a comment |
Thanks for contributing an answer to Stack Overflow!
- Please be sure to answer the question. Provide details and share your research!
But avoid …
- Asking for help, clarification, or responding to other answers.
- Making statements based on opinion; back them up with references or personal experience.
To learn more, see our tips on writing great answers.
Sign up or log in
StackExchange.ready(function () {
StackExchange.helpers.onClickDraftSave('#login-link');
});
Sign up using Google
Sign up using Facebook
Sign up using Email and Password
Post as a guest
Required, but never shown
StackExchange.ready(
function () {
StackExchange.openid.initPostLogin('.new-post-login', 'https%3a%2f%2fstackoverflow.com%2fquestions%2f35774714%2fhow-to-cache-the-run-npm-install-instruction-when-docker-build-a-dockerfile%23new-answer', 'question_page');
}
);
Post as a guest
Required, but never shown
Sign up or log in
StackExchange.ready(function () {
StackExchange.helpers.onClickDraftSave('#login-link');
});
Sign up using Google
Sign up using Facebook
Sign up using Email and Password
Post as a guest
Required, but never shown
Sign up or log in
StackExchange.ready(function () {
StackExchange.helpers.onClickDraftSave('#login-link');
});
Sign up using Google
Sign up using Facebook
Sign up using Email and Password
Post as a guest
Required, but never shown
Sign up or log in
StackExchange.ready(function () {
StackExchange.helpers.onClickDraftSave('#login-link');
});
Sign up using Google
Sign up using Facebook
Sign up using Email and Password
Sign up using Google
Sign up using Facebook
Sign up using Email and Password
Post as a guest
Required, but never shown
Required, but never shown
Required, but never shown
Required, but never shown
Required, but never shown
Required, but never shown
Required, but never shown
Required, but never shown
Required, but never shown