深入Dockerfile 与 项目打包镜像示例

Dockerfile

Dockerfile是什么

dockerfile是用来构建镜像的一个文本文件,文件里面由一行行的命令(指令)组成,一般而讲Dockerfile可以分为 四个 部分:

  • 基础镜像信息
  • 维护者信息
  • 镜像操作指令
  • 启动执行指令

Dockerfile指令

dockerfile一般由许多指令组成,各个指令意义如下表格:

指令说明
FROM指定基础镜像
LABEL指定维护者信息,可以使用LABEL maintainer=xxx 来标注作者信息
RUN运行命令 v
CMD指定启动容器时默认的命令 v
ENTRYPOINT指定镜像的默认入口.运行命令 v
EXPOSE声明镜像内服务监听的端口 v
ENV指定环境变量,可以在docker run的时候使用-e改变 v
ADD复制指定的src路径下的内容到容器中的dest路径下,src可以为url会自动下载,可以为tar文件,会自动解压
COPY复制本地主机的src路径下的内容到镜像中的dest路径下,但不会自动解压等
LABEL指定生成镜像的元数据标签信息
VOLUME创建数据卷挂载点
USER指定运行容器时的用户名或UID
WORKDIR配置工作目录,为后续的RUN、CMD、ENTRYPOINT指令配置工作目录ARG指定镜像内使用的参数(如版本号信息等),可以在build的时候,使用–build-args改变 v
OBBUILD配置当创建的镜像作为其他镜像的基础镜像是,所指定的创建操作指令
STOPSIGNAL容器退出的信号值
HEALTHCHECK健康检查
SHELL指定使用shell时的默认shell类型

主要指令说明

FROM

FROM 指定基础镜像,最好挑一些apline,slim之类的基础小镜像.

如何确定我需要什么要的基础镜像?

  • Java应用当然是java基础镜像(SpringBoot应用)或者Tomcat基础镜像(War应用)
  • JS模块化应用一般用nodejs基础镜像
  • 其他各种语言用自己的服务器或者基础环境镜像,如python、golang、java、php等
LABEL

标注镜像的一些说明信息,如:

LABEL maintainer=xxx # 用来来标注作者信息

RUN
  • RUN指令只在构建镜像的时候生效。
  • RUN指令在当前镜像层顶部的新层执行任何命令,并提交结果,生成新的镜像层。
  • 生成的提交映像将用于Dockerfile中的下一步。 分层运行RUN指令并生成提交符合Docker的核心概念,就像源代码控制一样。
  • RUN ( shell 形式, /bin/sh -c 的方式运行,避免破坏shell字符串)
  • RUN [“executable”, “param1”, “param2”] ( exec 形式)
RUN /bin/bash -c 'source $HOME/.bashrc; \
echo $HOME'
#上面等于下面这种写法
RUN /bin/bash -c 'source $HOME/.bashrc; echo $HOME'
RUN ["/bin/bash", "-c", "echo hello"]

什么是shell和exec形式

  1. shell 是 /bin/sh -c 的方式,
  2. exec [“/bin/sh”,“-c”,command] 的方式== shell方式,也就是exec 默认方式不会进行变量替换
CMD和ENTRYPOINT
  1. CMD和ENTRYPOINT都可以作为容器启动的入口
  2. 在制作镜像的dockerfile的时候,一般是使用CMD 和 ENTRYPOINT进行组合来作为完整的容器的启动命令

ENTRYPOINT: 作为启动命令
CMD: 作为命令的参数

CMD的三种写法

  • CMD ["executable","param1","param2"] ( exec 方式, 首选方式)
  • CMD ["param1","param2"] (为ENTRYPOINT提供默认参数)
  • CMD command param1 param2 ( shell 形式)

ENTRYPOINT 的两种写法

  • ENTRYPOINT ["executable", "param1", "param2"] ( exec 方式, 首选方式)
  • ENTRYPOINT command param1 param2 (shell 形式)
# 一个示例
FROM alpine
LABEL maintainer=fangyajun
CMD ["1111"]
ENTRYPOINT ["echo"]
#构建出如上镜像后测试
docker run xxxx:效果 echo 1111

组合最终效果

在这里插入图片描述

ARG和ENV

