欢迎您访问程序员文章站本站旨在为大家提供分享程序员计算机编程知识!
您现在的位置是: 首页

Docker 使用Dockerfile创建镜像

程序员文章站 2024-01-26 12:40:16
...

Docker 使用Dockerfile创建镜像

Dockerfile由一行行命令语句组成,并且支持以#开头的注释行。
一般而言,Dockerfile主体内容分为四部分:基础镜像信息,维护者信息,镜像操作指令和容器启动时执行指令。

简单示例:使用Dockerfile创建java镜像
在本地新建一个空目录,在其中创建Dockerfile文件,在Dockerfile中,加入需要执行的Java编译命令,例如:

#指定基础镜像,本地没有会从dockerhub pull下来
FROM java:8
#作者
LABEL maintainer bigdata
#复制内容到镜像,格式为copy <src> <dest>
COPY . /usr/src/javaapp
#WORKDIR 为后续的RUM、CMD、ENTRYPOINT指令配置工作目录
WORKDIR /usr/src/javaapp
#运行指定指令RUN <command> 或 RUN ["executable","paraml","param2"]
#前者默认将在shell终端中运行命令,即/bin/sh -c;
#后者则使用exec执行
RUN javac HelloWorld.java
# cmd指令用来指定启动容器时默认执行的命令
CMD ["java","HelloWorld"]

构建Java镜像

#-f指定Dockerfile文件的路径
#-t指定镜像名字和TAG
#.指定当前目录,实际上需要一个上下文路径
docker build -t java-image .

Docker 使用Dockerfile创建镜像
运行此镜像自动编译程序并执行

docker run -it --rm --name java-container java-image

Docker 使用Dockerfile创建镜像
查看java容器日志

docker logs java-container

查看java容器详细信息

docker inspect java-container

Dockerfile常用指令

From

FROM指令是最重要的一个并且必须为Dockerfile文件开篇的第一个非注释行,指定所创建像的基础镜像,后续的指令运行于此基础镜像提供的运行环境。
默认情况下docker build会从本地仓库找指定的镜像文件,如果不存在就会从Docker Hub上拉取。
语法:

FROM <image>
FROM <image>:<tag>

LABEL

LABEL指令可以为生成的镜像添加元数据标签信息,这些信息可以用来辅助过滤出特定镜像。
语法:

LABEL <key>=<value> <key>=<value> <key>=<value>

COPY

用于从宿主机复制文件到创建的新镜像文件
语法:
src:要复制的源文件或者目录,可以使用通配符
dest:目标路径,即正在创建的image的文件系统路径,建议使用绝对路径,否则copy指令则以WORKDIR为其起始路径

COPY <src> <dest>

注意:

  1. src必须是上下文中的路径,不能是其父目录中的文件
  2. src是目录,则其内部文件或子目录会被递归复制,但src目录自身不会被复制
  3. 指定了多个src或在src中使用了通配符,则dest必须是一个目录,以/符号结尾
  4. dest不存在,将会被自动创建,包括其父目录路径

ADD

添加内容到镜像,支持使用TAR文件和URL路径
语法:
该命令将复制指定的路径下内容到容器中的路径下

ADD <src> <dest>

注意:

  1. src:和COPY注意事项相同
  2. 如果src为URL并且dest没有以/结尾,则src指定的文件将被下载到dest
  3. 如果src是一个本地系统上压缩格式的tar文件,会展开成一个目录;但是通过URL获取的tar文件不会自动展开。
  4. 如果src有多个,直接或间接使用了通配符指定多个资源,则dest必须是目录并且以/结尾

#### WORKDIR
为后续的RUN、CMD、ENTRYPOINT指令配置工作目录
语法:

