【云原生 | Docker篇】实战Dockerfile(五)

网友投稿 253 2022-10-20

【云原生 | Docker篇】实战Dockerfile(五)

文章目录

​​实战Dockerfile​​

​​前言​​

​​运行实例命令​​

​​第一例、这是我第一个Dockerfile​​

​​第二例、ARG指令和ENV指令简单使用​​

​​第三例、ARG指令可任意位置定义​​

​​第四例、ENV的坑--构建期间就已经确定好值​​

​​第五例、ADD与COPY指令简单使用​​

​​第六例、COPY的文件可以改变用户​​

​​第七例、 WORKDIR的应用​​

​​第八例、VOLUME需要注意的坑与EXPOSE使用​​

​​第九例、CMD、ENTRYPOINT容器启动指令​​

​​第十例、 多阶段构建​​

实战Dockerfile

前言

博主语录:一文精讲一个知识点,多了你记不住,一句废话都没有

经典语录:别在生活里找你想要的,要去感受生活里发生的东西

传送门:【云原生 | Docker篇】深入Dockerfile_Lansonli的博客

以下是实战经典十例,反复练习,可玩转Dockerfile

运行实例命令

# 修改dockerfile文件vim Docderfile# 构建容器看执行过程docker build --no-cache -t demo:test -f Dockerile .#传入构建参数docker build --no-cache --build-arg param="11 22 33" msg="aa bb cc" -t demo:test -f Dockerfile2 .#进入容器控制台docker exec -it mydemo1 /bin/sh

第一例、这是我第一个Dockerfile

# 这是我第一个DockerfileFROM alpine# 给镜像加个标签LABEL maintainer="lanson @ dd" \abc=def \aaa=bbb cccc=ddd  # 运行的指令,安装了软件,修改了文件,默认是用id=0 也就是root,这个基础系统的root用户# 代表镜像构建过程中运行的命令。RUN echo 11111  # 镜像启动如果要运行很长命令才行,容器启动执行的命令## 1、准备一个sh文件,让镜像启动运行sh文件(大多镜像操作)## 2、直接在CMD的位置写即可CMD sleep 10;echo success

第二例、ARG指令和ENV指令简单使用

# 不可以引用多个FROM alpineLABEL maintainer="llanson @ dd" \abc=def \aaa=bbb cccc=ddd    #指定构建参数【构建时】ARG aaa=aaaa#指定环境变量【为RUN以及CMD指定环境变量的】ENV  parm=11111  # shell* 形式; bash -c "echo 11111"RUN echo $parm  #  exec 形式。$parm 默认拿不到ENVRUN ["echo","$aaa"]# 错误语法  RUN ["echo",'$parm']# 错误语法  RUN ["echo",$parm]# 错误语法。NOT FOUND(取不出环境变量【ENV】,ARG也是取不出)#RUN ["echo",'${aaa}']#RUN ["echo",${parm}]#都是可以启动容器的命令有什么不同#CMD sleep 1;echo $parm;echo $aaa;# 都是可以启动容器的命令有什么不同ENTRYPOINT sleep 1;echo $parm;

第三例、ARG指令可任意位置定义

#可以在任意位置定义,并在以后取值使用,#使用--build-arg version=3.13 改变;以我们传入的为准ARG version=3.13.4# 3.13  FROM alpine:$versionLABEL maintainer="lanson" a=b \c=dd#构建期+运行期都可以生效;但是只能在运行期进行修改#怎么修改:构建期修改和运行期修改#构建期不能改 ENV的值#运行期:docker run -e app=atguigu 就可以修改ENV app=itdachang  ##测试构建期间生效RUN echo $appRUN echo $param# 定义以后的剩下环节(不包括运行时)能生效:取值$param;#可以在构建时进行变化,docker build# ARG不像ENV不能并排写ARG param=123456  ARG msg="hello docker"#构建时期我们会运行的指令(根据Dockerfile创建一个镜像的整个过程时期)RUN echo 11111RUN echo $paramRUN echo $msg  #运行时期我们会运行的指令(根据之前创建的镜像启动一个容器,容器启动默认运行的命令)#(docker run/docker start)# CMD和ENTRYPOINT` 都是指定的运行时的指令CMD ["/bin/sh","-c","echo 1111;echo $param;echo app_${app}"]

