Docker进阶四-Dockerfile详解03

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"]

你可能感兴趣的:(Docker,docker,linux,centos)