Dockerfile最佳实践


官网地址:https://docs.docker.com/develop/develop-images/dockerfile_best-practices/。

一个容器只运行一个进程

原因

  • 提供单独的扩展,仅对出现性能瓶颈的容器进行扩缩容,合理的利用资源。
  • 安全:避免当一个程序受到攻击入侵时,另一个程序直接暴露在危险之中。
  • 隔离:避免程序之间的资源竞争,合理的规划单个程序的资源限制。

不要在构建中升级版本

比如不建议在Ubuntu系统中使用apt-get upgrade。因为这个命令会把本地已安装的软件与软件列表中对应的软件进行对比,如果发现已安装的软件版本太低,就会提示更新,这样就会导致软件版本的不可控和最终构建镜像的不一致性。

将变化频率一样的RUN指令合一

RUN指令常用于安装软件包,建议把使用到的apt-get install命令合并在一起,其目的是为了更好的将镜像分层,避免带来不必要的成本。如下所示。

FROM nginx:latest

RUN apt-get update && \
    apt-get install -y iproute2 && \
    rm -rf /var/lib/apt/lists/*

使用特定的标签

建议指定特定的标签,如:14.04。因为默认的标签为:latest,当镜像更新时,标签将指向最新的镜像,这将导致最终构建镜像不一致或者有可能失败。

FROM ubuntu:14.04

删除多余的文件

当我们更新了apt-get源,下载解压并安装了一些软件包,它们都保存在"/var/lib/apt/lists/“目录中。但是,运行应用时Docker镜像中并不需要这些文件。通过删除”/var/lib/apt/lists/"目录实现清理apt cache。
除此之外,在使用Dockerfile过程中应及时清理不必要的文件,如安装包、压缩包等。参考网址:https://blog.csdn.net/qq_38556887/article/details/124431586。

RUN apt-get update && apt-get install -y nginx && rm -rf /var/lib/apt/lists/*

选择合适的基础镜像

尽可能的使用对应部署环境的官方镜像(https://hub.docker.com)。对于一些不需要部署环境的镜像,建议使用 Alpine镜像,因为它非常的小(目前不足6MB)但确是一个完整的Linux发行版,非常适合作为基础镜像。

FROM node:7-alpine

设置WORKDIR和CMD

建议使用绝对路径作为工作目录,因为这读起来更加清晰明确。
同时,这将导致之后RUN/CMD/ENTRYPOINT指令默认在工作目录执行。

WORKDIR /opt/project/npm
CMD ["npm","start"]

使用ENTRYPOINT(可选)

可以将ENTRYPOINT指令作为容器的默认执行命令,用CMD作为参数,让docker用来就像systemctl一样方便。

ENTRYPOINT ["./entrypoint.sh"]
CMD ["start"]

docker run start

在entrypoint脚本中使用exec

在上面的./entrypoint.sh中如果存在exec的命令执行,该命令将是容器中pid为1的进程。

优先使用COPY

COPY相较于ADD,更加透明可控。COPY仅支持基础的文件从本地到容器的移动,而ADD会把压缩包解压。ADD更适合于从压缩包中提取数据到容器。

合理调整COPY和RUN的顺序

将不易变化的部分先COPY,然后执行RUN命令,最后COPY剩余的部分。

设置默认的环境变量、映射端口和数据卷

  • ENV指令指定的环境变量在容器中可以使用。
  • ARG指令指定的变量仅在构建镜像时生效。
ENV PATH=/usr/local/nginx/bin:$PATH

使用EXPOSE暴露端口

EXPOSE指令可用于指定容器将要监听的端口。

多阶段构建

多阶段构建可以极大的降低镜像的大小,减少层数。例如我们可以使用第一个镜像完成编译构建过程,将产物传输到第二个镜像形成镜像包,实现构建与部署的解耦。

# syntax=docker/dockerfile:1
FROM golang:1.16-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"]

使用VOLUME管理数据卷

VOLUME指令可以用于暴露任何数据库存储文件、配置文件或容器创建的文件和目录。

使用LABEL设置镜像元数据

合理的使用LABEL对镜像做一些标注,如发行版本、证书信息、联系方式等。

添加HEALTHCHECK

编写.dockerignore文件

功能类似.gitignore。

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值