```bash
WORKDIR <dirpath>

在Dockerfile文件中,WORKDIR可以出现多次,路径可以是相对路径,但是它是相对于前一个WORKDIR指令指定的路径,另外,WORKDIR可以是ENV指定定义的变量

ENV

用来给镜像定义所需要的环境变量,并且可以被Dockerfile文件中位于其后的其他指令(如ENV、ADD、COPY等)所调用,调用格式:${variable_name}
语法:

ENV <key> <value>
ENV <key>=<value> ..

第一种格式中,key之后的所有内容都会被视为value的组成部分,所以一次只能设置一个变量
第二种格式可以一次设置多个变量,如果value当中有空格可以使用\进行转义或者对value加引号进行标识,另外\也可以用来续行。

ARG

定义创建镜像过程中使用的变量
语法:

ARG <name>[=<default value>]

在执行docker build时,可以通过-build-arg[=]来为变量赋值。当镜像编译成功后,ARG指定的变量将不再存在(ENV指定的变量将在镜像中保留)

RUN

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

RUN <command>
RUN <"<executable>","<paraml>","<param2>"]

前者默认将在shell终端中运行命令,即/bin/sh -c;
后者指令会被解析为JSON数组,因此必须用双引号,当中executable是要运行的命令,后面是传递给命令的选项或者参数。使用exec执行,不会启动shell环境。如果允许的命令依赖shell特性,可以替换成类型如下的格式:

RUN ["/bin/bash","-c","<executable>","<paraml>"]

CMD

指定启动容器时默认执行的命令。
语法:
支持三种格式

CMD <command>
CMD ["<executable","<paraml>","<param2>"]
CMD ["<param1>","<param2>"],用于为ENTRYPOINT提供默认参数

RUN和CMD区别:

  1. RUN指令运行于镜像文件构建过程中,CMD则运行于基于Dockerfile构建出的新镜像文件启动为一个容器的时候
  2. CMD指令的主要目的在于给启动的容器指定默认要运行的程序,且在运行结束后,容器也将终止。CMD命令可以被docker run的命令选项给覆盖
  3. Dockerfile中可以存在多个CMD指令,但是只有最后一个会生效

ENTRYPOINT

指定镜像的默认入口命令,该入口命令会在启动容器时作为根命令执行,所有传入值作为该命令的参数。
支持两种格式:

ENTRYPOINT command param1 param2
ENTRYPOINT ["executable","paraml","param2"]

和CMD命令不同的是ENTRYPOINT启动的程序不会被docker run命令指定的参数所覆盖,这些命令行参数会被当做参数传递给ENTRYPOINT指定的程序(docker run命令的-entrypoint参数可以覆盖ENTRYPOINT)

docker run命令传入的参数会覆盖CMD指令的内容并且附加到ENTRYPOINT命令最后作为其参数使用
同样,Dockerfile中可以存在多个ENTRYPOINT指令,但是只有最后一个会生效

Dockerfile中如果既有CMD又有ENTRYPOINT,并且CMD是一个完整可执行命令,那么谁在最后谁生效

ONBUILD

用来在Dockerfile中定义一个触发器,指定当基于所生成镜像创建子镜像时,自动执行的操作指令。
语法:

ONBUILD <instruction>

Dockerfile用来构建镜像文件,镜像文件也可以当成是基础镜像被另外一个Dockerfile用作FROM指令的参数,后面这个Dockerfile中的FROM指令在构建过程中被执行的时候,会触发基础镜像里面的ONBUILD指令。
ONBUILD不能自我嵌套,ONBUILD不会触发FROM指令。
在ONBUILD指令中使用ADD和COPY要小心,因为新构建过程中的上下文在缺少指定的源文件的时候会失败。

EXPOSE

声明镜像内服务监听的端口
语法:

EXPOSE <port>

该指令只是起到声明作用,并不会自动完成端口映射。
如果要映射端口出来,在启动容器时可以使用-P参数(Docker主机会自动分配一个宿主机的临时端口)或-P HOST_PORT:CONTAINER_PORT参数(具体指定所映射的本地端口)

VOLUME

创建一个数据挂载点
语法:

VOLUME ["/data"]

运行容器时可以从本地主机或其他容器挂载数据卷,一般用来存放数据库和需要保持的数据等。

完整Dockerfile实例:创建tomcat镜像

创建Dockerfile文件

#指定基础镜像,本地没有会从dockerhub pull下来
FROM centos
#设置变量
ARG myname
#添加元数据标签信息
LABEL authon=$myname

#复制文件到镜像
ADD jdk-8u221-linux-x64.tar.gz /usr/local
ADD apache-tomcat-9.0.36.tar.gz /usr/local

#配置环境变量
ENV JAVA_HOME /usr/local/jdk1.8.0_221
ENV CLASSPATH .:$JAVA_HOME/lib
ENV CATALINA_HOME /usr/local/apache-tomcat-9.0.36
ENV PATH $PATH:$JAVA_HOME/bin:$CATALINA_HOME/bin

WORKDIR $CATALINA_HOME

RUN yum -y install vim

VOLUME ["/data"]

EXPOSE 8080

CMD ls

ENTRYPOINT ["cataline.sh","run"]

构建镜像

docker build -t tomcat-image .

查看tomcat-image镜像

docker images
REPOSITORY                                      TAG                 IMAGE ID            CREATED             SIZE
tomcat-image                                 latest              947798e7f694        About an hour ago   695MB

启动容器

docker run -d -p 8080:8080 --name tomcat-container tomcat-image

查看tomcat-container容器是否在运行

docker ps

查看容器信息和日志

docker logs tomcat-container
docker inspect tomcat-container

Docker 使用Dockerfile创建镜像
查看网页
Docker 使用Dockerfile创建镜像
完成通过Dockerfile构建tomcat

相关命令

#查看正在运行的容器
docker ps
#删除容器
docker rm tomcat-container
#删除镜像
docker rmi tomcat-image
相关标签: linux