携手创作,共同成长!这是我参与「掘金日新计划 · 8 月更文挑战」的第30天,点击查看活动详情
Dockerfile
- Dockerfile 是 Docker 中用于定义镜像自动化构建流程的配置文件
- 在 Dockerfile 中,包含了构建镜像过程中需要执行的命令和其他操作
- 它可以明确设定 Docker 镜像的制作过程,帮助我们在容器体系下能够完成自动构构建
使用 Dockerfile 构建镜像的步骤
- 编写一个 dockerfile 文件
- docker build 构建成为一个镜像
- docker run 运行镜像
- docker push 发布镜像(DockerHub 、阿里云仓库)
为什么要用 Dockerfile
- Dockerfile 是面向开发的,以后要发布项目,做镜像,就需要编写 dockerfile 文件
- Docker 镜像逐渐成企业交付的标准,必须要掌握!
- DockerFile 构建镜像文件,定义了一切的步骤,源代码
- Dockerfile 的体积小,容易进行快速迁移部署
- 环境构建流程记录在 Dockerfile 中,能够直观的看到镜像构建的顺序和逻辑
- Docker Images 通过 DockerFile 构建生成的镜像,最终发布和运行产品
- Docker 容器,镜像运行起来提供服务
Dockerfile 构建过程
- 每个保留关键字(指令)都是必须是大写字母
- 执行从上到下顺序
- #表示注释
- 每一个指令都会创建提交一个新的镜像层,并提交
简单的 Dockerfile 栗子
编写 dockerfile 文件
在任意目录创建一个 dockerfile 文件,输入以下命令
# 构建一个基于ubuntu的docker定制镜像
# 基础镜像
FROM ubuntu
# 镜像作者
MAINTAINER my_name polotest@domain.com
# 执行命令
## 换成国内的软件源
RUN sed -i 's/archive.ubuntu.com/mirrors.ustc.edu.cn/g' /etc/apt/sources.list
RUN sed -i 's/security.ubuntu.com/mirrors.ustc.edu.cn/g' /etc/apt/sources.list
## 安装nginx
RUN apt update >/dev/null 2>&1
RUN apt install nginx -y >/dev/null 2>&1
# 暴露对外端口
EXPOSE 80
执行 docker build
docker build --network=host -t ubuntu-nginx:v1 .
镜像的构建过程
[user@centos8 nginx]$ docker build --network=host -t ubuntu-nginx:v1 .
# 将上下文求发送给Docker引擎
Sending build context to Docker daemon 2.56kB
# 下载依赖的镜像
Step 1/7 : FROM ubuntu
latest: Pulling from library/ubuntu
d51af753c3d3: Pull complete
fc878cd0a91c: Pull complete
6154df8ff988: Pull complete
fee5db0ff82f: Pull complete
Digest: sha256:747d2dbbaaee995098c9792d99bd333c6783ce56150d1b11e333bbceed5c54d7
Status: Downloaded newer image for ubuntu:latest
# 生成镜像 1d622ef86b13
---> 1d622ef86b13
Step 2/7 : MAINTAINER my_name myemail@domain.com
# 运行容器 4eec6e3094f0,在容器内运行上面的这个命令,标记维护者信息
---> Running in 4eec6e3094f0
# 移除临时容器 4eec6e3094f0
Removing intermediate container 4eec6e3094f0
# 生成镜像 6679d1c204e3
---> 6679d1c204e3
Step 3/7 : RUN sed -i 's/archive.ubuntu.com/mirrors.ustc.edu.cn/g' /etc/apt/sources.list
# 运行容器84d38c20d8c4,在容器内运行上面的这个命令,更换软件源记录
---> Running in 84d38c20d8c4
# 移除临时容器 84d38c20d8c4
Removing intermediate container 84d38c20d8c4
# 生成镜像 83f29f7b055a
---> 83f29f7b055a
Step 4/7 : RUN sed -i 's/security.ubuntu.com/mirrors.ustc.edu.cn/g' /etc/apt/sources.list
# 运行容器 763e4493d93f, 在容器内运行上面的这个命令,更换软件源记录
---> Running in 763e4493d93f
# 移除临时容器 763e4493d93f
Removing intermediate container 763e4493d93f
# 生成镜像 6297f20605d9
---> 6297f20605d9
Step 5/7 : RUN apt update >/dev/null 2>&1
# 运行容器 2665a7e5a2e9,在容器内运行上面的这个命令, 更新软件源缓存
---> Running in 2665a7e5a2e9
# 移除临时容器 2665a7e5a2e9
Removing intermediate container 2665a7e5a2e9
# 生成镜像 fdfed940ca4d
---> fdfed940ca4d
Step 6/7 : RUN apt install nginx -y >/dev/null 2>&1
# 运行 容器 722a9a544643,在容器内运行上面的这个命令, 安装nginx
---> Running in 722a9a544643
# 移除临时容器 722a9a544643
Removing intermediate container 722a9a544643
# 生成镜像 6ee76f7df9e5
---> 6ee76f7df9e5
Step 7/7 : EXPOSE 80
# 运行容器 a12ed3216ee0,在容器内运行上面的这个命令, 暴露80端口
---> Running in a12ed3216ee0
# 移除临时容器 a12ed3216ee0
Removing intermediate container a12ed3216ee0
# 生成最终的镜像 7cf64279ba98
---> 7cf64279ba98
Successfully built 7cf64279ba98
# 将这个镜像标记命名 ubuntu-nginx 版本号v1
Successfully tagged ubuntu-nginx:v1
Dockerfile 就是将在文件中书写的构建指令,一层一层从 FROM 指定的基础镜像使用临时容器过渡,逐层叠加起来最终生成目标镜像
使用 docker history 查看镜像历史
[user@centos8 nginx]$ docker history ubuntu-nginx:v1
IMAGE CREATED CREATED BY SIZE COMMENT
7cf64279ba98 21 minutes ago /bin/sh -c #(nop) EXPOSE 80 0B
6ee76f7df9e5 21 minutes ago /bin/sh -c apt install nginx -y >/dev/null 2… 59.2MB
fdfed940ca4d 21 minutes ago /bin/sh -c apt update >/dev/null 2>&1 21.4MB
6297f20605d9 21 minutes ago /bin/sh -c sed -i 's/security.ubuntu.com/mir… 2.76kB
83f29f7b055a 21 minutes ago /bin/sh -c sed -i 's/archive.ubuntu.com/mirr… 2.76kB
6679d1c204e3 21 minutes ago /bin/sh -c #(nop) MAINTAINER my_name myemai… 0B
1d622ef86b13 2 weeks ago /bin/sh -c #(nop) CMD ["/bin/bash"] 0B
<missing> 2 weeks ago /bin/sh -c mkdir -p /run/systemd && echo 'do… 7B
<missing> 2 weeks ago /bin/sh -c set -xe && echo '#!/bin/sh' > /… 811B
<missing> 2 weeks ago /bin/sh -c [ -z "$(apt-get indextargets)" ] 1.01MB
<missing> 2 weeks ago /bin/sh -c #(nop) ADD file:a58c8b447951f9e30… 72.8MB
Dockerfile 的结构
Dockerfile 主要包含四部分内容:
- 基础镜像信息
- 维护者信息
- 镜像操作指令
- 容器启动时指令
可以将 Dockerfile 理解为一个由上往下执行指令的脚本文件
当调用构建命令,通过 Dockerfile 构建镜像时,Docker 会按照指令顺序进行对应的操作
简单的 Dockerfile 栗子二
FROM centos:latest
MAINTAINER polo
ENV MYPATH /usr/local
WORKDIR $MYPATH
RUN yum -y install vim
RUN yum -y install net-tools
EXPOSE 80
CMD echo $MYPATH
CMD echo "-----end----"
CMD /bin/bash
执行 docker build
docker build -f test.dockerfile -t test .
查看镜像和容器
docker build 命令详解
docker build 命令原理
- docker build 命令从 Dockerfile 和上下文构建镜像
- 构建的上下文:位于指定 PATH 或 URL 中的一组文件
- 构建过程可以引用上下文中的任何文件,例如,构建可以使用 COPY 指令来引用上下文中的文件
- PATH:就是本地文件系统上的一个目录路径
- URL:Git 地址
- 个人理解:以设置的上下文为根目录,在 dockerfile 中写的文件路径都会以这个上下文开始找
构建上下文是递归处理的
PATH 包含任何子目录,URL 包含 repository 及其子模块
简单的栗子
上下文为当前目录
也是最简单的 docker build 使用方式
docker build .
- 指定 PATH 为 . ,因此本地目录中的所有文件都会被延迟并发送到 Docker 守护程序
- PATH 指定在哪里可以找到 Docker 守护程序上构建的“上下文”的文件
- 请记住,守护进程可以在远程机器上运行,并且不会在客户端(运行 docker build 的地方)解析 Dockerfile
- 这意味着 PATH 中的所有文件都会被发送,而不仅仅是 Dockerfile 中列出的 ADD 文件
- 当看到 Sending build context 消息时,docker 客户端的意思是将上下文从本地机器传输到 Docker 守护进程。
构建由 Docker 守护程序(Daemon)运行
- 而不是 CLI(命令行)运行
- 构建过程做的第一件事是将整个上下文(递归)发送到守护进程
- 官方建议:将一个空目录作为上下文起点,并将 Dockerfile 保存在该目录中,仅添加构建 Dockerfile 所需的文件
特别注意
不要使用根目录 / 作为构建上下文的 PATH,因为会导致构建时,将硬盘驱动器的全部内容发送到 Docker 守护程序
逐一运行
- Docker 守护进程将逐一运行 Dockerfile 中的指令,如有必要,会将每条指令的结果提交到新镜像,最后会输出一个最新镜像的 ID
- Docker 守护进程将自动清理发送的上下文
- 重点:每条指令都是独立运行的,并会创建一个新镜像,因此像 RUN cd /tmp 不会对下一条自定产生任何影响
- 只要有可能,Docker 就会使用构建缓存来加速 Docker 构建过程,这由控制台输出中的 CACHED 消息指示
> docker build -t svendowideit/ambassador .
[internal] load build definition from Dockerfile 0.1s
=> transferring dockerfile: 286B 0.0s
[internal] load .dockerignore 0.1s
=> transferring context: 2B 0.0s
[internal] load metadata for docker.io/library/alpine:3.2 0.4s
CACHED [1/2] FROM docker.io/library/alpine:3.2@sha256:e9a2035f9d0d7ce 0.0s
CACHED [2/2] RUN apk add --no-cache socat 0.0s
exporting to image 0.0s
=> exporting layers 0.0s
=> writing image sha256:1affb80ca37018ac12067fa2af38cc5bcc2a8f09963de 0.0s
=> naming to docker.io/svendowideit/ambassador 0.0s
命令行参数
-f,--file
指定 dockerfile 路径
docker build -f /path/to/a/Dockerfile .
不指定的话,默认会读取上下文路径( . )下的 dockerfile
-t,--tag
指定构建的镜像名和 tag
docker build -t ubuntu-nginx:v1 .
构建的镜像指定多个 tag
docker build -t shykes/myapp:1.0.2 -t shykes/myapp:latest .
--add-host
可以使用一个或多个 --add-host 标志将其他主机添加到容器的 /etc/hosts 文件中
docker build --add-host=docker:10.180.0.1 .
--no-cache
构建镜像时不使用缓存
--network
在构建过程中为 RUN 指令设置网络模式
更多参数可以看官方文档