ARG:

  • ARG指令定义了一个变量,用户可以在构建时使用–build-arg = 传递,docker build命令会将其传递给构建器。
  • –build-arg 指定参数会覆盖Dockerfile 中指定的同名参数
  • ARG只在构建期有效,运行期无效

ENV:

  • 在构建阶段中所有后续指令的环境中使用,并且在许多情况下也可以内联替换。
  • ENV 指令在启动运行的时候可以修改,而ARG指令只在构建的时候生效,这是2个最大的不同
  • docker run --env 可以修改这些值
  • 容器运行时ENV值可以生效
ADD和COPY

COPY的两种写法:
在这里插入图片描述
src: 代表的是宿主机的文件目录
dest: 指的是容器的目录,

如下示例:

FROM alpine
LABEL maintainer="fangyajun"
## 容器下面的所有的工作目录
WORKDIR /myapp/
# 把本地宿主机当前的目录 *.tar.gz 的压缩包添加进镜像的/myapp/目录下(add 会自动解压压缩包)
# . 代表容器的当前目录
COPY *.tar.gz .

RUN  pwd && ls -l

ADD指令
同COPY用法,不过 ADD拥有自动下载远程文件和解压的功能。

注意:

  • src 路径必须在构建的上下文中; 不能使用 …/something /something 这种方式,因为docker
    构建的第一步是将上下文目录(和子目录)发送到docker守护程序。
  • 如果 src 是URL,并且 dest 不以斜杠结尾,则从URL下载文件并将其复制到 dest 。
  • 如果 dest 以斜杠结尾,将自动推断出url的名字(保留最后一部分),保存到 dest
  • 如果 src 是目录,则将复制目录的整个内容,包括文件系统元数据。
WORKDIR和VOLUME
  • WORKDIR指令为Dockerfile中跟随它的所有 RUN,CMD,ENTRYPOINT,COPY,ADD 指令设置工作目录。 如果WORKDIR不存在,即使以后的Dockerfile指令中未使用它也将被创建。

  • WORKDIR指令可在Dockerfile中多次使用。 如果提供了相对路径,则它将相对于上一个WORKDIR指令的路径。 例如:

    WORKDIR /a
    WORKDIR b
    WORKDIR c
    RUN pwd
    #结果 /a/b/c
    

VOLUME
作用:把容器的某些文件夹映射到主机外部
写法:

# 把docker容器中的/var/log/ 挂载到宿主机中,宿主机是匿名卷,可以使用docker inspect 来查看
VOLUME ["/var/log/"]  
VOLUME /var/log  #可以直接写
VOLUME /var/log /var/db #可以空格分割多个

项目打包进行与多阶段构建

多阶段构建

如何让一个镜像变得更小; 多阶段构建的典型示例

### 我们如何打包一个Java镜像
FROM maven
WORKDIR /app
COPY . .
RUN mvn clean package
COPY /app/target/*.jar /app/app.jar
ENTRYPOINT java -jar app.jar
## 这样的镜像有多大?
## 我们最小做到多大??

生产示例

以下所有前提 保证Dockerfile和项目在同一个文件夹

# 第一阶段:环境构建;
FROM maven:3.5.0-jdk-8-alpine AS builder
# 指定docker容器的工作目录
WORKDIR /app
# 复制宿主机的当前目录(当前目录必须有pom.xml文件和src文件夹)的所有内容 到容器的/app 目录下
ADD ./ /app
## 运行打包命令
RUN mvn clean package -Dmaven.test.skip=true
# 第二阶段,最小运行时环境,只需要jre
FROM openjdk:8-jre-alpine
# 修改时区
RUN ln -sf /usr/share/zoneinfo/Asia/Shanghai /etc/localtime && echo
'Asia/Shanghai' >/etc/timezone
LABEL maintainer="534096094@qq.com"
# 从上一个阶段复制内容
COPY --from=builder /app/target/*.jar /app.jar
ENV JAVA_OPTS=""
ENV PARAMS=""
# 运行jar包
ENTRYPOINT [ "sh", "-c", "java -Djava.security.egd=file:/dev/./urandom $JAVA_OPTS
-jar /app.jar $PARAMS" ]
  • 1
    点赞
  • 4
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值