docker (二) - 生成镜像
俩种方式:
-
更新镜像
docker commit
-
构建镜像
docker build
更新镜像
先使用基础镜像创建一个容器,然后对容器内容进行更改,然后使用 docker commit 命令提交为一个新的镜像(以tomcat为例)。
# 根据基础镜像,创建容器
> docker run --name tom1 -p 80:8080 -d tomcat
# 修改容器内容
> docker exec -it tom1 /bin/bash
> cd webapps/ROOT rm -f index.jsp
> echo hello world > index.html
> exit
# 提交为新镜像 - 在本地生成
# docker commit -m="描述消息" -a="作者" 容器ID或容器名 镜像名:TAG
docker commit -m="修改了首页" -a="jimmy" tom1 jimmy/tomcat:v1.0
# 使用新镜像运行容器
docker run --name tom2 -p 8080:8080 -d jimmy/tomcat:v1.0
构建镜像
构建镜像需要使用Dockerfile
Dockerfifile常用指令
-
FROM
FROM指令是最重要的一个并且必须为Dockerfifile文件开篇的第一个非注释行,用于为镜像文件构建过程指定基础镜像,后续的指令运行于此基础镜像提供的运行环境。这个基础镜像可以是任何可用镜像,默认情况下docker build会从本地仓库找指定的镜像文件,如果不存在就会从Docker Hub上拉取。
FROM <image>
FROM <image>:<tag>
FROM <image>@<digest>
-
MAINTAINER
Dockerfifile的制作者提供的本人详细信息.
Dockerfifile不限制MAINTAINER出现的位置,但是推荐放到FROM指令之后
MAINTAINER <name>
可以用LABLE替代
-
LABEL
给镜像指定各种元数据
LABEL <key>=<value> <key>=<value> <key>=<value>...
-
COPY
用于从宿主机复制文件到创建的新镜像文件。
COPY <src>...<dest>
COPY ["<src>",..."<dest>"]
# :要复制的源文件或者目录,可以使用通配符
# :目标路径,即正在创建的image的文件系统路径;建议使用绝对路径,否则COPY指令则以
WORKDIR
为 其起始路径a. 必须是build上下文中的路径,不能是其父目录中的文件
b.如果 是目录,则其内部文件或子目录会被递归复制,但 目录自身不会被复制
c.如果指定了多个 ,或在 中使用了通配符,则 必须是一个目录,则必须以**/**符号结尾
d.如果 不存在,将会被自动创建,包括其父目录路径
-
ADD
基本用法和COPY指令一样,ADD支持使用TAR文件和URL路径。
ADD <src>...<dest>
ADD ["<src>",..."<dest>"]
add会自动解压压缩包
-
WORKDIR
用于为Dockerfifile中所有的RUN、CMD、ENTRYPOINT、COPY和ADD指定设定工作目录,只会影响当前WORKDIR之后的指令。
WORKDIR <dirpath>
-
VOLUME
用来创建挂载点,可以挂载宿主机上的卷或者其他容器上的卷
VOLUME <mountpoint>
VOLUME ["<mountpoint>"]
-
EXPOSE
用于给容器打开指定要监听的端口以实现和外部通信
EXPOSE <port>[/<protocol>] [<port>[/<protocol>]...]
-
ENV
用来给镜像定义所需要的环境变量,并且可以被Dockerfifile文件中位于其后的其他指令(如ENV、ADD、COPY等)所调用,调用格式: v a r i a b l e n a m e 或 者 variable_name或者 variablename或者{variable_name}
ENV <key> <value>
ENV <key>=<value>...
-
ARG
指定一个变量,可以在docker build创建镜像的时候,使用 --build-arg = 来指定参数
ARG <name>[=<default value>]
-
RUN
用来指定docker build过程中运行指定的命令
RUN <command>
:参数一般是一个shell命令,以 /bin/sh -c 来运行它RUN ["<executable>","<param1>","<param2>"]
:参数是一个JSON格式的数组,当中 是要运行的命令,后面是传递给命令的选项或者参数; -
CMD
容器启动时运行的命令
CMD <command>
CMD ["<executable>","<param1>","<param2>"]
CMD ["<param1>","<param2>"]
RUN和CMD区别:
-
RUN指令运行于镜像文件构建过程中,CMD则运行于基于Dockerfifile构建出的新镜像文件启动为一个容器的时候
-
CMD指令的主要目的在于给启动的容器指定默认要运行的程序,且在运行结束后,容器也将终止;不过,CMD命令可以被docker run的命令行选项给覆盖
-
Dockerfifile中可以存在多个CMD指令,但是只有最后一个会生效
-
-
ENTRYPOINT
类似于CMD指令功能,用于给容器指定默认运行程序
E
NTRYPOINT<command>
ENTRYPOINT["<executable>","<param1>","<param2>"]
-
ONBUILD
用来在Dockerfifile中定义一个触发器
ONBUILD <instruction>
Dockerfifile用来构建镜像文件,镜像文件也可以当成是基础镜像被另外一个Dockerfifile用作FROM指令的参数在后面这个Dockerfifile中的FROM指令在构建过程中被执行的时候,会触发基础镜像里面的ONBUILDONBUILD不能自我嵌套,ONBUILD不会触发FROM和MAINTAINER指令在ONBUILD指令中使用ADD和COPY要小心,因为新构建过程中的上下文在缺少指定的源文件的时候会失败
实例使用dockerfile构建自己的镜像
# 找到一个目录
> mk dir /usr/local/dockerfile
# 将tomcat.tar.gz 和 jdk.tar.gz 压缩文件上传至这个文件夹
# 创建`Dockerfile`文件
> vim Dockerfile
# 写入内容:
~FROM centos:7
~LABEL author=jimmy
~# 挂载
~VOLUME ["/data1"]
~
~# 解压文件
~ADD apache-tomcat-7.0.92.tar.gz /usr/local/
~ADD jdk-8u60-linux-x64.tar.gz /usr/local/
~
~# 环境变量
~ENV JAVA_HOME=/usr/local/jdk1.8.0_60
~ENV CLASSPATH .:$JAVA_HOME/lib
~ENV CATALINA_HOME=/usr/local/apache-tomcat-7.0.92
~ENV PATH=$PATH:$JAVA_HOME/bin:$CATALINA_HOME/bin
~
~# 暴露端口
~EXPOSE 8080
~
~# 指定工作目录
~WORKDIR $CATALINA_HOME
~# 执行命令
~RUN yum install -y vim
~
~# 容器默认启动程序
~ENTRYPOINT ["catalina.sh","run"]~
# 保存Dockerfile,然后执行docker build。注意最后一个 . 这个表示当前目录不可省略
docker build -t jimmy/tomcat7.0.92:v1 .