Docker进阶四-Dockerfile详解03

发布时间:2024-08-31 13:01

Dockerfile区分一些易混淆的指令

1、USER 执行cmd等之类命令的使用那个用户

alpine  sudo   gosu
FROM centos
RUN groupadd -r abc && useradd -r -g abc aaa
USER aaa
CMD whoami
# CMD 就是容器启动以后要执行的命令

2、ARG、ENV

  • The ARG instruction defines a variable that users can pass at build-time to the builder with the docker build :arg在构建期间。docker build
  • The environment variables set using ENV will persist when a container is run from the resulting image. You can view the values using docker inspect, and change them using docker run --env =. env在运行是可以用到的
FROM alpine

ARG bbb haha
ENV abc 666

CMD echo $bbb
容器运行的时候arg的东西拿不到

CMD echo $abc
容器运行的时候env的能拿到


FROM alpine

ARG bbb haha
ENV abc=$bbb

CMD echo $abc

ARG指定的值,在镜像构建的后面位置,构建期间都可以使用到。

改变这些值行不行
docker build -f Dockerfile-arg-env -t file-arg --build-arg bbb=888 --build-arg abc=777 .
结果888 


# 构建时 bbb=888 abc=777 ,cmd打印888.原因 构建时不能改变env
# 运行时 
\\ ARG ENV
build时 √。–build-arg改变 构建参数(ARG声明) 生效,能不能改(不能)
运行时 不生效 生效。能改 -e abc

最佳实战:

ARG:定义一些版本信息

​ FROM alpine

​ ARG version=1

​ RUN yum install nginx:$version

Env:运行时的环境变量。

ENV env = --spring.profile.active=prod

​ -e修改。sb java -jar xxx.jar $env

3、ADD和COPY

#构建了一个SpringBoot镜像。 xxx.jar 
/opt

docker build -t hello .

ADD:将当前目录下的内容放到镜像里面一起打包。

COPY:将当前目录下的内容放到镜像里面一起打包。

