不允许你不知道的Dockerfile指令

本文详细介绍了Dockerfile中的关键指令,如FROM、MAINTAINER、RUN、ADD/COPY、WORKDIR、VOLUME、EXPOSE、CMD、ENTRYPOINT、ARG和ENV等,展示了如何使用这些指令构建、定制和管理基于Nginx的容器,强调了容器内运行程序的注意事项和最佳实践。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

图片

1.Dockerfile 指令介绍

  • FROM 这个镜像的妈妈是谁?(指定基础镜像)

  • MAINTAINER 告诉别人,谁复制养它(指定维护者信息,可以没有)

  • RUN 你想让它干啥(在命令前面加上 RUN 即可)

  • ADD 添加宿主机的文件到容器里,还多了一个自动解压的功能

  • COPY 作用和ADD是一样的,都是拷贝宿主机的文件到容器内,COPY 就是仅仅拷贝

  • WORKDIR 我是cd,今天刚化了妆(设置当前工作目录)

  • VOLUME 给它一个存放行李的地方(设置卷,挂载主机目录)

  • EXPOSE 它要打开的门是啥(指定对外的端口)

  • CMD 奔跑吧,兄弟!(指定容器启动后要干的事情)

  • ENV 环境变量

  • ENTRYPOINT 容器启动后执行的命令

2.使用 Dockerfile 构建镜像

  • 写一个 dockerfile 构建一个 nginx 镜像,运行生成容器后,并且对 nginx 的首页内容进行更改

# 创建 Dockerfile,注意文件名,必须是 Dockerfile,内容如下 FROM nginx RUN echo '<meta charset=utf8> tfos 带你用 docker 运行 nginx 服务.' > /usr/share/nginx/html/index.html # 在 Dockerfile 文件目录下构建镜像,. 表示当前目录 docker build . # 查看镜像 docker images # 修改镜像名 docker tag 镜像id 修改后的镜像名 # 运行该镜像,生成容器 docker run -d -p 80:80 镜像名称 # 查看当前运行的容器 docker ps

图片

图片

图片

  • 访问宿主机的 80 端口

图片

3.COPY 指令

  • copy 指令从宿主机复制文件/目录到新的一层镜像内,copy 指令能够保留源文件的元数据,如权限,访问时间等等,这点很重要

# 复制宿主机文件到镜像内指定的目录 copy 宿主机文件 镜像目录 # 支持多个文件,以及通配符形式复制,语法要满足 Golang 的 filepath.Match copy 文件名* /tmp/tfos?.tex. /home

4.ADD 指令

  • 特性和 COPY 基本一致,不过多了些功能

    • 源文件是一个 URL,此时 docker 引擎会下载该链接,放入目标路径,且权限自动设为 600,若这不是期望结果,还得增加一层 RUN 指令进行调整

    • 源文件是一个 URL,且是一个压缩包,不会自动解压,也得单独用 RUN 指令解压

    • 源文件是一个压缩文件,且是 gzip,bzip2,xz,tar 情况,ADD 指令会自动解压缩该文件到目标路径

  • Dockerfile 官方更为推荐使用 COPY,ADD 包含了更多复杂的功能,且 ADD 会使构建缓存失效,导致镜像构建缓慢

5.CMD 指令

  • 用法,注意是双引号,在指定了 entrypoint 指令后,用 CMD 指定具体的参数

CMD ["参数1","参数2"]
  • docker 不是虚拟机,容器就是一个进程,既然是进程,那么程序在启动的时候需要指定些运行参数,这就是 CMD 指令

    • 例如 centos 镜像默认的 CMD 是 /bin/bash,直接 docker run -it centos 会直接进入 bash 解析器,等同于:CMD ["/bin/bash"]

    • 也可以启动容器时候,指定参数,docker run -it centos cat /etc/os-release,等同于:CMD ["cat","/etc/os-release"]

  • CMD 指令 shell 命令,也会被转化为 shell 形式,例如 CMD echo $PATH 会被转换为 CMD ["sh","-c","echo $PATH"]

6.容器内运行程序

  • 这里要注意的是,docker 不是虚拟机的概念,虚拟机里的程序运行,基本上都是在后台运行,利用 systemctl 运行,但是容器内没有后台进程的概念,必须在前台运行

  • 容器就是为了主进程而存在的,主进程如果退出了,容器也就丢失意义,自动退出

  • 例如有一个经典问题

    • CMD systemctl start nginx,这样的写法是错误的,容器会立即退出

    • 因为 systemctl start nginx 是希望以守护进程形式启动 nginx,且 CMD 命令会转换为:CMD ["sh","-c","systemctl start nginx"]

    • 这样的命令主进程是 sh 解析器,执行完毕后立即结束了,因此容器也就退出了

    • 因此正确的做法应该是 CMD ["nginx","-g","daemon off;"]

