Search This Blog

Saturday 7 May 2016

Why the order of the Docker commands in the Dockerfile matters

The Docker image is built from directives in the Dockerfile. Docker images are actually built in layers and each layer is part of the image's filesystem. A layer either adds to or replaces the previous one. Each Docker directive, when run, results in a new layer and the layer is cached, unless Docker is instructed otherwise. When the container starts, a final read-write layer is added on top to allow to store changes to the container. Docker uses the union filesystem to merge different filesystems and directories into the final one.

When the Docker image is being built, it uses the cached layers. If a layer was invalidated (one of the invalidation criteria is the checksum of files present in the layer, so when a file has changed during the build), Docker reruns all directives from the one, whose cached layer was invalidated, to the current command to recreate/create up-to-date layers. This makes Docker efficient and fast, and it also means the order of commands is important.

Example:


WRONG

1
2
3
4
5
6
WORKDIR /var/www/my_application            container directory where the RUN, CMD will be run

COPY .  /var/www/my_application            puts all our application files, including package,json, to its resting place in the container
RUN ["npm", "install"]                     installs application nodejs dependencies - this invalidates the cached layer for the COPY directive 
RUN ["node_modules/bower/bin/bower.js", "install", "--allow-root"]   installs application frontend dependencies - this invalidates the cached layer for the COPY directive          
RUN ["node_modules/gulp/bin/gulp.js"]      runs task runner that again invalidates the COPY directive layer by creating new (minified etc) files


CORRECT


 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
WORKDIR /var/www/my_application            container directory where the RUN, CMD will be run

COPY package.json  /var/www/my_application this layer will only be invalidated if the package,json changes
RUN ["npm", "install"]                     installs application nodejs dependencies

COPY bower.json  /var/www/my_application   this layer will only be invalidated if the bower.json  changes
RUN ["node_modules/bower/bin/bower.js", "install", "--allow-root"]  installs application frontend dependencies    

COPY .  /var/www/my_application            puts all our application files to its resting place in the container

RUN ["node_modules/gulp/bin/gulp.js"]      runs task runner

No comments:

Post a Comment

Note: only a member of this blog may post a comment.