第四例、ENV的坑--构建期间就已经确定好值

# env的坑FROM alpine# ARG msg=hello# # ENV肯定能引用ARG# ENV name=${msg}  # RUN echo ${name}# RUN echo ${msg}# ENV只能运行期改掉ENV msg1=helloENV msg2=$msg1# 以上构建期间就已经确定好值了;ENV持久化问题。RUN echo ${msg1}RUN echo ${msg2}# msg1=msg2没问题;如果我运行期修改了msg1=66666的值,请求msg1;msg2输出什么# 结果输出: 6666   hello;  传值不是传引用???原因:# docker build的时候,env环境的信息会固化,直接在镜像配置里面就已经写死,msg1=hello,msg2=hello。# -e 真的只能修改当前env本身# 为什么运行期间能用ENV定义的所有值,一定是ENV存在某个地方CMD ["/bin/sh","-c","echo ${msg1};echo ${msg2};"]

第五例、ADD与COPY指令简单使用

# ADD与COPY指令FROM alpine#把上下文Context指定的内容添加到镜像中,如果是压缩包,自动解压,# 把当前内容复制到这个 alpine小系统里面# 如果是远程文件,自动下载;# 如果是压缩包,自动解压;ADD  /dest/#本地linux系统的内容文件添加进去  【宿主机   镜像内】# docker build -t demo:test  -f Dockerfile 【.:上下文的文件路径】    : .代表上下文环境;代表Dockerfile所在的当前目录#自动解压# 压缩包位置:/root/dockerfilesADD *.tar.gz   /app/# RUN ls -l# 相当于给当前容器开一个用户,以后的命令可以用这个用户运行# 不自动解压和下载# COPY nginx# 以容器的用户:# RUN  "useradd "COPY  --chown=redis:redis   *.tar.gz  /redis/# RUN指令上下并没有上下文关系;# RUN cd /dest# 当前还是列举的根目录# RUN ls -lRUN cd /dest && ls -lRUN cd /app && ls -lRUN cd /redis && ls -l#把上下文Context指定的内容复制到镜像中# COPY

第六例、COPY的文件可以改变用户

# COPY的文件可以改变用户FROM alpine# 开用户#RUN adduser -u lanson -g lanson# 以后的所有命令会用 lanson:lanson 来执行。有可能没有执行权限# 容器中的ROOT虽然不是linux宿主机的真实root,但是可以改掉这个镜像的所有  USER 1000:1000# 把复制来的文件给用户所有权COPY --chown=lanson:lanson   *.txt   /a.txt  RUN ls -l /#不是root不能写RUN  echo 2222 >> a.txt

第七例、 WORKDIR的应用

# WORKDIR的应用FROM alpineRUN pwd && ls -l# 为以下所有的命令运行指定了基础目录WORKDIR /app# 可以为进入容器指定一个默认目录WORKDIR abc##比如我们的nginx镜像可以做成这样#WORKDIR /usr/share/nginx/html# /app/abc  多个WORKDIR可以嵌套RUN pwd && ls -l#复制到当前目录下COPY *.txt   ./RUN  pwd && ls -lCMD ping baidu.com# Nginx镜像WORKDIR应用FROM nginxWORKDIR /usr/share/nginx/html  #剩下都是原来 nginx 默认的

第八例、VOLUME需要注意的坑与EXPOSE使用

第九例、CMD、ENTRYPOINT容器启动指令

