Dockerfile Tutorial
本文最后更新于 2025年1月27日 下午
Very detailed tutorial on Dockerfile.
FROM
基础image的来源。
FROM
<repository>:[tag]1
2
3FROM busybox # will pull latest tag by default
FROM busybox:latest # 默认使用hub.docker.com 仓库image
FROM registry.cn-shenzhen.aliyuncs.com/abo/devops:v1FROM
<repository>@<digest>1
2
3FROM alpine@sha256:d7342993700f8cd7aba8496c2d0e57be0666e80b4c441925fc6f9361fa81d10e
# docker pull 通过digest方式
docker pull alpine@sha256:d7342993700f8cd7aba8496c2d0e57be0666e80b4c441925fc6f9361fa81d10e
MAINTANTIER
添加维护者等信息。
MAINTANTIER<infomatin>
注意: MAINTANTIER语法已经被新的LABEL替代
1 | |
LABEL
作用和MAINTANTIER一摸一样
语法格式:LABEL <key>=<vale> <key>=<vale> …
1 | |
COPY
复制文件或者目录.
COPY <src> <dest>1
2# 所有的copy都指的是Dockerfile当前目录下的文件来讲的
COPY test.tar.gz /data/web/COPY["<src>", …"<dest>"]1
COPY ["test.tar.gz","/data/web/"]注意事项
src支持通配符dest建议使用绝对路径路径中不能存在空白字符,常用第二种格式
src是目录,只会复制其下层目录以及文件,不会复制src目录本身到dest指定了多个
src或者使用了通配符,dest必须是同一个,且dest必须以/结尾
ADD
复制添加文件或者目录.
ADD<src> <dest>1
2
3
4
5# 复制压缩包以及index.html文件到/data/web/目录下,并且压缩包会被自动解压,仅仅本地src才会被解压
ADD test.tar.gz index.html /data/web/
# 支持SRC为URL,请注意dest后面带/和不带区别
ADD http://aliyun.com/test.tar.gz /data/web # 添加文件并且被命名为web
ADD http://aliyun.com/test.tar.gz /data/web/ # 添加文件到/data/web/ADD["<src>", ..."<dest>"]1
2
3
4# 添加URL的压缩文件和本地index文件到目标目录
ADD ["http://5.5.5.100:8000/software/linux/nginx-1.18.0.tar.gz","index.html","/data/web/"]
# 添加本地的两个文件到目标目录
ADD ["test.tar.gz","index.html","/data/web/"]
VOLUME
用于在image中创建一个挂载点,以挂载docker host上的卷或者其他容器上的卷
VOLUME<mointpoint>1
VOLUME /data/mydata/VOLUME["<mountpoint>"]1
VOLUME ["/data/mydata/"]
注意:如果挂载点路径此前存在文件,``docker run`后会在挂载完成后将此前文件复制到新的挂载卷中
EXPOSE
容器运行起来向外需要暴露的端口。
EXPOSE <port>/<[tcp|udp]>
1 | |
ENV
容器定义环境变量,可以被ENV ADD COPY 所调用
ENV<key><value>1
2# 这种方式中,key后面的所有内容都会被认为是value的值,因此这种只能定义一个变量
ENV HTTP_ROOT /usr/local/nginx/html/ENV<key>=<value>1
2
3
4# 此种方式可以定义多个变量
ENV HTTP_ROOT="/usr/local/nginx/html/" \
WORKDIR="/data/web/"
PORT=80调用方式:
$HTTP_ROOTor${HTTP_ROOT}
RUN
**docker build**过程中需要运行的命令.
RUN<command>1
2# 这种方式是以 /bin/sh -c 来运行mkdir,容器PID不为1,不能接受unix信号
RUN mkdir -p /data/webRUN[“<command>“,”<参数1>“,”<参数n>“]1
2
3
4
5
6
7
8# 这种方式不是以 /bin/sh -c 来运行mkdir
ENV HTTP_ROOT="/data/test/"
# 以下三种方式均可创建指定目录
RUN ["mkdir","-p","$HTTP_ROOT"]
RUN ["mkdir","-p $HTTP_ROOT"]
RUN ["mkdir","p ${HTTP_ROOT}"]
# 如果要依赖shell特性以这种方式运行运行,请参照下面的格式,标准写法,推荐用以下方式
RUN ["/bin/bash",-c","mkdir", "-p","$HTTP_ROOT"]
CMD
docker run过程中,容器运行起来需要执行的命令,注意和RUN做对比.RUN是构建过程需要的命令,CMD是容器运行起来运行的命令.
CMD<完整的命令以及参数>CMD指定的命令可以被docker run后面的命令覆盖!!!1
2ENV HTTP_ROOT="/data/test/"
CMD /bin/httpd -f -h $HTTP_ROOTCMD[“<command>“,”<参数1>“,”<参数n>“]这种方式 方括号内无法读取环境变量参数
1
2
3
4
5
6ENV HTTP_ROOT="/data/test/"
# 错误写法
CMD ["/bin/httpd","-f","-h","$HTTP_ROOT"] # 这种方式CMD无法获取变量参数,
# 正确写法
CMD ["/bin/httpd","-f","-h /data/web/html/"]
CMD ["/bin/httpd","-f","-h","/data/web/html/"]CMD[“<参数1>”,”<参数2>“,”<参数n>“]此种方式用于为
ENTRYPOINT提供默认参数
ENTRYPOINT
功能和CMD一样,但是有差异,**ENTRYPOINT 运行的命令不可以被docker run后面的命令覆盖**
ENTRYPOINT["<command>"]1
2
3# 为ENTRYPOINT提供运行参数,作用等于 CMD ["/bin/httpd","-f","-h","/data/web/html"]
CMD ["-f","-h","/data/web/html"]
ENTRYPOINT ["/bin/httpd"]示例
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25####
vim entrypoint.sh
#!/bin/sh
cat >/etc/nginx/conf.d/www.conf << EOF
server {
server_name $HOSTNAME;
listen ${IP:-0.0.0.0}:${PORT:-80}; # -80和-0.0.0.0均为预设变量语法格式,如果未有变量输入将启动默认参数
root ${NGX_ROOT:-/usr/share/nginx/html};
}
EOF
exec "$@" # 此脚本运行完成后进程将被其所有参数替换
#####
vim Dockerfile
FROM nginx:1.18-alpine
LABEL author="Jason Hu"
ENV NGX_ROOT="/data/nginx/html/"
ADD entrypoint.sh /bin/
ADD index.html $NGX_ROOT
RUN chmod +x /bin/entrypoint.sh
ENTRYPOINT ["/bin/entrypoint.sh"]
CMD ["/usr/sbin/nginx","-g","daemon off;"]
####
docker build -t nginx:lab .
# use build image but web page still is the default not the one we defined, I'm thinking where did I miss?
docker run --rm -itd -p 80:80 nginx:lab && curl localhost
HEALTHCHECK
用于容器的健康检查.
HEALTHCHECK[options]CMD<command>options可以有以下几种:--interval=<value># default 30s--timeout=<value># default 30s--start-period=<value># default 0s—retries=<value># default 3
在容器内部运行命令检查健康状态,检查的结果状态值有以下三种:
0—succeedhealthy1—unhealthy2—reserved
HEALTHCHECKNONE
1 | |
SHELL
指定默认shell来运行命令,Linux 不指定默认是 ["/bin/sh","-c"] , Windows 默认不指定是["CMD","/S","/C"],SHELL可以在Dockerfil中出现多次
SHELL ["<command>","<参数>"]
STOPSIGNAL容器接受的unix信号来退出容器.
STOPSIGNAL<signal>ARG在
docker build过程中定义的变量,可以使用--build-arg <key>=<value>来引入ARG<key>=<value>1
2
3
4ARG author=scofield
LABEL maintainer=${author}
docker build --build-arg author=westlife -t test:v10 .
# 新创建的出来的镜像 maintainer=westlifeONBUILD用于在
Dockerfile中定义一个触发器,自己创建的image被另外一个Dockerfile用作基础镜像时会执行的指令语法格式:
ONBUILD<Dockerfile指令>1
ONBUILD ADD http://nginx.org/download/nginx-1.19.4.tar.gz /data/nginx/