使用Dockerfile创建镜像

2023-12-24  本文已影响0人  mini鱼

1、 Dockerfile基本结构

Dockerfile由一行行命令语句组成,并且支持以#开头的注释行。
一般而言,Dockerfile分为四部分:基础镜像信息、维护者信息、镜像
操作指令和容器启动时执行指令。例如:

# This Dockerfile uses the ubuntu image
# VERSION 2 - EDITION 1
# Author: docker_user
# Command format: Instruction [arguments / command] ..
# Base image to use, this must be set as the first line
FROM ubuntu
# Maintainer: docker_user <docker_user at email.com> (@docker_user)
MAINTAINER docker_user docker_user@email.com
# Commands to update the image
RUN echo "deb http://archive.ubuntu.com/ubuntu/ raring main universe" >> /etc/apt/
sources.list
RUN apt-get update && apt-get install -y nginx
RUN echo "\ndaemon off;" >> /etc/nginx/nginx.conf
# Commands when creating a new container
CMD /usr/sbin/nginx

其中,一开始必须指明所基于的镜像名称,接下来一般是说明维护者信息。后面则是镜像操作指令,例如RUN指令,RUN指令将对镜像执行跟随的命令。每运行一条RUN指令,镜像就添加新的一层,并提交。最后是CMD指令,用来指定运行容器时的操作命令。

Dockerfile 官方参考

2、 指令说明

Dockerfile 指令 说明
FROM 指定基础镜像,用于后续的指令构建。
MAINTAINER 指定Dockerfile的作者/维护者。(已弃用,推荐使用LABEL指令)
LABEL 添加镜像的元数据,使用键值对的形式。
RUN 在构建过程中在镜像中执行命令。
CMD 指定容器创建时的默认命令。(可以被覆盖)
ENTRYPOINT 设置容器创建时的主要命令。(不可被覆盖)
EXPOSE 声明容器运行时监听的特定网络端口。
ENV 在容器内部设置环境变量。
ADD 将文件、目录或远程URL复制到镜像中,tar文件会自动解压。
COPY 将文件或目录复制到镜像中。
VOLUME 为容器创建挂载点或声明卷。
WORKDIR 设置后续指令的工作目录。
USER 指定后续指令的用户上下文。
ARG 定义在构建过程中传递给构建器的变量,可使用 "docker build" 命令设置。
ONBUILD 当该镜像被用作另一个构建过程的基础时,添加触发器。
STOPSIGNAL 设置发送给容器以退出的系统调用信号。
HEALTHCHECK 定义周期性检查容器健康状态的命令。
SHELL 覆盖Docker中默认的shell,用于RUN、CMD和ENTRYPOINT指令。

LABEL org.opencontainers.image.authors="SvenDowideit@home.org.au"

RUN apt-get update \
&& apt-get install -y libsnappy-dev zlib1g-dev libbz2-dev \
&& rm -rf /var/cache/apt
LABEL version="1.0"
LABEL description="This text illustrates \ that label-values can span multiple lines."

EXPOSE 22 80 8443

注意,该指令只是起到声明作用,并不会自动完成端口映射。
在启动容器时需要使用-P,Docker主机会自动分配一个宿主机的临时端口转发到指定的端口;使用-p,则可以具体指定哪个宿主机的本地端口会映射过来。

ENV PG_MAJOR 9.3
ENV PG_VERSION 9.3.4
RUN curl -SL http://example.com/postgres-$PG_VERSION.tar.xz | tar -xJC /usr/src/
postgress && …
ENV PATH /usr/local/postgres-$PG_MAJOR/bin:$PATH

指令指定的环境变量在运行时可以被覆盖掉,如docker run --env <key>=<value> built_image。

ADD *.c /code/

ENTRYPOINT ["executable", "param1", "param2"](exec调用执行);
ENTRYPOINT command param1 param2(shell中执行)。

此时,CMD指令指定值将作为根命令的参数。
每个Dockerfile中只能有一个ENTRYPOINT,当指定多个时,只有最后一个有效。
在运行时,可以被--entrypoint参数覆盖掉,如docker run --entrypoint。

RUN groupadd -r postgres && useradd -r -g postgres postgres

WORKDIR /a
WORKDIR b
WORKDIR c
RUN pwd

则最终路径为/ a/b/c。

构建命令 docker build 中可以用 --build-arg <参数名>=<值> 来覆盖。

[...]
ONBUILD ADD . /app/src
ONBUILD RUN /usr/local/bin/python-build --dir /app/src
[...]

如果基于image-A创建新的镜像时,新的Dockerfile中使用FROM image-A指定基础镜像,会自动执行ONBUILD指令的内容,等价于在后面添加了两条指令:

FROM image-A
#Automatically run the following
ADD . /app/src
RUN /usr/local/bin/python-build --dir /app/src

使用ONBUILD指令的镜像,推荐在标签中注明,例如ruby:1.9-onbuild。

STOPSIGNAL signal

HEALTHCHECK [OPTIONS] CMD command:根据所执行命令返回值是否为0来判断;

·HEALTHCHECK[OPTIONS]CMD command:根据所执行命令返回值是否为0来判断;
·HEALTHCHECK NONE:禁止基础镜像中的健康检查。
OPTION支持:
·--interval=DURATION(默认为:30s):过多久检查一次;
·--timeout=DURATION(默认为:30s):每次检查等待结果的超时;
·--retries=N(默认为:3):如果失败了,重试几次才最终确定失败。

3、创建镜像

编写完成Dockerfile之后,可以通过docker build命令来创建镜像。

$ docker build -t test-image:1.1 /tmp/docker_builder/

4、使用.dockerignore文件

可以通过.dockerignore文件(每一行添加一条匹配模式)来让 Docker忽略匹配模式路径下的目录和文件。例如:

# comment
*/temp*
*/*/temp*
tmp?
~*

5、最佳实践

所谓最佳实践,实际上是从需求出发,来定制适合自己、高效方便的镜像。
首先,要尽量吃透每个指令的含义和执行效果,自己多编写一些简单的例子进行测试,弄清楚了再撰写正式的Dockerfile。此外,Docker Hub官方仓库中提供了大量的优秀镜像和对应的Dockefile,可以通过阅读它们来学习如何撰写高效的Dockerfile。
笔者在应用过程中也总结了一些实践经验。建议读者在生成镜像过程中,尝试从如下角度进行思考,完善所生成的镜像。

上一篇 下一篇

猜你喜欢

热点阅读