Sample Dockerfile 1
# NOTE: this example is taken from the default Dockerfile for the official nginx Docker Hub Repo
# https://hub.docker.com/_/nginx/
# NOTE: This file is slightly different then the video, because nginx versions have been updated
# to match the latest standards from docker hub... but it's doing the same thing as the video
# describes
FROM debian:stretch-slim
# all images must have a FROM
# usually from a minimal Linux distribution like debain or (even better) alpine
# if you truly want to start with an empty container, use FROM scratch
ENV NGINX_VERSION 1.13.1-1~stretch
ENV NJS_VERSION 1.13.1.0.1.10-1~stretch
# optional environment variable that's used in later lines and set as envvar when container is running
RUN apt-get update \
&& apt-get install --no-install-recommends --no-install-suggests -y gnupg1 \
&& \
NGINX_GPGKEY=573BFD6B3D8FBC641079A6ABABF5BD827BD9BF62; \
found=''; \
for server in \
ha.pool.sks-keyservers.net \
hkp://keyserver.ubuntu.com:80 \
hkp://p80.pool.sks-keyservers.net:80 \
pgp.mit.edu \
; do \
echo "Fetching GPG key $NGINX_GPGKEY from $server"; \
apt-key adv --keyserver "$server" --keyserver-options timeout=10 --recv-keys "$NGINX_GPGKEY" && found=yes && break; \
done; \
test -z "$found" && echo >&2 "error: failed to fetch GPG key $NGINX_GPGKEY" && exit 1; \
apt-get remove --purge -y gnupg1 && apt-get -y --purge autoremove && rm -rf /var/lib/apt/lists/* \
&& echo "deb http://nginx.org/packages/mainline/debian/ stretch nginx" >> /etc/apt/sources.list \
&& apt-get update \
&& apt-get install --no-install-recommends --no-install-suggests -y \
nginx=${NGINX_VERSION} \
nginx-module-xslt=${NGINX_VERSION} \
nginx-module-geoip=${NGINX_VERSION} \
nginx-module-image-filter=${NGINX_VERSION} \
nginx-module-njs=${NJS_VERSION} \
gettext-base \
&& rm -rf /var/lib/apt/lists/*
# optional commands to run at shell inside container at build time
# this one adds package repo for nginx from nginx.org and installs it
RUN ln -sf /dev/stdout /var/log/nginx/access.log \
&& ln -sf /dev/stderr /var/log/nginx/error.log
# forward request and error logs to docker log collector
EXPOSE 80 443
# expose these ports on the docker virtual network
# you still need to use -p or -P to open/forward these ports on host
CMD ["nginx", "-g", "daemon off;"]
# required: run this command when container is launched
# only one CMD allowed, so if there are multiple, last one wins
Output of 'docker image build'
- Each step is a command in above Dockerfile
- Hashes
- Each step has assigned a hash that is stored in docker cache
- Next time we build this image it will use built layers for lines of Dockerfile that were not changed
- This is possible thanks to union filesystem mentioned earlier
- Saves consecutive build times rapidly
- When you change only source code of your application but not Docker Image itself, Docker knows that rebuilding of the entire image is not needed and it rebuilds only parts from change down.
- For this reason is important to put steps that are changing often close to bottom in the file
- For example source code or your application binary
~> docker image build -t customnginx .
Sending build context to Docker daemon 4.096kB
Step 1/7 : FROM debian:stretch-slim
stretch-slim: Pulling from library/debian
afeb2bfd31c0: Already exists
Digest: sha256:b4c6e46603728bdc550c9075be78439c45a0d509008770ad3775d097f28b6cca
Status: Downloaded newer image for debian:stretch-slim
---> 28b28a662057
Step 2/7 : ENV NGINX_VERSION 1.13.1-1~stretch
---> Running in 6d83ac829dc3
---> 5884c10b6d1a
Removing intermediate container 6d83ac829dc3
Step 3/7 : ENV NJS_VERSION 1.13.1.0.1.10-1~stretch
---> Running in 2caf53b6fe5d
---> 19525e41b7da
Removing intermediate container 2caf53b6fe5d
Step 4/7 : RUN apt-get update && apt-get install --no-install-recommends --no-install-suggests -y gnupg1 &&
NGINX_GPGKEY=573BFD6B3D8FBC641079A6ABABF5BD827BD9BF62; found=''; for server in ha.pool.sks-keyservers.net hkp://keyserver.ubuntu.com:80 hkp://p80.pool.sks-keyservers.net:80 pgp.mit.edu
; do echo "Fetching GPG key $NGINX_GPGKEY from $server"; apt-key adv --keyserver "$server" --keyserver-options timeout=10 --recv-keys "$NGINX_GPGKEY" && found=yes && break; done; test -z "$found" && echo >&2 "error: failed to fetch GPG key $NGINX_GPGKEY" && exit 1; apt-get remove --purge -y gnupg1 && apt-get -y --purge autoremove && rm -rf /var/lib/apt/lists/* && echo "deb http://nginx.org/packages/mainline/debian/ stretch nginx" >> /etc/apt/sources.list && apt-get update && apt-get install --no-install-recommends --no-install-suggests -y nginx=${NGINX_VERSION} nginx-module-xslt=${NGINX_VERSION} nginx-module-geoip=${NGINX_VERSION}
nginx-module-image-filter=${NGINX_VERSION}
nginx-module-njs=${NJS_VERSION} gettext-base && rm -rf /var/lib/apt/lists/*
---> Running in 342040963d0a
~~~ OUTPUT OMITTED ~~~
---> 0106e4203a77
Removing intermediate container 342040963d0a
Step 5/7 : RUN ln -sf /dev/stdout /var/log/nginx/access.log && ln -sf /dev/stderr /var/log/nginx/error.log
---> Running in db911dcb69a8
---> bf7660001493
Removing intermediate container db911dcb69a8
Step 6/7 : EXPOSE 80 443
---> Running in 6888dbb37349
---> 875335f00273
Removing intermediate container 6888dbb37349
Step 7/7 : CMD nginx -g daemon off;
---> Running in 65b95a494f7d
---> 9d3746985fad
Removing intermediate container 65b95a494f7d
Successfully built 9d3746985fad
Successfully tagged customnginx:latest
Image was built
~> docker image ls
REPOSITORY TAG IMAGE ID CREATED SIZE
customnginx latest 9d3746985fad 4 minutes ago 107MB
When building Linux Docker Image from Windows Machine you may get this warning at the end
SECURITY WARNING: You are building a Docker image from Windows against a non-Windows Docker host. All files and directories added to build context will have '-rwxr-xr-x' permissions. It is recommended to double check and reset permissions for sensitive files and directories.
Changes to Dockerfile
- Let's add additional exposed port in Dockerfile
# ...
EXPOSE 80 443 8080
# ...
- New build process is way shorter and we can see that it reuses the cached hashes
~> docker image build -t customnginx .
Sending build context to Docker daemon 4.096kB
Step 1/7 : FROM debian:stretch-slim
---> 28b28a662057
Step 2/7 : ENV NGINX_VERSION 1.13.1-1~stretch
---> Using cache
---> 5884c10b6d1a
Step 3/7 : ENV NJS_VERSION 1.13.1.0.1.10-1~stretch
---> Using cache
---> 19525e41b7da
Step 4/7 : RUN apt-get update && apt-get install --no-install-recommends --no-install-suggests -y gnupg1 &&
NGINX_GPGKEY=573BFD6B3D8FBC641079A6ABABF5BD827BD9BF62; found=''; for server in ha.pool.sks-keyservers.net hkp://keyserver.ubuntu.com:80 hkp://p80.pool.sks-keyservers.net:80 pgp.mit.edu
; do echo "Fetching GPG key $NGINX_GPGKEY from $server"; apt-key adv --keyserver "$server" --keyserver-options timeout=10 --recv-keys "$NGINX_GPGKEY" && found=yes && break; done; test -z "$found" && echo >&2 "error: failed to fetch GPG key $NGINX_GPGKEY" && exit 1; apt-get remove --purge -y gnupg1 && apt-get -y --purge autoremove && rm -rf /var/lib/apt/lists/* && echo "deb http://nginx.org/packages/mainline/debian/ stretch nginx" >> /etc/apt/sources.list && apt-get update && apt-get install --no-install-recommends --no-install-suggests -y nginx=${NGINX_VERSION} nginx-module-xslt=${NGINX_VERSION} nginx-module-geoip=${NGINX_VERSION}
nginx-module-image-filter=${NGINX_VERSION}
nginx-module-njs=${NJS_VERSION} gettext-base && rm -rf /var/lib/apt/lists/*
---> Using cache
---> 0106e4203a77
Step 5/7 : RUN ln -sf /dev/stdout /var/log/nginx/access.log && ln -sf /dev/stderr /var/log/nginx/error.log
---> Using cache
---> bf7660001493
Step 6/7 : EXPOSE 80 443 8080
---> Running in 4f256cb5496a
---> ad8ca3aa8ca7
Removing intermediate container 4f256cb5496a
Step 7/7 : CMD nginx -g daemon off;
---> Running in 11c570471a04
---> aec83921eca4
Removing intermediate container 11c570471a04
Successfully built aec83921eca4
Successfully tagged customnginx:latest