Dockerfile best practices have emerged in the official document addresses Best Practices for Writing Dockerfiles . If you write a best practice, somewhat Guan Gong in front of the masters of Italy. So this article is a translation of the official document, understand, extend and complement the example
Container should be short-lived
By Dockerfile
container constructed mirroring start should be as brief (ephemeral). Short means that you can quickly start and termination
Use .dockerignore exclude unrelated to build file
.dockerignore
Grammar and .gitignore
consistent syntax. Use it to build files and directories to exclude unrelated, such asnode_modules
Construction of multi-stage
Construction of multi-stage can effectively reduce the volume of the mirror, in particular for the required language compiler, the application of a build process often follows
- Installation compilation tools
- Install third-party library dependencies
- Compile build applications
The first two steps have a lot of redundant volume mirroring, using a multi-stage build avoid this problem
This building is Go
an example of application of
FROM golang:1.11-alpine AS build
# Install tools required for project
# Run `docker build --no-cache .` to update dependencies
RUN apk add --no-cache git
RUN go get github.com/golang/dep/cmd/dep
# List project dependencies with Gopkg.toml and Gopkg.lock
# These layers are only re-built when Gopkg files are updated
COPY Gopkg.lock Gopkg.toml /go/src/project/
WORKDIR /go/src/project/
# Install library dependencies
RUN dep ensure -vendor-only
# Copy the entire project and build it
# This layer is rebuilt when a file changes in the project directory
COPY . /go/src/project/
RUN go build -o /bin/project
# This results in a single layer image
FROM scratch
COPY --from=build /bin/project /bin/project
ENTRYPOINT ["/bin/project"]
CMD ["--help"]
This is an example of constructing a front end application, you can refer to how to efficiently deploy the distal end application docker
FROM node:10-alpine as builder
ENV PROJECT_ENV production
ENV NODE_ENV production
# http-server 不变动也可以利用缓存
WORKDIR /code
ADD package.json /code
RUN npm install --production
ADD . /code
RUN npm run build
# 选择更小体积的基础镜像
FROM nginx:10-alpine
COPY --from=builder /code/public /usr/share/nginx/html
Avoid unnecessary installation package
Reduced size, reduced build time. The front-end application using the npm install --production
apparatus depends only production package.
Do one thing at a container
As a web application will contain three parts, web services, database and cache. Decoupling them into a plurality of containers, convenient scale. If you need to network traffic, you can bring them as to the next network.
As in my personal server, I used traefik
to do load balancing and service discovery, applications and databases are all traefik_default
under the network, details refer to the use of traefik do load balancing and service discovery
version: '3'
services:
# 该镜像会暴露出自身的 `header` 信息
whoami:
image: containous/whoami
restart: always
labels:
# 设置Host 为 whoami.docker.localhost 进行域名访问
- "traefik.http.routers.whoami.rule=Host(`whoami.docker.localhost`)"
# 使用已存在的 traefik 的 network
networks:
default:
external:
name: traefik_default
Mirroring reduce the number of layers
- Only
RUN
,COPY
,ADD
will create a number of layers, other instructions will not increase the volume mirroring - Whenever possible, use multi-stage build
Installation depends the following methods
RUN yum install -y node python go
Mounting the wrong way dependent, this will increase the number of layers of the mirror
RUN yum install -y node
RUN yum install -y python
RUN yum install -y go
The multi-line ordering parameters
And ease of readability accidentally repeating dispenser package
RUN apt-get update && apt-get install -y \
bzr \
cvs \
git \
mercurial \
subversion
Full use of the building Cache
During the construction of the mirror docker
traverses Dockerfile
all of the instructions in the file, sequentially. For each instruction, docker
will find whether the existing reusable mirrored in the cache, otherwise it will create a new image
We can use the docker build --no-cache
skip caching
ADD
AndCOPY
will calculate the filechecksum
has changed to decide whether to use the cacheRUN
Just to see if the command string cache hit, asRUN apt-get -y update
there may be a problem
As an node
application, first copy can package.json
be dependent on the installation, and then add the entire directory, can be done to fully utilize the cache.
FROM node:10-alpine as builder
WORKDIR /code
ADD package.json /code
# 此步将可以充分利用 node_modules 的缓存
RUN npm install --production
ADD . /code
RUN npm run build