Dockerfile指令与构建Java web基本镜像

Dockerfile

简介

Dockerfile 是用于构建 Docker 镜像的脚本文件,由一系列指令构成。通过 docker build 命令构建镜像时,Dockerfile 中的指令由上到下依次执行,每条命令都将会构建出一个镜像。这就是镜像分层。因此,指令越多,层次就越多,创建的镜像就越多,效率就越低。所以在定义 Dockerfile 时,能在一个指令完成的动作就不要分为两条。

指令简介

  • 指令时大小写不敏感的,但是规范时全大写
  • 指令后至少携带一个参数
  • # 号开头的行是注释

FROM

语法:FROM <image>[:<tag>]

解析:用于指定基础镜像,且必须是第一条指令,若省略了 tag,则默认为 latest。

MAINTAINER

语法:MAINTAINER <name>

解析:MAINTAINER 指令的参数一般是维护者姓名和邮箱。不过,该指令官方已不建议使用,而是使用 LABEL 指令代替。

LABEL

语法:LABEL <key>=<value> <key>=<value>…

解析:LABEL 指令中可以键值对的方式包含任意镜像的元数据信息,用于代替 MAINTAINER 指令。通过 docker inspect 可以查看到 LABEL 与 MAINTAINER 的内容。

ENV

语法:ENV <key> <value>

解析:用于指定环境变量,这些环境变量,后续可以被 RUN 指令使用,容器运行起来之后,也可以在容器中获得这些环境变量。

语法2:ENV <key1>=<value1> <key2>=<value2> …

解析:可以设置多个变量,每个变量为一对<key>=<value>指定。

WORKDIR

语法:WORKDIR path

解析:容器打开后默认进入的目录,一般在后续的 RUN、CMD、ENTRYPOINT、ADD 等指令中会引用该目录。可以设置多个 WORKDIR 指令。后续 WORKDIR 指令若用的是相对路径,则会基于之前 WORKDIR 指定的路径。在使用 docker run 运行容器时,可以通过 -w 参数覆盖构建时所设置的工作目录。

RUN

语法1:RUN <command>

解析:这里的 <command> 就是 shell 命令。docker build 执行过程中,会使用 shell 运行指定的 command。

语法2:RUN [“EXECUTABLE”, “PARAM1”, “PARAM2”, …]

解析:在 docker build 执行过程中,会调用一个参数 “EXECUTABLE” 指定应用程序运行,并使用后面第二、第三参数作为应用程序的运行参数。

CMD

语法1:CMD [“EXECUTABLE”, “PARAM1”, “PARAM2”, …]

解析:在容器启动后,即在执行完 docker run 后立即调用执行 “EXECUTABLE” 指定的可执行文件,并使用后面第二、三等参数哦作为应用程序的运行参数。

语法2:CMD command param1 param2 …

解析:这里的 command 就是 shell 命令。在容器启动后会立即运行指定的 shell 命令。

语法3:CMD [“PARAM1”, “PARAM2”, …]

解析:提供给 ENTERPOINT 的默认参数。

ENTRYPOINT

语法1:ENTRYPOINT [“EXECUTABLE”, “PARAM1”, “PARAM2”, …]

解析:在容器启动过程中,即在执行 docker run 时,会调用执行 “EXECUTABLE” 指定的应用程序,并使用后面第二、三等参数作为应用程序的运行参数。

语法2:ENTRYPOINT command param1 param2 …

解析:这里的 command 就是 shell 命令。在容器启动过程中,即执行 docker run 时,会运行指定 shell 命令。

EXPOSE

语法:EXPOSE <port> [<port>…]

解析:指定容器准备对外暴露的端口号,但该端口号并不会真正的对外暴露。若要真正暴露,则需要在执行 docker run 命令时使用 -p 来指定说要真正暴露的端口号。

ARG

语法:ARG <varname>[=<default value>]

解析:定义一个变量,该变量将会使用于镜像构建运行时。若要定义多个变量,则需要定义多个 ARG 指令。

ADD

语法1:ADD <src> <dest>

语法2:ADD [“<src>”, “<dest>”] # 路径中存在空格时需要用双引号引起来

解析:该指令将复制到当前宿主机中指定文件 src 到容器中指定目录 dest 中。src 可以时宿主机中的绝对路径,也可以是相对路径。但相对路径时相对于 docker build 命令所指定的路径。src 指定的文件可以时一个压缩文件,压缩文件复制到容器后会自动解压为目录。src 也可以是一个 URL,此时 ADD 指令相当于 wget 命令。src 最好不要是目录,其会将该目录中所有内容复制到容器的指定目录中。dest 是一个绝对路径,其最后面的路径必须要加上斜杠,否则系统会将最后的目录名称当作是文件名的。

COPY

说明:功能与 ADD 指令相同,只不过 src 不能是 URL。若 src 为压缩文件,复制到到容器后不会自动解压。

ONBUILD

语法:ONBUILD [INSTRUCTION]

解析:该指令用于指定当前镜像的子镜像进行构建时要执行的指令。

VOLUME

语法:VOLUME [“dir1”, “dir2”, …]

解析:在容器创建可以挂载的数据卷。

docker build 命令

使用 docker build 命令构建镜像

docker build [OPTIONS] PATH | URL | -

