Dockerfile 是一个文本文件,其内包含了一条条的指令(Instruction),每一条指令构建一层,因此每一条指令的内容,就是描述该层应当如何构建。
在本机上登陆你的 Docker 账户,以便之后发布使用,如果没有请到https://cloud.docker.com/ 注册一个。本机登陆命令:
docker login
所谓定制镜像,那一定是以一个镜像为基础,在其上进行定制。本部分以一个简单的 web 服务器为例,记录定制镜像的操作步骤。首先,新建一个文件夹 newdocker 并进入:
mkdir newdocker && cd newdocker
然后在当前目录新建一个 Dockerfile 文件,内容如下所示:
# Dockerfile # 使用 Python 运行时作为基础镜像 FROM python:2.7-slim # 设置 /app 为工作路径 WORKDIR /app # 将当前目录所有内容复制到容器的 /app 目录下 ADD . /app # 安装 requirements.txt 中指定的包 RUN pip install --trusted-host pypi.python.org -r requirements.txt # 对容器外开放80端口 EXPOSE 80 # 定义环境变量 ENV NAME World # 当容器启动时运行 app.py CMD ["python", "app.py"]
以上内容中,我们用FROM指定基础镜像,在Docker Store 上有非常多的高质量的官方镜像,服务类镜像如 nginx、redis、mongo、mysql、httpd、php、tomcat 等;各种语言应用镜像如 node、openjdk、python、ruby、golang 等;操作系统镜像如 ubuntu、debian、centos、fedora、alpine。除了选择现有镜像为基础镜像外,Docker 还存在一个特殊的镜像,名为 scratch。直接FROM scratch会让镜像体积更加小巧。
RUN指令是用来执行命令行命令的。由于我们的例子中只有一行 RUN 代码,我们来看看多行 RUN 的情况,如下代码所示:
RUN apt-get update RUN apt-get install -y gcc libc6-dev make RUN wget -O redis.tar.gz "http://download.redis.io/releases/redis-3.2.5.tar.gz" RUN mkdir -p /usr/src/redis RUN tar -xzf redis.tar.gz -C /usr/src/redis --strip-components=1 RUN make -C /usr/src/redis RUN make -C /usr/src/redis install
Dockerfile 中每一个指令都会建立一层,RUN 也不例外。每一个 RUN 的行为,就和刚才我们手工建立镜像的过程一样:新建立一层,在其上执行这些命令,执行结束后,commit 这一层的修改,构成新的镜像。
而上面的这种写法,创建了 7 层镜像。这是完全没有意义的,而且很多运行时不需要的东西,都被装进了镜像里,比如编译环境、更新的软件包等等。结果就是产生非常臃肿、非常多层的镜像,不仅仅增加了构建部署的时间,也很容易出错。 这是很多初学 Docker 的人常犯的一个错误。
正确的写法应该这样:
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
值得注意的是最后添加了清理工作的命令,删除了为了编译构建所需要的软件,清理了所有下载、展开的文件,并且还清理了 apt 缓存文件。
好了,以上内容走的有些远,我们回到 Dockerfile。