容器化-Docker-5-Docker File

DockerFile,它的主要作用是创建容器,它是一个容器的描述文件

可以通过描述文件来了解这个容器的构建过程和启动命令

快速理解最常用的DockerFile配置

两个阶段:

  • 构建镜像阶段
    1.定义底层镜像
    2.定义环境变量
    3.准备文件(可以使用环境变量中的定义)
    4.执行命令: 安装软件(可以使用环境变量中的定义)
  • 启动容器阶段
    5. 启动程序命令,需要一个前台进程来让容器保持运行(可以定义传参)

1 FROM(定义底层镜像)

# 格式
FROM <image>
# 示例
FROM centos

2 ENV(定义环境变量)

# 格式
ENV key=value
# 示例
ENV 

3 ADD/COPY (准备文件:把本地文件复制到镜像内)

# 格式: 
ADD <src path> <dest path>
OPY <srcpath> <dest path>
# 区别: ADD会解压tar文件到目标路径,COPY不会
# 示例
COPY ./html /usr/share/nginx/html

增量更新

4 RUN (安装软件执行命令,目的是把镜像设定为我们想要的)

# 格式:
    shell格式:
        RUN yum clean all && yum makecache && yum -y install nginx
	exec格式:
		RUN ["/usr/bin/yum", "-y", "install", "nginx"]
    # 备注:多条命令能写成一行就写成一行,否则会增大镜像层数增加镜像大小

run 建议用shell格式的就可以了

区别
shell和exec区别在于启动的时候(CMD或者ENTRYPOINT),如果用shell模式程序的PID就不是1了,在docker stop的时候可能停不掉进程

CMD (默认启动程序)

# shell格式:
CMD nginx -g 'daemon off'
# exec格式:
CMD ["nginx" "-g" "daemon off"]

建议exec格式

6 ENTRYPOINT (接收参数入口)

FROM centos:latest
ENTRYPOINT [ "echo" ]
CMD [ "Hello World"]
  • CMD是默认启动命令
  • 如果ENTRYPOINT 和 CMD一起使用,那么运行docker时候传的参数CMD会被替换为你传的参数
docker run --rm -it test   > 这个输出结果是: Hello World
docker run --rm -it test shuai ge  > 这个输出结果是: shuai ge

有什么用:
* 可以动态传参
* 可以在执行命令前做一些操作

可以动态传参的例子:

如果只有默认的CMD的话传参会异常

FROM centos:latest

CMD [ "curl", "-s", "http://myip.ipip.net" ]

我默认什么都不传,会自动执行CMD,比如我们希望显示 HTTP 头信息,这还是简单的,如果想获取其他网站怎么办?

docker build -t dip .

[@hbhly_SG11_176_84 web1]# docker run --rm -it dip
当前 IP:49.7.115.2  来自于:中国 北京 北京  电信


# 当我们在镜像后面传参,传参就会替换CMD
docker run --rm -it dip:v1 bash -c 'curl -s http://myip.ipip.net'

这时候使用ENTRYPOINT,传的参数会替换CMD,然后当做参数在传给ENTRYPOINT

FROM centos:latest

ENTRYPOINT [ "curl", "-s" ]

CMD [ "http://myip.ipip.net" ]

上面是一个应用场景,仅传参,还有Docker都在用另一个

FROM centos:latest
LABEL shuai.web.maintainer="docker web test shuai@xxx.com" shuai.web.update='20201111'


COPY ./web /usr/local/bin/web
COPY ./web-entrypoint.sh /usr/local/bin/web-entrypoint.sh

ENTRYPOINT ["web-entrypoint.sh"]

CMD ["web"]

shell脚本

[@hbhly_SG11_176_84 web1]# cat web-entrypoint.sh
#!/bin/sh

# allow the container to be started with `--port`

if [ "$1" = "-p" ]; then
	set -- web "$@"
fi

exec "$@"

看下

  • 如果什么都不传直接运行web
  • 如果传了-p 80参数就会执行web -p 80
  • 如果传的是其他的就当一个命令执行
# 什么都补传直接运行web,端口8080
docker run --rm -itd --name=web1 -p 81:8080 web

# 如果传了-p 80参数就会执行web -p 80 
docker run --rm -itd --name=web2 -p 80:80 web -p 80

# 如果传的是其他的就当一个命令执行
docker run --rm -it web curl http://myip.ipip.net

可选配置

VOLUME 匿名卷数据持久化

Dockerfile

FROM nginx
VOLUME  /usr/share/nginx/html
COPY ./html /usr/share/nginx/html
[@hbhly_SG11_176_84 nginx1]# docker volume inspect $(docker inspect nginx1 -f '{{(index .Mounts 0).Name}}' )
[
    {
        "CreatedAt": "2020-11-10T17:45:54+08:00",
        "Driver": "local",
        "Labels": null,
        "Mountpoint": "/var/lib/docker/volumes/14b848d873c1fdad2d709fe293ba8caab2c9bbcebfd9904c30c083b7cc3ef149/_data",
        "Name": "14b848d873c1fdad2d709fe293ba8caab2c9bbcebfd9904c30c083b7cc3ef149",
        "Options": null,
        "Scope": "local"
    }
]

WORKDIR 工作目录

格式:
    WORKDIR /online
注:
  通过WORKDIR设置工作目录后,Dockerfile中其后的命令RUN、CMD、ENTRYPOINT、ADD、COPY等命令都会在该目录下执行。在使用docker run运行容器时,可以通过-w参数覆盖构建时所设置的工作目录。

EXPOSE 标识服务端口

# 格式:
    EXPOSE 80
   
# 备注它仅仅是一个类似说明,主要作用是让用镜像的人或者读DOCKERFILE的人知道对外服务端口是什么,并不会映射端口

USER

指定运行容器时的用户名或 UID,后续的 RUN 也会使用指定用户。使用USER指定用户时,可以使用用户名、UID或GID,或是两者的组合。当服务不需要管理员权限时,可以通过该命令指定运行用户。并且可以在之前创建所需要的用户

 格式:
  USER user
  USER user:group
  USER uid
  USER uid:gid
  USER user:gid
  USER uid:group

 示例:
  USER www

 注:

  使用USER指定用户后,Dockerfile中其后的命令RUN、CMD、ENTRYPOINT都将使用该用户。镜像构建完成后,通过docker run运行容器时,可以通过-u参数来覆盖所指定的用户。

ARG 用于指定传递给构建运行时的变量

比如DockerFile里有用到build的时候传参如下

FROM busybox
USER ${user:-some_user}
ARG user
USER $user

$docker build --build-arg user=what_user

ONBUILD 用于设置镜像触发器

格式:  ONBUILD [INSTRUCTION]
示例:
  ONBUILD ADD . /app/src
  ONBUILD RUN /usr/local/bin/python-build --dir /app/src
注:  当所构建的镜像被用做其它镜像的基础镜像,该镜像中的触发器将会被钥触发
posted @ 2024-12-30 19:21  天帅  阅读(32)  评论(0)    收藏  举报