Dockerfile



一、概念:

Dockerfile由一行行命令语句组成,并且支持以 # 开头的注释行。一般而言,Dockerfile可以分为四部分:

  • 基础镜像信息 – FROM
  • 维护者信息 – LABEL
  • 镜像操作指令 --RUN
  • 启动时执行指令 – CMD

官方文档:https://docs.docker.com/engine/reference/builder/

二、案例:

1.先创建一个Dockerfile文件

vi Dockerfile文件名

2.编写内容

# 从哪里拉取
FROM alpine 
# 相当于代码的注释
LABEL maintainer=wfl

ENV param='Dockerfile' 
# 执行命令并创建新的Image Layer
RUN echo ${param}
	
CMD ["baidu.com"] 

ENTRYPOINT ["ping"] 

3.构建镜像

# .表示当前上下文
docker build -t 镜像名:tag -f Dockerfile文件名 . 

# /:根目录或者/xxx指定目录
docker build -t 镜像名:tag -f Dockerfile文件名 /指定目录 

# 查看构建的镜像
docker images 镜像名

# 可以查看镜像的层级
docker history [IMAGE ID]

4.运行

# 什么都不传则echo Dockerfile 
docker run xxxx
# 传入arg1则echo arg1
docker run xxx arg1

docker run -it 镜像名:tag # 交互模式

docker run -d 镜像名:tag # 后台模式

docker run -d -p 83:80 镜像名:tag  # 后台模式,-p 83:80 映射到本地83端口

三、指令:

FROM:

指定基础镜像

apline、slim、ubuntu等基础小镜像
scratch镜像是一个空镜像,常用于多阶段构建

MAINTAINER:

指定作者信息,已经过时,可以使用LABEL命令来替代

LABEL:

标注镜像的一些说明信息
案例:

LABEL label1="value" label2="value" 

RUN:

镜像构建时运行命令

shell形式和exec形式

  • shell 是 /bin/sh -c <command>的方式
  • exec [“/bin/sh”,“-c”,command] 的方式 ,exec 默认方式不会进行变量替换
    RUN没有上下文关系,RUN cd /dest && ls -l 和 RUN cd /dest RUN ls -l 是不同的命令

两种语法:

