Table of Contents

Dockerfile基础

之前写过的例子:https://github.com/GZhonghui/docker_samples


基础理解

哪些命令是build(构建镜像)的时候执行的?只会执行一次,比如COPY/RUN。
哪些命令是run(启动容器)的时候执行的?每次run都会执行,比如CMD(用于启动服务程序)。
TODO:总结一下

基础命令

TODO

例:从Linux开始构建环境

https://github.com/GZhonghui/docker_samples/tree/master/01_setup_python_env

例:从Python开始打包APP

https://github.com/GZhonghui/docker_samples/tree/master/02_python_app

例:使用Compose创建简单集群

https://github.com/GZhonghui/docker_samples/tree/master/03_docker_compose

硬件架构

构建的时候,需要区分CPU架构吗?

镜像标识

如何唯一标识一个镜像?

  1. 一个Name + 一个Tag(如果需要上传到DockerHub,还需要用户名来区分不同的人上传的镜像)
  2. Name很好理解。关键是Tag,实际上Tag是一个字符串,不一定是[x.y.z]的格式。
  3. 常见的latest也只是一个普通的Tag,不是所有的镜像都有latest这个Tag。
  4. 只是开发者在build的时候,手动添加了这个Tag而已。
  5. 当build新版本的时候,比如构建了xxx:2.0版本,顺便再用最新的内容重新构建一下xxx:latest。
  6. 也就是说一个Tag对应的镜像是可以被更新、替代的。(用户使用 docker pull 重新拉取一遍以更新?)
  7. 通过这样手动的操作,让latest标签一直指向最新的内容。
  8. 所以:这个标签不是自动表示「最新」的。
  9. 我个人不是很建议使用latest这个标签,有点迷惑。

构建命令

# 常用的构建命令
# 使用 -t 指定镜像的 name:tag,一定要养成写 tag 的好习惯!
docker build -t dj:1.0.0 .

体积控制

Docker 每条指令都会生成一层(layer),但镜像体积取决于每层引入/保留下来的文件数据,而不是层数本身。把命令拆开并不会“自动让镜像变大”;真正让镜像变大的,是在较早的层里写入了临时文件或缓存,然后在后续层才删除:这些被删除的文件仍然占据镜像空间(它们只是被“遮蔽”,没有真的消失)。

RUN/COPY/ADD 会创建新层;ENV/WORKDIR 这类大多只是元数据,几乎不增加体积。

同一层里创建并清理临时文件才能避免膨胀。

# 反例(更胖):
RUN apt-get update
RUN apt-get install -y build-essential
RUN rm -rf /var/lib/apt/lists/*
 
# 正例(更瘦):
# 因为“清理缓存”发生在同一层里。
RUN apt-get update \
    && apt-get install -y --no-install-recommends build-essential \
    && rm -rf /var/lib/apt/lists/*