FROM alpine  # ENTRYPOINT: 入口(真正的门)# ENTRYPOINT [ "ping" ]# 命令(进门的时候带口令)# 最终的用法: CMD是给ENTRYPOINT提供参数的#CMD可以被修改# CMD ping baidu.com  # ENTRYPOINT + CMD = 容器的完整启动命令# 这是启动命令# ENTRYPOINT ping + CMD baidu.com = 错误#多个CMD只有最后一次生效# CMD ping baidu.com  # ["echo","${param}"] 不是bash -c的方式,取不出环境变量性  【】# echo $param     = ["/bin/sh","-c","多长的命令都写在这里  echo ${param}"]# ENTRYPOINT或者CMD作为唯一入口,只能写一个,最后一个生效# ENTRYPOINT ping atguigu.com# RUN,CMD,ENTRYPOINT# []:  ["/bin/sh","-c"] = shell# shell:FROM alpineENV url=baidu.com#CMD ["ping","baidu.com"]# CMD ["useradd","-u","1000","-g","2000"]# CMD ["ping","${url}"]  取不出变量# CMD ping ${url}  # 官方都是建议使用 []方式# CMD ["/bin/sh","-c","ping ${url}"]  # ENTRYPOINT ping baidu.com + CMD怎么写都没用,容器启动都是以ENTRYPOINT的完整命令为准  # java -jar xxxx.jar --spring.profile=dev --server.port=8888  # 这两个合在一起不能是错误的命令#官方推荐的写法,,变化的写CMD,而CMD是提供参数给ENTRYPOINT# docker run imageName  cmd1  一旦传递了cmd1,CMD指定的所有参数都会被覆盖,# 自定义参数的情况下一定要传完CMD [ "5","baidu.com" ]#exec的写法 不变的写 ENTRYPOINT;未来他是容器启动的唯一入口,ENTRYPOINT [ "ping","-c" ]

第十例、 多阶段构建

FROM alpineRUN  安装mavenRUN mvn clean packageCOPY  xx.jar /app.jarENTRYPOINT [ "java","-jar","app.jar" ]  #SpringBoot应用 java -jar xxx.jar# jre环境;可以自己打包# 一个镜像分为多个大的阶段进行构建,最终的构建结果是最后一个阶段的结果  # 多阶段构建# FROM alpine AS build# xxxxxx  # FROM  jre# COPY  --from=build xxx  xxx# ENTRYPOINT [ "executable" ]FROM  maven:3.6.1-jdk-8-alpine AS buildappWORKDIR /appCOPY pom.xml .COPY src .RUN mvn clean package -Dmaven.test.skip=true# /app 下面有 targetRUN pwd && ls -lRUN cp /app/target/*.jar  /app.jarRUN ls -l### 以上第一阶段结束,我们得到了一个 app.jar  ## 只要一个JREFROM openjdk:8-jre-alpine#FROM openjdk:8u282-slimRUN ln -sf /usr/share/zoneinfo/Asia/Shanghai /etc/localtime && echo 'Asia/Shanghai' >/etc/timezoneLABEL maintainer="lanson"# 把上一个阶段的东西复制过来COPY --from=buildapp /app.jar  /app.jar# docker run -e JAVA_OPTS="-Xmx512m -Xms33 -" -e PARAMS="--spring.profiles=dev --server.port=8080" -jar /app/app.jar# 启动java的命令ENV JAVA_OPTS=""ENV PARAMS=""ENTRYPOINT [ "sh", "-c", "java -Djava.security.egd=file:/dev/./urandom $JAVA_OPTS -jar /app.jar $PARAMS" ]

十大案例比较经典,里面的备注信息一定看,注意点都在写在注释里,如果对Docker还不是很了解可以回顾看我之前的文章:

大数据需要拥抱云原生吗?云原生为什么这么火?_Lansonli的博客

【云原生 | Docker篇】《带你走进Docker的世界》轻松学会原理|架构|安装|加速(一)_Lansonli的博客

【云原生 | Docker篇】轻松学会 Docker命令(二)_Lansonli的博客

【云原生 | Docker篇】网络和存储原理_Lansonli的博客

欢迎点赞 收藏 留言 如有错误敬请指正!作者:Lansonli停下休息的时候不要忘了别人还在奔跑,希望大家抓紧时间学习,全力奔赴更美好的生活

版权声明:本文内容由网络用户投稿,版权归原作者所有,本站不拥有其著作权,亦不承担相应法律责任。如果您发现本站中有涉嫌抄袭或描述失实的内容,请联系我们jiasou666@gmail.com 处理,核实后本网站将在24小时内删除侵权内容。

上一篇:关于jackson序列化和feign返回值的问题
下一篇:【云原生 | Docker篇】深入Dockerfile(四)
相关文章

 发表评论

暂时没有评论,来抢沙发吧~