RUN <command> ( 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 $HOME"]

案例:

ENV param='Dockerfile' 
RUN echo $param  # 输出:Dockerfile
RUN ["echo","$param"]  # 输出:$param

CMD:设置容器启动后默认执行的命令和参数,可以被修改

CMD 的三种写法:

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

注意:

  • 多个CMD,只有最后一个CMD才会生效;
  • CMD的主要目的是为执行中的容器提供默认值。 这些默认值可以包含可执行文件,也可以省略可执行文件。
CMD ping baidu.com
CMD ["ping","baidu.com"]
CMD ["bin/sh","-c","ping baidu.com"]
# CMD 可以被修改
docker run -it 镜像名:tag ping github.com

# 官方推荐写法
CMD ["baidu.com"]
ENTRYPOINT ["ping"] # exec写法
# CMD给ENTRYPOINT提供参数

ENTRYPOINT:容器启动时会运行的命令

容器启动入口,不可以修改;多个ENTRYPOINT,只有最后一个ENTRYPOINT才会生效

两种写法:

  • ENTRYPOINT [“executable”, “param1”, “param2”] ( exec 方式, 首选方式)
  • ENTRYPOINT command param1 param2 (shell 形式)
ENTRYPOINT ping baidu.com

ARG:

定义变量,使用–build-arg = 传递,docker build命令会将其传递给构建器。

--build-arg:指定参数会覆盖Dockerfile中指定的同名参数,如果用户指定了未在Dockerfile中定义的构建参数 ,则构建会输出警告 。
ARG只在构建期有效,运行期无效。
定义后才生效

ARG param="默认值"
ARG param1="默认值"
RUN echo $param
RUN echo $param1

docker build --build-arg param=Dockerfile1 -t 镜像名:tag -f Dockerfile名 .

ENV:设置一个环境变量,引用常量

指定环境变量,可以在docker run的时候使用 -e 改变value

ENV param='Dockerfile' 
RUN echo $param  # 输出:Dockerfile
CMD echo $param  # 输出:Dockerfile

docker run -it -e param="aaa" 镜像名:tag

ADD:把本地文件添加到Docker image里面

复制指定的src路径下的内容到容器中的dest路径下,自动下载远程文件,自动解压的功能。

src 路径必须在构建的上下文中; 不能使用 …/xx /xx 这种方式,docker构建的第一步是将上下文目录(和子目录)发送到docker守护程序。
src 是URL,那么

  • dest 不以斜杠结尾,则从URL下载文件并将其复制到 dest 。
  • dest 以斜杠结尾,将自动推断出url的名字(保留最后一部分),保存到 dest。

src 是目录,则将复制目录的整个内容,包括文件系统元数据。

FROM alpine
ADD 路径/文件夹 /dest  # 不以斜杠结尾,把当前内容复制到alpine的dest
ADD 路径/文件夹 /dest/ # 以斜杠结尾,把当前内容复制到alpine的dest文件夹下
RUN cd /dest && ls -l

COPY:把本地文件添加到Docker image里面

复制本地主机的src路径下的内容到镜像中的dest路径下,不会自动解压

COPY的两种写法:

  • COPY [–chown=<user>:<group>] <src>… <dest>
  • COPY [–chown=<user>:<group>] [“<src>”,… “<dest>”]

--chown功能仅在用于构建Linux容器的Dockerfiles上受支持,而在Windows容器上不起作用。
COPY指令从 src 复制新文件或目录,并将它们添加到容器的文件系统中,路径为 dest 。
可以指定多个 src 资源,但是文件和目录的路径将被解释为相对于构建上下文的源。
每个 src 都可以包含通配符,并且匹配将使用Go的filepath.Match规则进行。

COPY hom* /dest/ #当前上下文,以home开始的所有资源 
COPY hom?.txt /dest/ # ?匹配单个字符 
COPY test.txt relativeDir/ # 目标路径如果设置为相对路径,则相对与 WORKDIR 开始 # 把 “test.txt”添加到<WORKDIR>/relativeDir/ 
COPY test.txt /absoluteDir/ #也可以使用绝对路径,复制到容器指定位置 

#所有复制的新文件都是uid(0)/gid(0)的用户,可以使用--chown改变,添加用户权限和用户组
COPY --chown=55:group1 files* /dest/ 
COPY --chown=bin files* /dest/ 
COPY --chown=1 files* /dest/ 

USER:

设置运行映像时要使用的用户名(或UID)以及可选的用户组(或GID),以及Dockerfile 中USER后面所有RUN,CMD和ENTRYPOINT指令。相当于给容器开一个用户权限,可以用这个权限去运行容器。

USER <user>[:<group>] 
USER <UID>[:<GID>]

WORKDIR,类似cd

为WORKDIR以下的指令,指定了基础目录。 若目录不存在,则创建。
可在Dockerfile中多次使用。 如果提供了相对路径,则它将相对于上一个WORKDIR指令的路径。

WORKDIR /w
RUN pwd #结果 /w

WORKDIR ww
RUN pwd #结果 /w/ww

ENV path=/w
WORKDIR $path 
RUN pwd 
#结果 /w

VOLUME:

创建数据卷挂载点,把容器的某些文件夹映射到主机外部,不存在则创建,一般用于挂载日志。

注意:对于声明后的卷内容的修改会被丢弃,所以一定在volume声明之前修改内容 ;

RUN mkdir /text #创建text文件
RUN echo aaa > /text/a.text #写入aaa到a.text文件

VOLUME ["/text"] #可以是JSON数组 
#VOLUME /text #可以直接写 
#VOLUME /text/a /text/b #可以空格分割多个

RUN echo bbb >> /text/a.text # 不生效

EXPOSE:

只是声明镜像内服务监听的端口

通知Docker容器在运行时在指定的网络端口上进行侦听。 可以指定端口是侦听TCP还 是UDP,如果未指定协议,则默认值为TCP。
实际上不会发布端口。 它充当构建映像的人员和运行容器的人员之间的一种文档,即有关打算发布哪些端口的信息。 要在运行容器时实际发布端口,请在docker run上使用-p标志发布并映射一个或多个端口,或使用-P标志发布所有公开的端口并将其映射到高阶端口。

EXPOSE <port> [<port>/<protocol>...] 
EXPOSE [80,443] 
EXPOSE 80/tcp 
EXPOSE 80/udp

HEALTHCHECK:

健康检查

多阶段构建

官方文档:https://docs.docker.com/develop/develop-images/multistage-build/

目的是如何让一个镜像变得更小。
选择最小的基础镜像
合并RUN环节的所有指令,少生成一些层
RUN期间可能安装其他程序会生成临时缓存,要自行删除。
使用 .dockerignore 文件,排除上下文中无需参与构建的资源
合理使用构建缓存加速构建。[–no-cache]
https://github.com/docker-library/

案例1:

1.先在项目下创建Dockerfile(保证Dockerfile和项目在同一个文件夹)
2.先上传Java项目到服务器
3.进入项目下,可查看

在这里插入图片描述

4.修改Dockerfile文件,可以全部复制使用
# 环境构建,在https://hub.docker.com/_/maven/tags?page=1&name=alpine搜索,
# AS builder 取别名
FROM maven:3.8.6-eclipse-temurin-8-alpine AS builder 

# 第一种:指定工作目录
#WORKDIR /app 
#ADD ./ /app 

#第一种: 将pom.xml和src拷贝到/app文件下
WORKDIR /app 
COPY pom.xml .
COPY src .

# 打包
RUN mvn clean package -Dmaven.test.skip=true 

# 将target下的所有jar包,都变成app.jar
RUN cp /app/target/*.jar /app.jar 

# 安装运行环境
FROM openjdk:8u282-slim
# 修改时区,可以让镜像时间同步。
# RUN /bin/cp /usr/share/zoneinfo/Asia/Shanghai /etc/localtime && echo 'Asia/Shanghai' >/etc/timezone 
# 或 RUN ln -sf /usr/share/zoneinfo/Asia/Shanghai /etc/localtime && echo 'Asia/Shanghai' >/etc/timezone 
RUN ln -sf /usr/share/zoneinfo/Asia/Shanghai /etc/localtime && echo 'Asia/Shanghai' >/etc/timezone 
# 作者
LABEL maintainer="test" 

# --from=builder 来自于上一个阶段复制内容,都复制过来
# 
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" ]
5.配置dockerignore
#创建
touch  .dockerignore 
#编辑
vi .dockerignore 
#具体的内容
.git
*.impl
target/*
6.构建镜像:docker build -t demo:java
7.启动:docker run -d -P demo:java

案例2:springboot-java 的Dockerfile写法

#FROM openjdk:8-jre-alpine 
FROM openjdk:8u282-slim
LABEL maintainer="test" 
# 需要服务已经打好了包上传
# 将target下的所有jar包,都变成app.jar
COPY target/*.jar /app.jar 
# 修改时区,touch /app.jar; 记录最后保存记录的时间(ls -lah)
RUN apk add -U tzdata && ln -sf /usr/share/zoneinfo/Asia/Shanghai /etc/localtime && echo 'Asia/Shanghai' >/etc/timezone && touch /app.jar; 

ENV JAVA_OPTS="" 
ENV PARAMS="" 
EXPOSE 8080 
ENTRYPOINT [ "sh", "-c", "java -Djava.security.egd=file:/dev/./urandom $JAVA_OPTS -jar /app.jar $PARAMS" ]

# 运行命令 docker run -e JAVA_OPTS="-Xmx512m -" -e PARAMS="--spring.profiles=dev --server.port=8080" -jar /app/app.jar
  • 1
    点赞
  • 4
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值