# Dockerfile best practices

• use COPY, not ADD (if you do not have good reason to). COPY only supports the basic copying of local files into the container, while ADD has some features (like local-only tar extraction and remote URL support) that are not immediately obvious
• after npm i run npm cache-clean --force to make your image as small as possible
• CMD ["node","index.js"], instead of CMD ["npm","start"]npm requires another process and we are not literal as we should be in Dockerfile. There is also a problem with handling signal termination by npm. For more details look here.
• use WORKDIR /folder instead of RUN mkdir /folder & RUN cd /folderWORKDIR will create folder if not exists and cd to it. WORKDIR creates folders with root:root permissions.
• use unprivileged user, in node : USER node – only CMD, ENTRYPOINT & RUN will be run as user that has been set. No matter where you will change user.
• COPY twice: package-lock.json and after npm i -> copy the rest of the project . .
• use apt commands once and as soon as possible
• build and image using a Dockerfile from STDIN, without sending build context – it will not sent any file as build context to the daemon – thus the build itself will be faster. It can be useful, when your Dockerfile does not require files to be copied into the image
• if need some files from the context, but not all of them, use .dockerignore
• each container should have only one concern
• only the instructions RUN, COPY, ADD create layers. Other instructions create temporary intermediate images, and do not increase the size of the build.
• sort multi-line arguments
• if you do not want to use the cache at all, you can use the --no-cache=true option on the docker build command
• once the cache is invalidated, all subsequent Dockerfile commands generate new images and the cache is not used
• always combine RUN apt-get update with apt-get install in the same RUN statement
• clean up apt cache by running rm -rf /var/lib/apt/lists/* after running the apt update && apt upgrade. Official Debian and Ubuntu images automatically run apt-get clean, so explicit invocation is not required.
• CMD should almost always be used in the form of CMD ["executable", "param1", "param2"…]
• the best use for ENTRYPOINT is to set the image’s main command, allowing that image to be run as though it was that command (and then use CMD as the default flags).
• for clarity and reliability, you should always use absolute paths for your WORKDIR
• an ONBUILD command executes after the current Dockerfile build completes. A Docker build executes ONBUILD commands before any command in a child Dockerfile. Images built with ONBUILD should get a separate tag, for example: ruby:1.9-onbuild
• Dockerfile should specify at least one of CMD or ENTRYPOINT commands
• ENTRYPOINT should be defined when using the container as an executable
• CMD should be used as a way of defining default arguments for an ENTRYPOINT command or for executing an ad-hoc command in a container
• CMD will be overridden when running the container with alternative arguments

#### FROM directive:

• stick to even image versions – those tend to be LTS
• use current official images as the basis for your images
• do not use latest, slim and onbuild tags
• use alpine when you need small image