DockreFile详解
什么是dockerfile?
Dockerfile 是一个用来构建镜像的文本文件,文本内容包含了一条条构建镜像所需的指令和说明
一个完整的Dockerfile包含了四个功能分区,编写顺序依次为基础镜像区、描述信息区、安装镜像执行指令区、容器启动执行指令区
Dockerfile以“#”号作为文件注释,但是字符串中间的“#”号不会被判定为注释,如下述示例2、3中的“#”不会被判定为注释符
(1):# 我是一条dockerfile的注释
(2):RUN echo 'hello # dockerfile'
(3):RUN apt-get update \
# install some packages
&& apt-get install -y cron
Docker参数说明
基础镜像区
(1):FROM 声明自定义镜像的基础镜像
FROM [镜像名称]:[tag编号]
# 一个Dockerfile中只会生效一个FROM标签,如果定义了多个FROM标签只会调用第一个
# FROM为必填项
描述信息区
(1):LABEL 声明镜像的作者、版本、构建时间、描述等一系列信息,此处可以声明任何信息
LABEL maintainer="PSQ"
LABEL version="v0.01"
LABEL date="2022-12-07"
LABEL description="我是一个描述标签"
# 可以根据需要添加多个LABEL标签
# LABEL非必填项
(2): MAINTAINER 声明镜像作者
MAINTAINER PSQ
# 一个Dockerfile中仅能声明一次MAINTAINER
# MAINTAINER非必填项
安装镜像执行指令区
(1):USER 执行Dockerfile中的shell指令时指定用户
USER root
或者
USER [用户名]:[组名称]
# 一个Dockerfile中仅能声明一次USER,如果定义了多个USER则只会调用最后一个
# USER非必填项
(2):EXPOSE 指定Dockerfile中的容器需要暴露的端口
EXPOSE 80
# 一个Dockerfile中可以声明多个EXPOSE标签,也可以在一个EXPOSE中声明暴露多个端口,使用空格区分开即可
# EXPOSE指令仅标识容器暴露的端口,并不会真正开放这些端口。如果要真正开放容器暴露的端口,还需要使用-p或-P选项来指定容器端口与主机端口的映射关系。
# EXPOSE非必填项
(3):WORKDIR 指定Dockerfile中的工作目录
WORKDIR /path
# 一个Dockerfile中仅能声明一次WORKDIR,如果有多个WORKDIR则只会调用最后一个
# WORKDIR非必填项
# 如果需要多个目录工作可以参考如下格式
WORKDIR /path-1
[ADD | COPY | RUN | CMD | ENTRYPOINT] your-shell
WORKDIR /path-2
[ADD | COPY | RUN | CMD | ENTRYPOINT] your-shell
....
(4):ADD 拷贝文件或目录到镜像中
ADD [文件、目录所在路径] [镜像中的目标路径]
# 一个Dockerfile中可以声明多个ADD标签,如果复制的文件后缀为.tar、.tar.gz、.tgz、.gz、.bz2后缀会被自动解压
# ADD非必填项
(5):COPY
COPY [文件、目录所在路径] [镜像中的目标路径]
# 一个Dockerfile中可以声明多个COPY标签,与ADD的区别在于压缩包文件不会被自动解压
# COPY非必填项
(6):VOLUME 把宿主机的目录映射到容器中
VOLUME ["[宿主机目录-1]:[容器映射的目录-1]","[宿主机目录-2]:[容器映射的目录-2]"]
或者
VOLUME [宿主机目录-1]:[容器映射的目录-1]
# 一个Dockerfile中可以有多个VOLUME标签
# VOLUME标签非必填项
(7):ARG 定义一个变量
ARG name=value
# 一个Dockerfile中可以有多个ARG标签
# 定义成功后可以在别的标签中是用$name来使用它,如:RUN echo "Hello $name" 会打印结果 “hello value”
# ARG标签非必填项
(8):RUN 构建镜像时需要运行的命令(在宿主机执行)
RUN ["echo", "hello dockerfile", ">", "test.txt"]
或者
RUN echo 'hello dockerfile' > test.txt
# 一个Dockerfile中可以有多个RUN标签
# 一个Dockerfile中应至少有一个RUN标签
(9):ENV 设置容器内的环境变量(在容器内执行)
ENV name1=value1
# 一个Dockerfile中可以有多个ENV标签
# ENV标签非必填项
容器启动执行指令区
(1):CMD 指定容器启动时要运行的命令
CMD ['/bin/bash', "xxx"]
或者
CMD /bin/bash xxx
# 一个Dockerfile中可以有多个CMD标签,存在多个CMD标签时会被依次执行
# 一个Dockerfile中至少要有一个CMD标签
(2):ENTRYPOINT
ENTRYPOINT ['/bin/bash', "xxx"]
或者
ENTRYPOINT /bin/bash xxx
# 一个Dockerfile中可以有多个ENTRYPOINT标签,存在多个ENTRYPOINT标签时会被依次执行
# ENTRYPOINT标签与CMD标签作用想用,区别在于不能被用户指定的命令覆盖,而CMD的命令可以被用户指定的命令覆盖
# CMD与ENTRYPOINT两者选其一即可
Dockerfile示例
[root@localhost ~] vim Dockerfile
FROM centos:7
# 我声明了这个dockerfile的备注信息
LABEL manager="PSQ"
LABEL date="2022-12-08"
LABEL description="这是一个测试案例"
RUN ["echo", "Dockerfile开始工作啦~"]
# 我指定了这个dockerfile的运行角色为root
USER root
# 我向容器里复制了一个txt后缀的文本文件
ADD test.txt /root/test.txt
# 准备工作完成现在开始构建容器啦
# 我在容器里运行了一条yum update -y的指令
CMD ["yum", "update", "-y"]
# 我用yum安装了几个常用的工具
CMD ["yum", "install", "-y", "lsof", "wget", "htop"]
OK,完成上述一个简单的实例后,我们就可以开始尝试运行这个dockerfile了
[root@localhost ~] docker build -t [你的镜像名称叫啥名字] -f Dockerfile [你的Dockerfile文件在哪个目录,如果在当前目录使用.号即可]
# 当结果底部打印了如下内容即表示你的镜像构建成功啦
Successfully built [sha256哈希码]
Successfully tagged [你的镜像名称叫啥名字]:latest
# 最后就是使用docker run -d -p -v --name xxxx来运行你构建的容器即可