7.ENTRYPOINT 指令

FROM centos:7.8.2003 RUN rpm --rebuilddb && yum install epel-release -y RUN rpm --rebuilddb && yum install curl -y CMD ["curl","-s","http://ipinfo.io/ip"]
  • 和 RUN 指令一样,分为两种格式:exec 和 shell

  • 作用和 CMD 一样,都是在指定容器启动程序以及参数

  • 当指定了 ENTRYPOINT 之后,CMD 指令的语义就有了变化,而是把 CMD 的内容当作参数传递给 ENTRYPOINT 指令

  • 实际用法

    • 准备好 Dockerfile

图片

  • 构建镜像

docker build .

图片

  • 查看镜像

docker images

图片

  • 修改镜像名称

docker tag 镜像id 修改后的镜像名称

图片

  • 根据名字查找镜像

docker images | grep 修改后的镜像名称

图片

  • 运行镜像,生成容器实例,没有前台运行,因此立即挂了

docker run 修改后的镜像名称

图片

  • 上述运行正确,但是我想再传入一个参数,该怎么操作?发现是无法直接传入参数的,该形式是覆盖镜像中的 CMD,就好比把该 docker 镜像当作一个环境去执行后的命令

  • 想要争取的给容器传入一个 -I 参数,该怎样操作?

  • 解决办法1,导致镜像没有意义

docker run 修改后的镜像名称 curl -s http://ipinfo.io/ip -I

图片

  • 解决办法2,使用 ENTRYPOINT

# 修改 Dockerfile如下 FROM centos:7.8.2003 RUN rpm --rebuilddb && yum install epel-release -y RUN rpm --rebuilddb && yum install curl -y ENTRYPOINT ["curl","-s","http://ipinfo.io/ip"] # 重新构建镜像 docker build . # -t 指定构建镜像 tag 名称 docker build -t '镜像名称' . # --no-cache 构建时不使用旧的缓存,重新下载生成新的缓存 docker build --no-cache -t '镜像名称' . # 查看本机所有镜像 docker images # 重新修改镜像名称 docker tag 镜像id 新的镜像名称 # 根据镜像名称查找镜像 docker images | grep 修改后的镜像名称 # 重新运行镜像,生成容器,传入的 CMD 参数作为 ENTRYPOINT 的参数来执行 docker run 新的镜像名称 -I

图片

8.ARG 和 ENV 命令

  • ENV 设置环境变量,后续所有的操作,通过 $变量名 就可以直接获取变量值绑定了,维护 dockerfile 脚本时更友好方便

  • ARG 和 EVN 一样,都是设置环境变量,区别在于 EVN 无论是在镜像构建,还是容器运行,该变量都可以使用;ARG 只是用于构建镜像需要设置的变量,容器运行时就消失了

ENV NAME="tfos" ENV AGE="18" ENV MYSQL_VERSION=8.0

9.VOLUME 指令

  • 容器在运行时,应该保证在存储层不写入任何数据,运行在容器内生产的数据,我们推荐是挂载,写入到宿主机上,进行维护

# 将容器内的 /data 文件夹,在容器运行时,该目录自动挂载为匿名卷,任何向该目录中写入数据的操作,都不会被容器记录,保证的容器存储层无状态理念 VOLUME /data # Dockerfile 样例 FROM centos:7.8.2003 MAINTAINER tfos VOLUME ["/data1","data2"] # 该容器运行时,这两个目录自动和宿主机目录做好映射关系 docker build . docker run 镜像id docker inspect 镜像id
  • 容器数据挂载的方式,通过 dockerfile,指定 VOLUME 目录

  • 通过 docker run -v 参数,直接设置需要映射挂载的目录

10.EXPOSE 指令

  • 指定容器运行时对外提供的端口服务

  • 帮助使用该镜像的人,快速理解该容器的一个端口业务

docker port 容器 docker run -p 宿主机端口:容器端口 # -P 随机宿主机端口:容器端口 docker run -P

11.WORKDIR 指令

  • 用于在 dockerfile 中,目录的切换,更改工作目录

WORKDIR /opt

12.USER 指令

  • 用于改变环境,用于切换用户

USER root
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

腾飞开源

你的鼓励将是我创作的最大动力!

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值