ADD [\"\",\"\",\"\"]  dest:容器里面的目录
可以指定很多种路径地址。自动下载,解压复制。
FROM alpine

ADD hello.tar /opt/hello

COPY hello.tar /opt/world/

CMD echo \"1234\"

这个东西构建的镜像为什么docker run -d 不行。因为容器运行的是ech 1234;
没有一个守护进程一直运行。
CMD ping baidu.com


4、VOLUME和WORKDIR

VOLUME:指定容器需要挂载的卷
WORKDIR:工作目录。
	1、以后的其他命令在这个目录里面运行
	2、exec进去都默认来到了 WORKDIR 指定的目录。sh
	docker run -it --rm file-volume sh
	
WORKDIR


WORKDIR /root  == RUN cd /root

挂载麻烦。自动挂载。
FROM alpine

WORKDIR /opt/a

VOLUME /opt/b

COPY hello.txt .

ADD hello.tar /opt/b

CMD whoami

volume声明的挂载目录,即使容器运行的时候,不用-v进行挂载。docker也会自动的进行匿名挂载。
nginx:

5、RUN、CMD、ENTRYPOINT

相同点:运行命令

不同点:

​ RUN:在构建镜像的时候运行的命令

CMD、ENTRYPOINT:在容器启动运行的命令

测试RUN;

#想构建一个具有git功能的镜像。
FROM centos

RUN yum install -y git

WORKDIR /opt/data

RUN git clone https://gitee.com/lanoox/luject.git

VOLUME /opt/data
CMD echo \"git clone success\"
#CMD 容器运行的时候CMD的命令才执行。

\"Docker进阶四-Dockerfile详解03_第1张图片\"
\"在这里插入图片描述\"

\"Docker进阶四-Dockerfile详解03_第2张图片\"

相同的镜像layer层发生变化,只有这层变化。

  • -RUN指令的所有命令都在镜像docker build期间就执行
  • CMD和ENTRYPOINT在容器启动时运行
    • CMD 容器运行的时候CMD的命令才执行。docker run -it --rm file-run bash 能进容器中
    • 替换为ENTRYPOINT。虽然指令运行了。但是 docker run -it --rm file-run bash 。最后的bash没有进去,失效了。

无论是CMD还是ENTRYPOINT还是RUN

  • RUN (shell form, the command is run in a shell, which by default is /bin/sh -c on Linux or cmd /S /C on Windows) RUN yum install -y git;/bin/sh -c可以动态获取一些变量
  • RUN [\"executable\", \"param1\", \"param2\"] (exec form);无法动态获取一些变量
FROM centos

ARG soft=git
RUN [\"yum install\",\"-y\",\"$soft\"] #这是错误的。因为非`/bin/sh -c`方式,用不到前面声明的ARG,ENV

WORKDIR /opt/data

RUN git clone https://gitee.com/lanoox/luject.git

VOLUME /opt/data
ENTRYPOINT echo \"git clone success\"

\"Docker进阶四-Dockerfile详解03_第3张图片\"

# bash-c 和 数组方式的区别,  修改后的;安装正确。
FROM centos

ARG soft=git
RUN [\"/bin/sh\",\"-c\",\"yum install -y $soft\"]
#-c command:后免是完整命令
WORKDIR /opt/data

RUN git clone https://gitee.com/lanoox/luject.git

VOLUME /opt/data
ENTRYPOINT echo \"git clone success\"

RUN、CMD、ENTRYPOINT都支持一下两种方式

The exec form, which is the preferred form:

ENTRYPOINT [\"executable\", \"param1\", \"param2\"]

The shell form:

ENTRYPOINT command param1 param2

总结:

  • 如果运行命令是。[]方式,默认不是bash -c就无法用变化,普通的方式RUN yum -install -y $soft可以使用变量。

  • CMD、ENTRYPOINT的最佳实战

    • Dockerfile文件必须至少有一个 CMD 或者ENTRYPOINT 命令.
    • ENTRYPOINT 用来定义容器如何运行.
    • CMD 应该被用来作为给ENTRYPOINT 传递。默认参数的一种方式
    • CMD 将会被覆盖,容器运行时指定参数的时候. ENTRYPOINT 命令不会被覆盖。
    • CMD多个只会有一个生效。
    • ENTRYPOINT :不被传入的指令覆盖,但是多个也只有一个生效。

    为什么我的指令Dockerfile写CMD的时候,docker run -it --rm file-run bash可以进控制台,而ENTRYPOINT 不行?

    运行效果:

    • Dockerfile是CMD;没打印git clone success。但是bash生效。

\"在这里插入图片描述\"

  • Dockerfile 是 ENTRYPOINT;打印了git clone success但是没有进容器(bash没生效)

\"在这里插入图片描述\"

  • 混写。CMD + ENTRYPOINT
FROM centos

ARG soft=git
RUN [\"/bin/bash\",\"-c\",\"yum install -y $soft\"]

WORKDIR /opt/data

RUN git clone https://gitee.com/lanoox/luject.git

VOLUME /opt/data


CMD [\"nginx\"] #CMD给entrypoint提供参数
ENTRYPOINT [\"yum\",\"install\",\"-y\"]


运行:
docker run -it --rm file-run maven
FROM centos

ARG soft=git
RUN [\"/bin/bash\",\"-c\",\"yum install -y $soft\"]

WORKDIR /opt/data

RUN git clone https://gitee.com/lanoox/luject.git

VOLUME /opt/data


CMD [\"\",\"\",\"\",\"\"] #可以放空
ENTRYPOINT [\"/bin/sh\",\"-c\",\"yum install -y\"]

#容器启动就是yum install -y \"\";自己启动命令加上git
CMD 后面有N参数。传了参数替换N个还是最后一个?
docker run -it --rm file-run maven  CMD [\"maven\"]  对
docker run -it --rm file-run maven  CMD [“”,“”,\"maven\"]

目的:构建镜像。SpringBoot编写的微服务,怎么做镜像?

1、运行的业务的目标环境?SB服务。java环境。FROM

2、怎么启动业务的。得到jar包,java -jar xxx.jar --spring.profile.active=prod --server.port=8080;决定镜像的ENTRYPOINT怎么写。docker exec?docker run(第一次容器启动要执行)?

docker exec haha -it bash【和entrypoint,cmd没啥关系】;

3、业务运行的时候需要啥?java。jar。jar包就想办法放进镜像中。COPY 。ADD

4、业务的那些数据是需要做持久化。VOLUME怎么写。

FROM java:8


#服务器只有dockerfile和jar在一起
COPY *.jar /app.jar

#即使运行没有-v,也会匿名挂载
VOLUME [\"/logs\"]

CMD [\"--server.port=8080\"]

EXPOSE [\"8080\"]

ENTRYPOINT [\"java\",\"-jar\",\"/app.jar\"]

ItVuer - 免责声明 - 关于我们 - 联系我们

本网站信息来源于互联网,如有侵权请联系:561261067@qq.com

桂ICP备16001015号