docker生成镜像的两种方式

基于一个基础镜像构建一个自己的镜像有两种方式:
  1.更新镜像:使用 docker commit 命令生成新的镜像
  2.构建镜像:使用 docker build 命令,需要创建Dockerfile文件
一:更新镜像
  先使用基础镜像创建一个容器,然后对容器内容进行更改,然后使用 docker commit 命令提交为一个新的镜像(以tomcat为例)。
  1.从仓库拉取最新的镜像
docker pull tomcat

  2.根据基础镜像,创建容器

docker run --name tomcat01 -p 80:8080 -d tomcat

 注意:如果是从阿里云镜像仓库拿到的镜像,在webapps里面没有文件,因为阿里云镜像默认是最小的镜像,所有不必要的都被剔除,将webapps.dist中的文件copy到webapp中即可解决(命令:cp -r webapps.dist/* webapps

 3.修改容器内容

docker exec -it tomcat01 /bin/bash 
cd webapps/ROOT 
rm -f index.jsp 
echo hello world > index.html exit

   4.提交为新镜像

#docker commit -m="描述消息" -a="作者" 容器ID或容器名 镜像名:TAG
docker commit -m="自定义的Tomcat镜像" -a="wk" mytomcat wk/tomcat:v1.0

  5.1 将自己的镜像上传到dockerHub

#第一步 先登录自己的docker仓库
docker login
#输入用户名和密码

#修改镜像名字
#docker tag SOURCE_IMAGE[:TAG] TARGET_IMAGE[:TAG]  注意这里的目标镜像需要使用你dockerhub上的用户名  类似我的wkdocker01
docker tag wk/tomcat:v01 wkdocker01/tomcat:v1.0

#上传自己的镜像
docker push wkdocker01/tomcat:v1.0

  5.2 将自己的镜像上传到阿里云

    阿里云容器镜像地址:https://cr.console.aliyun.com/cn-hangzhou/repositories

    首先在自己的阿里云容器镜像中创建自己的镜像仓库

               

    选本地仓库 ,通过命令推送到阿里云镜像仓库

     

     然后进入到自己的镜像仓库,这里有操作步骤教你上传镜像

    

  6.使用子的镜像来运行容器(当然也可以在dockerHub上pull下来自己空间的镜像)

docker run --name mytom -p 8091:8080 -d wk/tomcat:v1.0

 二:使用DockerFile构建spring boot项目镜像

  1.准备:把自己的springboot项目打包成可执行jar包

  2.把jar包上传到Linux服务器

  3.开始构建自己的项目容器

    3.1:在jar包路径下创建Dockerfile文件 vi Dockerfile

# 指定基础镜像,本地没有会从dockerHub pull下来 
FROM java:8 
#作者 MAINTAINER wk 
# 把可执行jar包复制到基础镜像的根目录下 
ADD smart-admin.jar /smart-admin.jar 
# 镜像要暴露的端口,如要使用端口,在执行docker run命令时使用-p生效 
EXPOSE 8080 # 在镜像运行为容器后执行的命令 ENTRYPOINT ["java","-jar","/smart-admin.jar"]

    3.2:使用 docker build 命令构建镜像,基本语法

docker build -t wkdocker01/smart-admin:v1 . 
# -f指定Dockerfile文件的路径
# -t指定镜像名字和TAG
# .指当前目录,这里实际上需要一个上下文路径

  4.运行自己的项目

docker run --name smart-admin -p 8080:8080 -d wkdocker01/smart-admin:v1 

三:把自己的vue前端项目上传到docker容器运行:

  1.首先创建一个default.conf文件,用户替换nginx目录下的default.conf文件

server {
    listen       80;
    server_name   127.0.0.1; # 修改为docker服务宿主机的ip

    location / {
        root   /usr/share/nginx/html;
        index  index.html index.htm;
        try_files $uri $uri/ /index.html =404;
    }
    location /smart-admin-api{ # smart-admin-api是vue项目里.env.production里的地址
         proxy_pass http://127.0.0.1:10086/smart-admin-api/;  # 这里写的是你后端接口的地址
    }

    error_page   500 502 503 504  /50x.html;
    location = /50x.html {
        root   html;
    }
}

  该配置文件定义了首页的指向为 /usr/share/nginx/html/index.html, 所以我们可以一会把构建出来的index.html文件和相关的静态资源放到/usr/share/nginx/html目录下。

  2.创建DockerFile文件

FROM nginx

MAINTAINER wk

#删除目录下的default.conf文件
RUN rm /etc/nginx/conf.d/default.conf

#将default.conf复制到/etc/nginx/conf.d/下,用本地的default.conf配置来替换nginx镜像里的默认配置
ADD default.conf /etc/nginx/conf.d/

#将项目根目录下dist文件夹(构建之后才会生成)下的所有文件复制到镜像/usr/share/nginx/html/目录下 
COPY dist/ /usr/share/nginx/html/

  3.将通过npm run build 打包好的dist文件拷贝到当前路径下

  4.通过docker build命令构建镜像,注意不要少了. (点)

docker build -t smart-admin-vue:v1.0 .

  5.通过docke run 启动容器

docker run --name smart-admin-vue -p 10085:80 -d smart-admin-vue:v1.0

  6.通过执行docker ps查看是否启动成功容器

 四:dockerFile常用的几个命令:

  FROM

  FROM指令是最重要的一个并且必须为Dockerfifile文件开篇的第一个非注释行,用于为镜像文件构建过程指定基础镜像,后续的指令运行于此基础镜像提供的运行环境

这个基础镜像可以是任何可用镜像,默认情况下docker build会从本地仓库找指定的镜像文件,如果不存在就会从Docker Hub上拉取
  语法:
FROM <image> 
FROM <image>:<tag>
FROM <image>@<digest>

  MAINTAINER(depreacted)

  Dockerfifile的制作者提供的本人详细信息

  Dockerfifile不限制MAINTAINER出现的位置,但是推荐放到FROM指令之后

  语法:

MAINTAINER <name>

  name可以是任何文本信息,一般用作者名称或者邮箱

  LABEL
  给镜像指定各种元数据
  语法:
LABEL <key>=<value> <key>=<value> <key>=<value>...

  一个Dockerfifile可以写多个LABEL,但是不推荐这么做,Dockerfifile每一条指令都会生成一层镜像,如果LABEL太长可以使用\符号换行。构建的镜像会继承基础镜像的LABEL,并且会去掉重复的,但如果值不同,则后面的值会覆盖前面的值。

  COPY

  用于从宿主机复制文件到创建的新镜像文件
  语法:
COPY <src>...<dest> 

COPY ["<src>",..."<dest>"]
# <src>:要复制的源文件或者目录,可以使用通配符
# <dest>:目标路径,即正在创建的image的文件系统路径;建议<dest>使用绝对路径,否则COPY指令则以WORKDIR为 其起始路径
  注意:如果你的路径中有空白字符,通常会使用第二种格式
  规则:
    <src> 必须是build上下文中的路径,不能是其父目录中的文件
    如果 <src> 是目录,则其内部文件或子目录会被递归复制,但 <src> 目录自身不会被复制
    如果指定了多个 <src> ,或在 <src> 中使用了通配符,则 <dest> 必须是一个目录,则必须以/符号结尾
    如果 <dest> 不存在,将会被自动创建,包括其父目录路径
  ADD
  基本用法和COPY指令一样,ADD支持使用TAR文件和URL路径
  语法:
ADD <src>...<dest> 

ADD ["<src>",..."<dest>"]
  规则:
  和COPY规则相同
  如果 <src> 为URL并且 <dest> 没有以/结尾,则 <src> 指定的文件将被下载到 <dest>
  如果 <src> 是一个本地系统上压缩格式的tar文件,它会展开成一个目录;但是通过URL获取的tar文件不会自动展开
  如果 <src> 有多个,直接或间接使用了通配符指定多个资源,则 <dest> 必须是目录并且以/结尾
  WORKDIR
  用于为Dockerfifile中所有的RUN、CMD、ENTRYPOINT、COPY和ADD指定设定工作目录,只会影响当前WORKDIR之后的指令。
  语法:
WORKDIR <dirpath>
  在Dockerfifile文件中,WORKDIR可以出现多次,路径可以是相对路径,但是它是相对于前一个WORKDIR指令指定的路径
  另外,WORKDIR可以是ENV指定定义的变量
  VOLUME
  用来创建挂载点,可以挂载宿主机上的卷或者其他容器上的卷
  语法:
VOLUME <mountpoint> 

VOLUME ["<mountpoint>"]

  不能指定宿主机当中的目录,宿主机挂载的目录是自动生成的

  EXPOSE
  用于给容器打开指定要监听的端口以实现和外部通信
  语法:
EXPOSE <port>[/<protocol>] [<port>[/<protocol>]...]
  <protocol> 用于指定传输层协议,可以是TCP或者UDP,默认是TCP协议
  EXPOSE可以一次性指定多个端口,例如: EXPOSE 80/tcp 80/udp
  ENV
  用来给镜像定义所需要的环境变量,并且可以被Dockerfile文件中位于其后的其他指令(如ENV、ADD、COPY等)所调用,调用格式:$variable_name或者${variable_name}
  语法:
ENV <key> <value> 

ENV <key>=<value>...
  第一种格式中, <key> 之后的所有内容都会被视为 <value> 的组成部分,所以一次只能设置一个变量
  第二种格式可以一次设置多个变量,如果 <value> 当中有空格可以使用\进行转义或者对 <value> 加引号进行标识;另外\也可以用来续行 
  ARG
  用法同ENV
  语法:
ARG <name>[=<default value>]

  指定一个变量,可以在docker build创建镜像的时候,使用 --build-arg <varname>=<value> 来指定参数

  RUN
  用来指定docker build过程中运行指定的命令
  语法:
RUN <command> 

RUN ["<executable>","<param1>","<param2>"]
  第一种格式里面的参数一般是一个shell命令,以 /bin/sh -c 来运行它
  第二种格式中的参数是一个JSON格式的数组,当中 <executable> 是要运行的命令,后面是传递给命令的选项或者参数;但是这种格式不会用 /bin/sh -c 来发起,所以常见的shell操作像变量替换和通配符替换不会进行;如果你运行的命令依赖shell特性,可以替换成类型以下的格式
RUN ["/bin/bash","-c","<executable>","<param1>"]
  CMD
  容器启动时运行的命令
  语法:
CMD <command> 

CMD ["<executable>","<param1>","<param2>"]

CMD ["<param1>","<param2>"]
  前两种语法和RUN相同
  第三种语法用于为ENTRYPOINT指令提供默认参数
  RUN和CMD区别:
  RUN指令运行于镜像文件构建过程中,CMD则运行于基于Dockerfifile构建出的新镜像文件启动为一个容器的时候
  CMD指令的主要目的在于给启动的容器指定默认要运行的程序,且在运行结束后,容器也将终止;不过,CMD命令可以被docker run的命令行选项给覆盖
  Dockerfifile中可以存在多个CMD指令,但是只有最后一个会生效
  ENTRYPOINT
  类似于CMD指令功能,用于给容器指定默认运行程序
  语法:
ENTRYPOINT<command> 

ENTRYPOINT["<executable>","<param1>","<param2>"]
  和CMD不同的是ENTRYPOINT启动的程序不会被docker run命令指定的参数所覆盖,而且,这些命令行参数会被当做参数传递给ENTRYPOINT指定的程序(但是,docker run命令的--entrypoint参数可以覆盖ENTRYPOINT)
  docker run命令传入的参数会覆盖CMD指令的内容并且附加到ENTRYPOINT命令最后作为其参数使用
  同样,Dockerfifile中可以存在多个ENTRYPOINT指令,但是只有最后一个会生效
  Dockerfifile中如果既有CMD又有ENTRYPOINT,并且CMD是一个完整可执行命令,那么谁在最后谁生效
  ONBUILD
  用来在Dockerfifile中定义一个触发器
  语法:
ONBUILD <instruction>
  Dockerfifile用来构建镜像文件,镜像文件也可以当成是基础镜像被另外一个Dockerfifile用作FROM指令的参数在后面这个Dockerfifile中的FROM指令在构建过程中被执行的时候,会触发基础镜像里面的ONBUILD指令
ONBUILD不能自我嵌套,ONBUILD不会触发FROM和MAINTAINER指令
在ONBUILD指令中使用ADD和COPY要小心,因为新构建过程中的上下文在缺少指定的源文件的时候会失败
 
posted @ 2021-12-07 22:42  WK_BlogYard  阅读(4987)  评论(0编辑  收藏  举报