使用 Dockerfile 定制镜像
Dockerfile 简介
通过上篇教程对 docker commit
的学习,我们可以了解到,镜像的定制实际上就是定制每一层所添加的配置、文件。如果我们可以把每一层修改、安装、构建、操作的命令都写入一个脚本,用这个脚本来构建、定制镜像,那么之前提及的无法重复的问题、镜像构建透明性的问题、体积的问题就都会解决。
而这个脚本就是 Dockerfile
。Dockerfile
是一个文本文件,其内包含了一条条的指令,每一条指令构建一层,因此每一条指令的内容,就是描述该层应当如何构建。
如果我们通过 Dockerfile
来构建上篇教程 docker commit
完成的事情,可以这么编写指令:
FROM nginx
RUN echo '<h1>Hello, Docker!</h1>' > /usr/share/nginx/html/index.html
这里面涉及到 Dockerfile
的两条最基本指令,FROM
和 RUN
:
FROM
用于指定基础镜像,表示定制镜像基于此基础镜像构建,常见的基础镜像有nginx
、php
、mysql
、go
、ubuntu
、alpine
等,FROM
是Dockerfile
的必备指令,并且必须是第一条指令;RUN
用来执行命令行命令,由于命令行的强大能力,因此它是定制镜像时最常用的指令,RUN
有两种格式:shell 格式(RUN <shell命令>
)和 exec 格式(RUN ["可执行文件", "参数1", "参数2"
,有点像函数调用)。
对于复杂的构建指令,可以像下面这样编写:
FROM debian:jessie
RUN buildDeps='gcc libc6-dev make' \
&& apt-get update \
&& apt-get install -y $buildDeps \
&& wget -O redis.tar.gz "http://download.redis.io/releases/redis-3.2.5.tar.gz"; \
&& mkdir -p /usr/src/redis \
&& tar -xzf redis.tar.gz -C /usr/src/redis --strip-components=1 \
&& make -C /usr/src/redis \
&& make -C /usr/src/redis install \
&& rm -rf /var/lib/apt/lists/* \
&& rm redis.tar.gz \
&& rm -r /usr/src/redis \
&& apt-get purge -y --auto-remove $buildDeps
在撰写 Dockerfile
的时候,要经常提醒自己,这并不是在写 Shell 脚本,而是在定义每 一层该如何构建,而且要确保每一层只添加真正需要添加的东西,任何无关的东西都应该清理掉,如果每条 RUN
指令都只执行一个 shell 脚本,会造成很多不必要的中间内容被装进镜像,导致镜像层级很多,体积臃肿,构建缓慢,这是初学者常犯的错误。
构建镜像
通过 Dockerfile
构建镜像需要在 Dockerfile
文件所在目录执行 docker build
命令,Dockerfile
中可以配置多个镜像,我们可以在构建时通过指定镜像名来构建指定镜像:
注:
-t
表示镜像名包含标签,如果没有标签,可以省略,最后面的.
号表示镜像构建的上下文目录(Dockerfile
中的相对路径都以此目录作为前缀),默认是当前目录。
我们可以通过命令输出清晰看到镜像构建过程,构建完成后,可以通过 docker run
来启动这个镜像:
docker run --name web3 -d -p 82:80 nginx:v3
此外,docker build
还有其他一些非常规的用法:
- 直接用 Git repo 进行构建:
docker build https://github.com/twang2218/gitlab-ce-zh.git#:8.14
; - 用给定的 tar 压缩包构建:
docker build http://server/context.tar.gz
; - 从标准输入中读取
Dockerfile
进行构建:docker build - < Dockerfile 或者 cat Dockerfile | docker build -
; - 从标准输入中读取上下文压缩包进行构建:
docker build - < context.tar.gz
。
No Comments