Dockerfile

本文最后更新于 2024年12月1日

Dockerfile概述

Dockerfile是用来构建Docker镜像的文本文件,是由一条条构建镜像所需的指令和参数构成的脚本。

从应用软件的角度来看,Dockerfile,Docker镜像,Docker容器分别代表软件的三个不同阶段

  • Dockerfile是软件的原材料
  • Docker镜像是软件的交付品
  • Docker容器可以认为是软件的运行态

Dockerfile面向开发,Docker镜像成为交付标准,Docker容器则涉及运维和部署,合力充当Docker体系的基石。

Dockerfile定义了进程需要的一切东西,Dockerfile涉及的内容包括执行代码或者文件,环境变量,依赖包,运行时环境,动态链接库,操作系统发行版,服务进程和内核进程(当应用程序需要和系统服务和内核进程打交道,这时需要考虑如何设计namespace的权限控制)等等。

Docker镜像,在用Dockerfile定义了一个构建文件之后,docker build时会产生一个Docker镜像,当运行Docker镜像时,会开始真正的提供服务。

Docker容器,是直接提供服务的进程。

Dockerfile构建过程:

  1. docker从基础镜像运行一个容器
  2. 执行一条指令,并对容器进行修改
  3. 执行类似docker commit的操作,提交一个新的镜像层
  4. docker再基于刚刚提交的镜像运行一个新容器
  5. 继续执行Dockerfile的下一条指令,直到所有指令都执行完成

Dockerfile的保留字指令

Dockerfile每个保留字指令均为大写,且后面至少跟随一个参数,指令从上到下顺序执行,用#表示注释。

FROM

基本出现在第一行,意思是要构建的新镜像继承于或者说基于哪个已存在的镜像。

FROM ubuntu:20.04

MAINTAINR

维护者信息(姓名和邮箱地址)

ENV

用于在构建镜像的过程中设置环境变量,这个环境变量可以在后续的任何RUN指令中使用,就像在命令前面指定了环境变量一样,也可以在其他指令中直接使用这些环境变量,比如WORKDIR $JAVA_HOME

ENV PATH="/usr/local/bin:${PATH}"

RUN

容器构建(docker build)时需要运行的命令,分为shellexec两种格式

shell

RUN apt-get update && apt-get install -y curl

exec

CMD ["可执行文件", "参数1", "参数2", ......]

EXPOSE

声明容器运行时应该开放的端口。它不会自动开启端口,但为外部用户或其他容器提供信息

EXPOSE 80 443

WORKDIR

指定在创建容器后,终端默认登录进来的工作目录,当执行docker run -it 镜像ID /bash进入容器内部的时候,会默认落脚在哪个目录里

USER

指定镜像以什么用户去执行,如果不指定,默认是root

USER myuser

VOLUME

容器数据卷,用于数据的保存和持久化。

VOLUME ["/data"]

ADD

ADD功能相比COPY更加强大,将宿主机内的文件拷贝进镜像,如果源文件是.tar.tar.gz等压缩格式的文件,ADD会自动解压到目标路径。ADD还可以从指定的URL下载文件并复制到容器内。

ADD <宿主机源路径> <容器内目标路径>

COPY

仅仅执行文件的复制,不支持自动解压或下载

COPY <宿主机源路径> <容器内目标路径>

CMD

指定容器启动后要做的事情,支持shellexec两种格式,还支持参数列表格式,如果指定了ENTRYPOINT指令,CMD就会被用来指定具体的运行参数

注意事项

1.RUNCMD的区别: RUN是构建镜像时执行,CMDdocker run容器启动时执行

2.Dockerfile中可以有多个CMD指令,但只有最后一个生效,CMD会被docker run之后的参数替换

例如:tomcat的Dockerfile的最后一行是CMD ["catalina.sh", "run"],那么使用docker run -it tomcat /bin/bash命令启动这个镜像时,容器会启动,但是tomcat就不会被启动,因为被run后的命令/bin/bash替换掉了,故容器启动后会运行/bin/bash

ENTRYPOINT

类似于CMD命令,但是不会被docker run后的命令覆盖,而且还会把docker run后的命令当作命令行参数传递给ENTRYPOINT指令指定的程序

ENTRYPOINT ["可执行文件", "参数1", "参数2", ......]

ENTRYPOINT可以和CMD一起用,一般是变参才会使用到CMD,这里的CMD等同于是在给ENTRYPOINT传参,当指定了ENTRYPOINT后,CMD的含义就发生了变化,不再是直接运行其命令而是将CMD的内容作为参数传递给ENTRYPOINT指令,它们两个组合后会变成<ENTRYPOINT> "<CMD>"

案例:

FROM nginx

ENTRYPOINT ["nginx", "-c"] #相当于命令加定参

CMD ["/etc/nginx/nginx.conf"] #相当于可替换的变参
按照Dockerfile原样执行 传参运行
Docker命令 docker run nginx docker run nginx -c /etc/nginx/kms.conf
容器实际执行 nginx -c /etc/nginx/nginx.conf nginx -c /etc/nginx/kms.conf

编写运行一个Dockerfile

FROM alpine

未完待续


Dockerfile
https://blog.liuzijian.com/post/929013b9-b765-b8c1-6343-84677774f987.html
作者
Liu Zijian
发布于
2024年11月24日
更新于
2024年12月1日
许可协议