alpine sudo gosu
FROM centos
RUN groupadd -r abc && useradd -r -g abc aaa
USER aaa
CMD whoami
# CMD 就是容器启动以后要执行的命令
ARG
instruction defines a variable that users can pass at build-time to the builder with the docker build
:arg在构建期间。docker buildENV
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
#构建了一个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
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:
相同点:运行命令
不同点:
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的命令才执行。
相同的镜像layer层发生变化,只有这层变化。
无论是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"
# 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的最佳实战
CMD
或者ENTRYPOINT
命令.ENTRYPOINT
用来定义容器如何运行.CMD
应该被用来作为给ENTRYPOINT
传递。默认参数的一种方式CMD
将会被覆盖,容器运行时指定参数的时候. ENTRYPOINT
命令不会被覆盖。ENTRYPOINT
:不被传入的指令覆盖,但是多个也只有一个生效。为什么我的指令Dockerfile写CMD的时候,docker run -it --rm file-run bash可以进控制台,而ENTRYPOINT
不行?
运行效果:
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"]