Please enable Javascript to view the contents

你不知道的 Docker 使用技巧

 ·  ☕ 2 分钟

1. 分阶段构建

编译项目需要借助一系列特定的工具,但在运行阶段并不需要这些工具。为了减小镜像体积,可以分阶段构建。在第一阶段进行构建,然后将编译生成的文件传入下一个阶段,生成更小体积的镜像。

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
FROM golang:1.12 as builder

COPY / /go/src/github.com/shaowenchen/goproject

WORKDIR /go/src/github.com/shaowenchen/goproject
RUN CGO_ENABLED=0 GO111MODULE=on GOOS=linux GOARCH=amd64 GOFLAGS=-mod=vendor go build -i -ldflags '-w -s' -o myserver cmd/myserver/apiserver.go

FROM alpine:3.9
RUN apk add --update ca-certificates && update-ca-certificates
COPY --from=builder /go/src/github.com/shaowenchen/goproject/myserver /usr/local/bin/
CMD ["sh"]

上面是一个编译 Go 工程镜像的 Dockerfile 文件。很多项目选择 alpine 作为基础镜像。但是,如果项目使用到系统的某些库,基础镜像不能随意选择。

2. 利用缓存构建

Docker 镜像是分层的结构,最多 127 层。除了 FROM 命令,Dockerfile 中其他命令都会生成一个新的镜像层。在构建过程中,如果发现命令将产生的镜像层与之前的一样,则会使用缓存复用。

为了利用缓存加速构建过程,可以将静态和配置命令放在前面,而将经常变化的内容放在后面。

1
2
3
4
5
6
FROM stackaero/nodejs-pm2-slim:1.1.5
WORKDIR /app
COPY package.json /app/
RUN npm install
COPY . /app/
CMD pm2 start ./index.js --no-daemon >> /dev/null

由于项目工程代码每次构建时,总会发生变化,应该尽量放在底部;依赖包不会经常发生变化,放在上面可以充分利用缓存。

使用下面的构建命令,可以禁用缓存:

1
docker build --no-cache

3. 使用 S2I 打包应用

相对于使用缓存优化构建速度,更加简单的方式是,使用 S2I 打包应用,增加一层镜像即可。

参考链接:使用 S2I 构建云原生应用

没有被 S2I 支持的语言或框架也没关系,我们可以将应用所需的基础环境打包成基础镜像,然后再进行构建。

4. .dockerignore 文件

Docker 以 C/S 模型进行工作,在执行构建时,会将所需的文件发送到 Docker Daemon 。有些很大、构建用不上的文件,会占用传输时间,我们可以定义 .dockerignore 忽略这些文件,就像 .gitignore 一样。

.dockerignore 文件

.git

Dockerfile 文件

1
2
3
FROM golang:1.12 as builder

COPY / /go/src/github.com/shaowenchen/goproject

上面的例子,COPY 时会忽略 .git 目录。

5. 将容器保存为镜像

在学习 Docker 时,经常会被教育不要在容器中做任何修改。这句话没错,遵循不可变的基础设施。

除了打包镜像,我们会直接进入容器进行调试。有时因为历史原因,找不到镜像或 Dockerfile 文件,需要将容器保存为镜像。

执行 docker commit 命令,可以将 ContainerID 保存为 shaowenchen/myimage:latest 镜像。

1
docker commit ContainerID  shaowenchen/myimage:latest

微信公众号
作者
微信公众号