# 基本使用示例
docker build -t test:1.0 .
  • -t 用于要生成镜像的 <repository>与<tag>。若省略 tag,则默认为 latest。
  • 最后的 点(.)是宿主机的 URL 路径,构建镜像时会从该路径中查找 Dockerfile 文件。同时该路径也是在 Dockerfile 中 ADD、COPY 指令中若使用的相对路径,那个相对路径就相对这个路径。不过需要注意,即使 ADD、COPY 指令中使用绝对路径指定源文件,该源文件所在路径也必须要在这个 URL 指定目录或子目录内,否则将无法找到该文件
# 指定 Dockerfile
docker build -f ./Dockerfile2 -t test:1.0 .
  • -f 用于指定本次构建所要使用的 Dockerfile 文件。如果文件名不是 docker build 默认加载的 Dockerfile 这个文件名。

构建自己的镜像

自己的 hello world 程序镜像

首先到docker hub上查看我们原先测试docker是否安装成功的 hello world 镜像的Dockerfile,我们先简单模仿这个镜像来写一个我们自己的。

在这里插入图片描述

上面就是 hello-world 镜像的Dockerfile

其中 FROM 指令前面介绍过了,时指定一个基础镜像。这里的 scratch 就是一个基础镜像,它是一个空镜像,是所有镜像的 Base Image (相当于面向对象编程中的 Object类)scratch 镜像只能在 Dockerfile 中被继承,不能通过 pull 命令拉取,不能 run,也没有 tag。并且它也不会生成镜像中的文件系统层。在 Docker 中,scratch 是一个保留字,用户不能作为自己的镜像名称使用。

首先,我们先在Linux系统下安装 gcc 相关编译器,用于编译 c 语言代码(仅作为本次实验,后续不会用到 c 语言相关带代码)

# c 语言编译器
yum install -y gcc gcc-c++
# 编译时需要使用 C 的静态类库,所以要再安装 glibc-static
yum install -y glibc-static

安装完成后,创建一个 hello.c 的文件,并写入如下内容:

#include<stdio.h>
int main()
{
  printf("-----------------\nhello docker!\n-----------------\n");
  return 0;
}

编写完成后,编译 hello.c 文件

# 编译 hello.c 得到 hello 可执行文件
gcc --static -o hello hello.c

在该目录下创建 Dockerfile 文件。内容如下:

FROM scratch
ADD hello /
CMD ["/hello"]

执行 docker build 命令来构建我们自己的 hello-world

docker build -t hello-world:test .

在这里插入图片描述

运行这个构建好的镜像查看结果,会发现,与我们自己所编写的输出格式一致。成功的构建了第一个镜像。

在这里插入图片描述

实际Java web项目构建镜像

构建目标:使用 centos:7 镜像作为基础镜像运行一个 Java web 项目,并成功运行以及可以请求其接口。

  1. 创建项目

    在这里插入图片描述

    在这里插入图片描述

    创建完成后,pom文件中注释掉下面这句(<skip>true</skip> 如果不注释,编译为jar后运行会报错,找不到主类)

    在这里插入图片描述

    修改 application.yaml 文件,设置端口为 8080

    在这里插入图片描述

    添加 controller 并编写一个简单的接口并启动测试

    在这里插入图片描述

  2. 所需文件整理

    测试完成后,使用 maven 打包为jar,将打包后的jar文件复制另一个目录(这里是我个人习惯,为了区分每次构建的东西,所以专门建立了一个DockerSpaces的目录,下面是每次所要构建具体镜像的目录)

    在这里插入图片描述

    将所需要的 jdk-1.8 也拷贝到该目录下(jdk是Oracle官网下载的)

  3. 编写Dockerfile

    在下面建立 Dockerfile 文件。内容如下:

    # 基础镜像
    FROM centos:7
    
    # 作者信息
    LABEL name=AutoNek email=neko.auto@hotmail.com
    
    # 添加 jkd 包
    ADD jdk-8u391-linux-x64.tar.gz /opt/java/
    
    # 设置 jdk 环境变量
    ENV JAVA_HOME=/opt/java/jdk1.8.0_391
    ENV CLASSPATH=.:$JAVA_HOME/lib/dt.jar:$JAVA_HOME/lib/tools.jar
    ENV PATH=$JAVA_HOME/bin:$PATH
    
    # 添加项目包
    ADD testpro-0.0.1-SNAPSHOT.jar /root/testpro/
    
    # 设置目录
    WORKDIR /root
    
    # 暴露端口
    EXPOSE 8080
    
    # 启动命令
    ENTRYPOINT ["java", "-jar", "/root/testpro/testpro-0.0.1-SNAPSHOT.jar"]
    
  4. 构建并启动容器

    构建为镜像并查看

    docker -t helloweb:1.0 .
    
    # 查看镜像
    docker images
    
    # 运行该镜像
    docker run -dp 8082:8080 --name myhello helloweb:1.0
    
    # 查看运行中的镜像
    docker ps
    

    在这里插入图片描述

    查看log日志

    在这里插入图片描述

    同样,访问该接口也是没有问题的

    在这里插入图片描述

    至此我们自己的 Java web 项目就成功构建成了镜像并且发布成功。

  • 22
    点赞
  • 20
    收藏
    觉得还不错? 一键收藏
  • 1
    评论
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值