写Dockerfile的一些技巧 (2)

CMD和ENTRYPOINT指令指定了容器运行的默认命令,推荐二者结合使用。使用exec格式ENTRYPOINT指令设置固定的默认命令和参数,然后使用CMD指令设置可变的参数。 ​

不要在Dockerfile中做端口映射

Docker的两个核心概念是可重复性和可移植性,镜像应该可以在任何主机上运行多次。映射端口会破坏镜像的可移植性,且这样的镜像只能在一台主机上启动一个容器。所以端口映射应在docker run命令中用-p参数指定。

# 不要在Dockerfile中做如下映射 EXPOSE 80:8080 # 仅仅暴露80端口,需要另做映射 EXPOSE 80 使用多阶段构建

在 Docker 17.05 以上版本中,你可以使用 多阶段构建 来减少所构建镜像的大小; ​

避免安装不必要的包

为了降低复杂性、减少依赖、减小文件大小、节约构建时间,你应该避免安装任何不必要的包。例如,不要在数据库镜像中包含一个文本编辑器。 ​

一个容器只运行一个进程

应该保证在一个容器中只运行一个进程。将多个应用解耦到不同容器中,保证了容器的横向扩展和复用。例如 web 应用应该包含三个容器: web应用.数据库,缓存; 如果容器互相依赖,你可以使用 Docker 自定义网络 来把这些容器连接起来。

镜像层数尽可能少

你需要在 Dockerfile 可读性(也包括长期的可维护性)和减少层数之间做一个平衡;

用python -m pip而不是pip

这是为了确保我们使用的 pip 是我们想用的那个 python 对应的 pip。有时候,一个系统里安装了 Python 2 和 Python 3,而我们可能错误地设置了 PATH 环境变量(或则因为其他的原因),导致我们运行 python 命令的时候,启动的 Python 3(或者 2),但是 pip 命令是 Python 2(或者3)的 pip。还有一些其他原因使我们更应该用 python -m pip 的,详见 https://snarky.ca/why-you-should-use-python-m-pip/

一个典型的例子(升级 pip) python -m pip install --quiet --upgrade pip 让pip install 更安静

上例中,在 pip install 命令里,我们用了 --quiet 参数,减少 pip install 打印出来的信息。这样可以让 docker build 更安静。尤其是,如果在 CI 里运行 docker build 的话,减少打印信息可以让 CI log 更加可读。

让apt-get install 更安静

类似的,用 apt-get 安装软件包的时候,我们用 -qq 命令,甚至重定向输出到 /dev/null 让它更安静。

apt-get -qq update apt-get -qq install -y curl > /dev/null 让curl和wget更安静

首先,如果要下载文件,curl 和 wget 二选一即可。如果用 curl,可以用 --silent 参数

curl -sLO https://storage.googleapis.com/minikube/releases/latest/minikube-linux-amd64

wget 有 --quiet 参数

wget -q https://storage.googleapis.com/minikube/releases/latest/minikube-linux-amd64 用axel而不是curl或wget

作为一个开源软件,中外开发者都会运行 docker build。开发者所处的地理位置不同,各自都希望从距离自己最近(最快)的 mirror 下载和安装文件。axel 可以从多个 mirror 下载同一个文件,根据各个 mirror 的速度,决定分别从不同 mirror 下载的字节数量。如果有的 mirror 挂了,axel 可以忽略之。尤其对于身处国内的开发者,axel 完全可以取代 curl 以及 wget;

axel 和 wget 一样支持 --quiet 参数。以下是一个从大洋两岸的 mirrors 下载 Go 编译器的例子;

echo "Install Go compiler ..."GO_MIRROR_0="http://mirrors.ustc.edu.cn/golang/go1.13.4.linux-amd64.tar.gz"GO_MIRROR_1="https://dl.google.com/go/go1.13.4.linux-amd64.tar.gz"axel --quiet --output go.tar.gz $GO_MIRROR_0 $GO_MIRROR_1````````````````````` 让python setup.py更安静

有时候我们会在 Dockerfile 里 build 和 install Python packages,此时我们需要运行

python ./setup.py build --quietpython ./setup.py install --quiet

不过如果我们要 build binary distribution package,则需要注意使用全局参数 --quiet

python ./setup.py --quiet bdist_wheel 明辨ARG和ENV

ARG 和 ENV 是 Dockerfile 里用来定制化 Docker image 的利器,经常结合在一起使用,也常领 Dockerfile 新手挠头。其实,记住一下几条规则,基本就可以了; ​

ARG 存在于 docker build 命令执行期间。默认值写在 Dockerfile 里。如果需要修改,可以通过 docker build 命令里的 --build-arg 参数来指定。

ENV 存在于 docker run 命令执行期间。默认值写在 Dockerfile 里。如果要修改,可以通过 docker run 命令的 --env 参数来指定。

如果要把 ARG 的值保存到 container 运行起来之后仍然可以可用,则需要在 ARG 之后写一个 ENV。

为了方便理解,请看下面几个例子。第一个例子:为了把 ARG 的值保存到 docker run 的时候也可以被用到,我们把它写入一个文件 /root/hello.sh; ​

FROM ubuntu:18.04ARG releaser=youmenRUN echo "echo $releaser" > /root/hello.shRUN chmod +x /root/hello.sh

内容版权声明:除非注明,否则皆为本站原创文章。

转载注明出处:https://www.heiqu.com/zzpjwf.html