FROM ubuntu:16.04
RUN apt-get update &&
apt-get install -y wget
FROM ubuntu:16.04
RUN apt-get update && \
apt-get install -y wget
Lines not starting with a correct instruction or not being a part of the previous instruction are labeled as invalid.
# Empty line
# directive=value
FROM ubuntu:16.04
RUN apt-get update && \
apt-get install -y wget
# directive=value
FROM ubuntu:16.04
RUN apt-get update && \
apt-get install -y wget
Parser directives must be at the very top of the Dockerfile.
# directive=value1
# directive=value2
FROM ubuntu:16.04
RUN apt-get update && \
apt-get install -y wget
# directive=value
FROM ubuntu:16.04
RUN apt-get update && \
apt-get install -y wget
Parser directive cannot be used more than once.
# DIRECTIVE=value
FROM ubuntu:16.04
RUN apt-get update && \
apt-get install -y wget
# directive=value
FROM ubuntu:16.04
RUN apt-get update && \
apt-get install -y wget
According to the convention, names of parser directives should be typed in lowercase.
# About my dockerfile
# directive=value
FROM ubuntu:16.04
RUN apt-get update && \
apt-get install -y wget
# directive=value
FROM ubuntu:16.04
RUN apt-get update && \
apt-get install -y wget
Parser directive is treated as a comment if it appears after a builder instruction, a comment which is not a parser directive, or when it is impossible to recognize it.
# About my dockerfile
# directive=
FROM ubuntu:16.04
RUN apt-get update && \
apt-get install -y wget
# directive=value
FROM ubuntu:16.04
RUN apt-get update && \
apt-get install -y wget
If used, parser directives must contain values.
RUN wget -O - https://some.site | wc -l > /number
SHELL ["/bin/bash", "-o", "pipefail", "-c"]
RUN wget -O - https://some.site | wc -l > /number
Some RUN
commands depend on the ability to pipe the output of one command into another using the pipe character (|
), as in the following example:
RUN wget -O - https://some.site | wc -l > /number
The commands are executed with the /bin/sh -c
interpreter, which means that only the exit code of the last operation is evaluated.
The build step from the example above will produce a new image for as long as the wc -l
succeeds – even if the wget
command fails.
FROM ubuntu:16.04
USER root
RUN ...
FROM ubuntu:16.04
USER root
RUN ...
USER not-root
Changing USER
to root
creates a risk of unauthorized access into the container. As soon as the instruction that required root access has finished, it should be changed to an unpriviliged user.
FROM node:10.16.3-alpine
CMD ["npm","install","test"]
CMD ["node","test"]
FROM node:10.16.3-alpine
RUN npm install test
CMD ["node","test"]
Instructions like CMD
,HEALTHCHECK
and ENTRYPOINT
can only appear once in the Dockerfile. If used multiple times, only the last one will be executed.
COPY file .
ARG CODE_VERSION=latest
FROM base:${CODE_VERSION}
ARG CODE_VERSION=latest
FROM base:${CODE_VERSION}
According to the documentation, the only instruction that can appear before FROM
is ARG
.
COPY . .
RUN npm install
FROM node:10.16.3-alpine
COPY . .
RUN npm install
Every Dockerfile must contain FROM
instructions.
FROM node:10.16.3-alpine as build
COPY --from=build . .
FROM node:10.16.3-alpine as build
RUN ...
FROM node:10.16.3-alpine
COPY --from=build . .
Attempting to copy from the same image in which the instruction is executed will result in an error.
FROM node:10.16.3-alpine
RUN ...
FROM node:10.16.3-alpine
COPY --from=build . .
FROM node:10.16.3-alpine as build
RUN ...
FROM node:10.16.3-alpine
COPY --from=build . .
Attempting to copy from a non-existing image will result in an error.
FROM node:10.16.3-alpine
MAINTAINER me :)
FROM node:10.16.3-alpine
LABEL maintainer="me :)"
The MAINTAINER
instruction is deprecated and should not be used anymore. It is advised to use the LABEL
instruction instead.
FROM node:10.16.3-alpine
CMD ['node']
FROM node:10.16.3-alpine
CMD ["node"]
According to JSON syntax, the arguments in the table must be in double brackets.
FROM node:10.16.3-alpine
CMD node
FROM node:10.16.3-alpine
CMD ["node"]
If plain text is used for passing arguments, signals from the OS are not correctly passed to the executables, which is in the majority of the cases what you would expect.
FROM microsoft/windowsservercore
SHELL powershell -command
RUN Write-Host hello
FROM microsoft/windowsservercore
SHELL ["powershell", "-command"]
RUN Write-Host hello
According to the SHELL
syntax, arguments must be written in a JSON table.
FROM node:10.16.3-alpine as build
RUN ...
FROM node:10.16.3-alpine as build
RUN ...
FROM node:10.16.3-alpine as build1
RUN ...
FROM node:10.16.3-alpine as build2
RUN ...
Repeating a step name will result in an error.
FROM node:latest
FROM node:10.16.3-alpine
Using the latest
tag does not mean it is assigned to a specific image version.
The latest
tag can be used in case the image name refers to a previously defined alias.
FROM node
FROM node:10.16.3-alpine
Using the latest
tag does not mean it is assigned to a specific image version.
FROM node:10.16.3-alpine as build
RUN ...
FROM build
RUN ...
RUN apt-get update && apt-get install -y python
RUN apt-get update && apt-get install -y python \
&& apt-get clean \
&& rm -rf /var/lib/apt/lists/*
Removing apt-get
lists will decrease the size of the image. Note: the operation must be performed in the same RUN
instruction as the installation.
RUN cd /usr/src/app
WORKDIR /usr/scr/app
Most commands run with an absolute path and don't require changing the working directory. If you do need to change the directory, you should use the WORKDIR
instruction.
RUN sudo apt-get install
RUN apt-get install
Using sudo to provide permissions is not recommended as it may lead to unexpected behavior. It is advised to use a tool like gosu instead.
Command (ssh, vim, shutdown, service, ps, free, top, kill, mount, ifconfig)
does not make sense in a container.
FROM node:10.16.3-alpine
RUN vim
FROM node:10.16.3-alpine
Commands like ssh
, vim
, shutdown
, service
, ps
, free
, top
, kill
, mount
and ifconfig
should not be excecuted inside Docker containers.
FROM debian
RUN apt-get update && apt-get upgrade
FROM debian
RUN apt-get update
Linux distributions do not endure using apt
as the tool's interface may suffer changes between versions. It is advised to use apt-get
and apt-cache
instead as they are more stable.
Running apt-get upgrade
, dist-upgrade
or apk upgrade
is not recommended as some of the essential packages from the base images will not upgrade inside a container with no privileges. In case a package from the base image is outdated, it is advised to contact its maintainers.
If some package requires an upgrade, use apk --cache add packageName
instead of apk upgrade
.
ADD http://example.com/big.tar.xz /usr/src/things/
RUN tar -xJf /usr/src/things/big.tar.xz -C /usr/src/things
RUN make -C /usr/src/things all
RUN mkdir -p /usr/src/things \
&& curl -SL http://example.com/big.tar.xz \
| tar -xJC /usr/src/things \
&& make -C /usr/src/things all
Because image size matters, using ADD
to fetch packages from remote URLs is strongly discouraged. Instead, you should use curl
or wget
. That way you can delete the files you no longer need after they’ve been extracted and you don’t have to add another layer in your image.
COPY rootfs.tar.xz /usr/src/things
RUN tar -xJf /usr/src/things/big.tar.xz -C /usr/src/things
ADD rootfs.tar.xz /usr/src/things
Although both commands are similar in terms of functionality, it is advised to use COPY
instead of ADD
. COPY
only supports basic copying of local files into the container, while ADD
is better suited for local tar file auto-extraction into the image (e.g. ADD rootfs.tar.xz /.
)
FROM node:10.16.3-alpine
RUN vim
FROM node:10.16.3-alpine
Do not install two tools doing the same thing.
RUN ln -sfv /bin/bash /bin/sh
SHELL ["/bin/bash", "-c"]
Docker supports the SHELL
instruction which does not require overwriting /bin/sh
in the container.
RUN apt-get install python
RUN apt-get install -y python
The build might break without human intervention if the option -y/--assume-yes
is not applied.
RUN apt-get install -y python
RUN apt-get install -y --no-install-recommends python
Avoid installing additional packages that you did not explicitly want.
FROM python:3.4
ADD requirements.txt /usr/src/app/
FROM python:3.4
COPY requirements.txt /usr/src/app/
For other items (files, directories) that do not require ADD
’s tar auto-extraction capability, you should always use COPY
.
FROM node:10.16.3-alpine
COPY package.json yarn.lock my_app
FROM node:10.16.3-alpine
COPY package.json yarn.lock my_app/
If multiple resources are specified, either directly or due to the use of a wildcard, then it must be a directory and it must end with a slash /
.
FROM alpine:3.7
RUN apk add --update foo=1.0
&& rm -rf /var/cache/apk/*
FROM alpine:3.7
RUN apk --no-cache add foo=1.0
From Alpine Linux 3.3 onwards, a new --no-cache
option for apk
is available which allows users to install packages with an index that is updated and used on-the-fly and not cached locally. As a result, using --update
and removing /var/cache/apk/*
is no longer required during the package install.
RUN apt-get install python
RUN apt-get install python=2.7
Version pinning forces the build to retrieve a particular version regardless of the cache contents. It also reduce failures due to unanticipated changes in required packages.
RUN pip install django
RUN pip install django==1.9
Version pinning forces the build to retrieve a particular version regardless of the cache contents. It also reduce failures due to unanticipated changes in required packages.
RUN npm install express
RUN npm install express@4.1.1
Version pinning forces the build to retrieve a particular version regardless of the cache contents. It also reduce failures due to unanticipated changes in required packages.
RUN apk --no-cache add foo
RUN apk --no-cache add foo=1.2.3
Version pinning forces the build to retrieve a particular version regardless of the cache contents. It also reduce failures due to unanticipated changes in required packages.
RUN gem install bundler
RUN gem install bundler:1.1
Version pinning forces the build to retrieve a particular version regardless of the cache contents. It also reduce failures due to unanticipated changes in required packages.
ONBUILD ONBUILD ADD . /app/src
ONBUILD ADD . /app/src
Chaining ONBUILD
instructions using ONBUILD ONBUILD
isn’t allowed.
The ONBUILD
instruction may not trigger FROM
or MAINTAINER
instructions.
WORKDIR usr/src/app
WORKDIR /usr/src/app
Version pinning forces the build to retrieve a particular version regardless of the cache contents. It also reduce failures due to unanticipated changes in required packages.
EXPOSE 80000
EXPOSE 65535
https://en.wikipedia.org/wiki/List_of_TCP_and_UDP_port_numbers
from node:10.16.3-alpine
FROM node:10.16.3-alpine
According to the convention, names of instructions should be typed in uppercase.