Dockerfile学习文档

Dockerfile详解

Dockerfile是一个组合映像命令的文本;可以使用在命令行中调用任何命令;Docker通过dockerfile中的指令自动生成镜像。

通过docker build -t repository:tag ./ 即可构建,要求:./下存在Dockerfile文件

之前我们聊的镜像分层,这个层怎么分的,就是由Dockerfile中的每一条指令构成

编写规则

  • 文件名必须是 Dockerfile
  • Dockerfile中所用的所有文件一定要和Dockerfile文件在同一级父目录下
  • Dockerfile中相对路径默认都是Dockerfile所在的目录
  • Dockerfile中一能写到一行的指令,一定要写到一行,因为每条指令都被视为一层,层多了执行效率就慢
  • Dockerfile中指令大小写不敏感,但指令都用大写(约定俗成)
  • Dockerfile 非注释行第一行必须是 FROM
  • Dockerfile 工作空间目录下支持隐藏文件(.dockeringore),类似于git的.gitingore

原文链接:
作者:以九为书
链接:https://www.jianshu.com/p/4508784f6ddc

指令详解

FROM:基础镜像

FROM <image>:<tag> [as other_name]      # tag可选;不写默认是latest版
  • FROM是Dockerfile文件开篇第一个非注释行代码
  • 用于为镜像文件构建过程指定基础镜像,后续的指令都基于该基础镜像环境运行
  • 基础镜像可以是任何一个镜像文件
  • as other_name是可选的,通常用于多阶段构建(有利于减少镜像大小)
  • 使用是通过--from other_name使用,例如COPY --from other_name

LABEL:镜像描述信息

LABEL author="zp wang <test@qq.com>"
LABEL describe="test image"# 或
LABEL author="zp wang <test@qq.com>" describe="test image"# 或
LABEL author="zp wang <test@qq.com>" \describe="test image"
  • LABEL指令用来给镜像以键值对的形式添加一些元数据信息
  • 可以替代MAINTAINER指令
  • 会集成基础镜像中的LABEL,key相同会被覆盖

MAINTAINER:添加作者信息

MAINTAINER zp wang <test@163.com>
  • 慢慢废弃

COPY:从构建主机复制文件到镜像中

COPY <src> <dest>COPY ["<src>", "<src>", ... "<dest>"]
  • <src>:要复制的源文件或目录,支持通配符
  • <src>必须在build所在路径或子路径下,不能是其父目录
  • <src>是目录。其内部的文件和子目录都会递归复制,但<src>目录本身不会被复制
  • 如果指定了多个<src>或使用了通配符,这<dest>必须是一个目录,且必须以/结尾
    #-----------------------------------------分割线--------------------------------------------#
  • <dest>:目标路径,即镜像中文件系统的路径
  • <dest>如果不存在会自动创建,包含其父目录路径也会被创建
# 拷贝一个文件
COPY testFile /opt/# 拷贝一个目录
COPY testDir /opt/testDir

testDir下所有文件和目录都会被递归复制
目标路径要写testDir,否则会复制到/opt下

ADD:从构建宿主机复制文件到镜像中

类似于COPY指令,但ADD支持tar文件还让URL路径

ADD <src> <dest>ADD ["<src>","<src>"... "<dest>"]
  • <src>如果是一个压缩文件(tar),被被解压为一个目录,如果是通过URL下载一个文件不会被解压
  • <src>如果是多个,或使用了通配符,则<dest>必须是以/结尾的目录,否则<src>会被作为一个普通文件,<src>的内容将被写入到<dest>

WORKDIR:设置工作目录

类似于cd命令,为了改变当前的目录域

此后RUN、CMD、ENTRYPOINT、COPY、ADD等命令都在此目录下作为当前工作目录

WORKDIR /opt
  • 如果设置的目录不存在会自动创建,包括他的父目录
  • 一个Dockerfile中WORKDIR可以出现多次,其路径也可以为相对路径,相对路径是基于前一个WORKDIR路径
  • WORKDIR也可以调用ENV指定的变量

ENV:设置镜像中的环境变量

# 一次设置一个
ENV <key> <value># 一次设置多个
ENV <key>=<value> <key1>=<value1> <key2>=<value2> .....

使用环境变量的方式

$varname
${varname}
${varname:-default value}           # 设置一个默认值,如果varname未被设置,值为默认值
${varname:+default value}           # 设置默认值;不管值存不存在都使用默认值

USER:设置启动容器的用户

# 使用用户名
USER testuser# 使用用户的UID
USER UID

RUN:镜像构建时执行的命令

# 语法1,shell 形式
RUN command1 && command2# 语法2,exec 形式
RUN ["executable","param1","[aram2]"]# 示例
RUN echo 1 && echo 2 RUN echo 1 && echo 2 \echo 3 && echo 4RUN ["/bin/bash","-c","echo hello world"]
RUN 在下一次建构期间,会优先查找本地缓存,若不想使用缓存可以通过--no-cache解除
docker build --no-cacheRUN 指令指定的命令是否可以执行取决于 基础镜像shell形式默认使用/bin/sh -c 执行后面的command
可以使用 &&\ 连接多个命令exec形式exec形式被解析为JSON序列,这意味着必须使用双引号 ""
与 shell 形式不同,exec 形式不会调用shell解析。但exec形式可以运行在不包含shell命令的基础镜像中
例如:RUN ["echo","$HOME"] ;这样的指令 $HOME并不会被解析,必须RUN ["/bin/sh","-c","echo $HOME"]

EXPOSE:为容器打开指定的监听端口以实现与外部通信

EXPOSE <port>/<protocol>EXPOSE 80
EXPOSE 80/http
EXPOSE 2379/tcp
<port>:端口号
<protocol>:协议类型,默认TCP协议,tcp/udp/http/https
并不会直接暴露出去,docker run时还需要-P指定才可以,这里更像是一个说明

VOLUME:实现挂载功能,将宿主机目录挂载到容器中

VOLUME ["/data"]                    # [“/data”]可以是一个JsonArray ,也可以是多个值VOLUME /var/log 
VOLUME /var/log /opt
三种写法都是正确的
VOLUME类似于docker run -v /host_data /container_data 。
一般不需要在Dockerfile中写明,且在Kubernetes场景几乎没用

CMD:为容器设置默认启动命令或参数

# 语法1,shell形式
CMD command param1 param2 ...# 语法2,exec形式
CMD ["executable","param1","param2"]# 语法3,还是exec形式,不过仅设置参数
CMD ["param1","param2"]
CMD运行结束后容器将终止,CMD可以被docker run后面的命令覆盖
一个Dockerfile只有顺序向下的最后一个CMD生效语法1,shell形式,默认/bin/sh -c此时运行为shell的子进程,能使用shell的操作符(if、环境变量、? *通配符等)
注意:进程在容器中的 PID != 1,这意味着该进程并不能接受到外部传入的停止信号docker stop语法2,exec形式CMD ["executable","param1","param2"]不会以/bin/sh -c运行(非shell子进程),因此不支持shell的操作符
若运行的命令依赖shell特性,可以手动启动CMD ["/bin/sh","-c","executable","param1"...]语法3,exec形式CMD ["param1","param2"]一般结合ENTRYPOINT指令使用

ENTRYPOINT:用于为容器指定默认运行程序或命令

与CMD类似,但存在区别,主要用于指定启动的父进程,PID=1

# 语法1,shell形式
ENTRYPOINT command# 语法2,exec形式
ENTRYPOINT ["/bin/bash","param1","param2"]
ENTRYPOINT设置默认命令不会被docker run命令行指定的参数覆盖,指定的命令行会被当做参数传递给ENTRYPOINT指定的程序。
docker run命令的 --entrypoint选项可以覆盖ENTRYPOINT指令指定的程序
一个Dockerfile中可以有多个ENTRYPOINT,但只有最后一个生效
ENTRYPOINT主要用于启动父进程,后面跟的参数被当做子进程来启动

ARG:指定环境变量用于构建过程

ARG name[=default value]ARG test_name
ARG nother_name=wzp
ARG指令定义的参数,在构建过程以docker build --build-arg test_name=test 形式赋值若ARG中没有设置默认值,构建时将抛出警告:[Warning] One or more build-args..were not consumedDocker默认存在的ARG 参数,可以在--build-arg时直接使用HTTP_PROXY/http_proxy/HTTPS_PROXY/https_proxy/FTP_PROXY/ftp_proxy/NO_PROXY/no_proxy

ONBUILD:为镜像添加触发器

ONBUILD可以为镜像添加一个触发器,其参数可以是任意一个Dockerfile指令。

ONBUILD <dockerfile_exec> <param1> <param2>ONBUILD RUN mkdir mydir
该指令,对于使用该Dockerfile构建的镜像并不会生效,只有当其他Dockerfile以当前镜像作为基础镜像时被触发
例如:Dockfile A 构建了镜像A,Dockfile B中设置FROM A,此时构建镜像B是会运行ONBUILD设置的指令

STOPSINGAL:设置停止时要发送给PID=1进程的信号

主要的目的是为了让容器内的应用程序在接收到signal之后可以先做一些事情,实现容器的平滑退出,如果不做任何处理,容器将在一段时间之后强制退出,会造成业务的强制中断,这个时间默认是10s。

STOPSIGNAL signal

默认的停止信号为:SIGTERM,也可以通过docker run -s指定

HEALTHCHECK:指定容器健康检查命令

当在一个镜像指定了 HEALTHCHECK 指令后,用其启动容器,初始状态会为 starting,在 HEALTHCHECK 指令检查成功后变为 healthy,如果连续一定次数失败,则会变为 unhealthy

HEALTHCHECK [OPTIONS] CMD command# 示例
HEALTHCHECK --interval=5s --timeout=3s \CMD curl -fs http://localhost/ || exit 1        # 如果执行不成功返回1
出现多次,只有最后一次生效
OPTIONS选项
--interval=30:两次健康检查的间隔,默认为 30 秒;
--timeout=30:健康检查命令运行的超时时间,超过视为失败,默认30秒;
--retries=3:指定失败多少次视为unhealth,默认3次
返回值
0:成功; 1:失败; 2:保留

SHELL:指定shell形式的默认值

SHELL 指令可以指定 RUN、ENTRYPOINT、CMD 指令的 shell,Linux 中默认为[“/bin/sh”, “-c”] ,Windows默认[“CMD”,“/S”,“/C”]

通常用于构建Windows用的镜像

SHELL ["/bin/bash","-c"]SHELL ["powershell", "-command"]# 示例,比如在Windows时,默认shell是["CMD","/S","/C"]
RUN powershell -command Execute-MyCmdlet -param1 "c:\foo.txt"
# docker调用的是cmd /S /C powershell -command Execute-MyCmdlet -param1 "c:\foo.txt"
RUN ["powershell", "-command", "Execute-MyCmdlet", "-param1 \"c:\\foo.txt\""]
# 这样虽然没有调用cmd.exe 但写起来比较麻烦,所以可以通过SHELL  ["powershell", "-command"] 这样省去前边的powershell -command

构建一个运行在一个我自己剪裁过的基础系统二进制包 上的 Java8 镜像

# 通过centos7的二进制包(假设是我自己做了系统裁剪移植)
FROM scratch
ADD centos-7-x86_64-docker.tar.xz /RUN yum install -y wget && \yum clean all && \ln -sf /usr/share/zoneinfo/Asia/Shanghai /etc/localtime && \echo "Asia/Shanghai" > /etc/timezoneENV JAVA_VERSION jdk1.8.0_271
ENV JAVA_HOME /usr/lib/${JAVA_VERSION}
ENV PATH ${JAVA_HOME}/bin:$PATH# 涉及改变镜像大小的指令,尽量放到同一行,这样构建过程中的删除指令对减小体积才能生效
RUN wget --no-cookies --no-check-certificate --header "Cookie: gpw_e24=http%3A%2F%2Fwww.oracle.com%2F; oraclelicense=accept-securebackup-cookie" \http://download.oracle.com/otn-pub/java/jdk/8u271-b09/61ae65e088624f5aaa0b1d2d801acb16/jdk-8u271-linux-x64.tar.gz -O /usr/lib/jdk-8u271-linux-x64.tar.gz && \tar -xf /usr/lib/jdk-8u271-linux-x64.tar.gz -C /usr/lib/ && \rm -rf /usr/lib/jdk-8u271-linux-x64.tar.gz && \rm -rf ${JAVA_HOME}/src.zip \${JAVA_HOME}/lib/visualvm \${JAVA_HOME}/jre/lib/plugin.jar \${JAVA_HOME}/jre/bin/javaws \${JAVA_HOME}/jre/lib/desktop \${JAVA_HOME}/jre/plugin \${JAVA_HOME}/jre/lib/deploy* \${JAVA_HOME}/jre/lib/amd64/libglass.so \${JAVA_HOME}/jre/lib/amd64/libgstreamer-lite.so \${JAVA_HOME}/jre/lib/amd64/libjavafx*.so \${JAVA_HOME}/jre/lib/amd64/libjfx*.soCMD ['/bin/bash']

选⽤最⼩化基础镜像

编写 Dockerfile 时,通常使⽤⼀个通⽤的容器镜像作为基础镜像,例如: eclipse-temurin:8-alpine ,选⽤最

⼩化基础镜像,即只包含项⽬确实需要的系统⼯具和库的镜像,较⼩的基础镜像可以确保在⼀个新节点上拉起容器

时有更快的启动时间(节省了从镜像仓库拉取镜像的⽹络请求时间),并且能够最⼩化系统的攻击⾯,确保所⽤的

操作系统是安全的,⼀般推荐采⽤以 alpine 系统为基础的基础镜像。

# 举一些例子
golang:1.11-alpine3.9
golang:1.15
openjdk:8
adoptopenjdk:8u242-b08-jdk-hotspot-bionic
node:10-alpine
node:16.14.0
node:12-buster-slim
python:3.7-stretch
python:3.7-slim
python:3.7-alpine
nginx:alpine
busybox:alpine
centos:alpine

Dockerfile生产示例

# Build the manager binary
FROM golang:1.16 as builder
WORKDIR /workspaceARG go_proxy=https://goproxy.cn
ENV GO111MODULE=on \GOPROXY=${go_proxy} \CGO_ENABLED=0# Copy the Go Modules manifests
COPY go.mod go.mod
COPY go.sum go.sum
# cache deps before building and copying source so that we don't need to re-download as much
# and so that source changes don't invalidate our downloaded layer
# ENV GOPROXY https://goproxy.cn/
RUN go mod download# Copy the go source
COPY main.go main.go#COPY api/ api/
COPY controllers/ controllers/
COPY pkg/ pkg/# Build
RUN go build -ldflags '-w -s' -a -o manager main.go# Use distroless as minimal base image to package the manager binary
# Refer to https://github.com/GoogleContainerTools/distroless for more details
# FROM gcr.azk8s.cn/distroless/static:latest
FROM alpine:3.14RUN  sed -i 's/dl-cdn.alpinelinux.org/mirrors.ustc.edu.cn/g' /etc/apk/repositories && apk update && apk add subversionWORKDIR /
COPY --from=builder /workspace/manager .
# USER nonroot:nonrootENTRYPOINT ["/manager"]
FROM golang:1.15-alpine as builder
WORKDIR /app
COPY test.go  /app
RUN go build -o test test.goFROM alpine:3.16RUN apk --no-cache --update add \python3 cmd:pip3 vim curl python3-dev gcc musl-dev openssh skopeo openjdk8 zip makeCOPY requirements.txt .
COPY test.zip .
RUN pip3 install --upgrade pip && pip3 install -r /requirements.txt \&& unzip -o -d . /test.zip && rm -f test.zipCOPY --from=builder /app/test /usr/local/bin/testWORKDIR /app
COPY . /app
RUN rm -f /app/test.zipCMD ["/app/docker-run-cmd.sh"]
FROM golang:1.15-alpine as builder
WORKDIR /app
COPY test.go  /app
RUN go build -o test test.goFROM alpine:3.16RUN apk --no-cache --update add \python3 cmd:pip3 vim curl python3-dev gcc musl-dev openssh skopeo openjdk8 zip makeCOPY requirements.txt .
COPY test.zip .
RUN pip3 install --upgrade pip && pip3 install -r /requirements.txt \&& unzip -o -d . /test.zip && rm -f test.zipCOPY --from=builder /app/test /usr/local/bin/testWORKDIR /app
COPY . /app
RUN rm -f /app/test.zipCMD ["/app/docker-run-cmd.sh"]

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/news/586924.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

SpringMVC源码解析——DispatcherServlet的逻辑处理

DispatcherServlet类相关的结构图如下&#xff1a; 其中jakarta.servlet.http.HttpServlet的父类是jakarta.servlet.GenericServlet&#xff0c;实现接口jakarta.servlet.Servlet。我们先看一下jakarta.servlet.Servlet接口的源码如下&#xff1a; /*** 定义所有servlet必须实…

PHP8的JIT(Just-In-Time)编译器是什么?

PHP8的JIT&#xff08;Just-In-Time&#xff09;编译器是什么&#xff1f; PHP8是最新的PHP版本&#xff0c;引入了JIT&#xff08;Just-In-Time&#xff09;编译器&#xff0c;以进一步提高性能和执行速度。 JIT编译器是一种在运行时将解释性语言转化为机器码的技术。在过去…

【网络安全】网络隔离设备

一、网络和终端隔离产品 网络和终端隔离产品分为终端隔离产品和网络隔离产品两大类。终端隔离产品一般指隔离卡或者隔离计算机。网络隔离产品根据产品形态和功能上的不同&#xff0c;该类产品可以分为协议转换产品、网闸和网络单向导入产品三种。 图1为终端隔离产品的一个典型…

2022-2023年度广东省职业院校学生专业技能大赛“软件测试”赛项性能测试题目-Jmeter

性能测试-JM 1、脚本添加: 脚本文件名称:SuppAndComp,测试计划名称:SuppAndComp。测试计划下添加两个线程组: (1)线程组一操作内容:系统管理员登录、进行新增供应商操作。 线程组名称SuppAdd。具体要求如下: 登录操作存放到仅一次控制器中,供应商名称前4位为固定…

dash 中的模式匹配回调函数Pattern-Matching Callbacks 8

模式匹配 模式匹配回调选择器 MATCH、ALL 和 ALLSMALLER 允许您编写可以响应或更新任意或动态数量组件的回调函数。 此示例呈现任意数量的 dcc. Dropdown 元素&#xff0c;并且只要任何 dcc. Dropdown 元素发生更改&#xff0c;就会触发回调。尝试添加几个下拉菜单并选择它们的…

Grafana增加仪表盘

1.Grafana介绍 grafana 是一款采用Go语言编写的开源应用&#xff0c;主要用于大规模指标数据的可视化展现&#xff0c;是网络架构和应用分析中最流行的时序数据展示工具&#xff0c;目前已经支持绝大部分常用的时序数据库。 Grafana下载地址&#xff1a;https://grafana.com/g…

burpsuite的安装与介绍

安装(挑一个你喜欢的版本安装就行) 编程环境安装指南:Java、Python 和 Burp Suite抓包工具_burpsuite和java-CSDN博客 简介 Burp Suite是一个用于攻击Web应用程序的集成平台。它集成了多种渗透测试组件,能够帮助我们更好地完成对Web应用的渗透测试和攻击,无论是自动化还…

基于CNN神经网络的手写字符识别实验报告

作业要求 具体实验内容根据实际情况自拟&#xff0c;可以是传统的BP神经网络&#xff0c;Hopfield神经网络&#xff0c;也可以是深度学习相关内容。 数据集自选&#xff0c;可以是自建数据集&#xff0c;或MNIST&#xff0c;CIFAR10等公开数据集。 实验报告内容包括但不限于&am…

nodejs+vue+微信小程序+python+PHP的会议管理系统-计算机毕业设计推荐

会议管理系统可以为公司领导提供会议记录管理功能&#xff0c;公司领导也就是系统的管理员&#xff0c;具有员工管理、公告管理、会议室管理、会议资料管理、会议投票管理、意见收集管理等管理的权限&#xff0c;添加或者删除用户基本信息。管理员需要先进行登录&#xff0c;获…

[C#]opencvsharp进行图像拼接普通拼接stitch算法拼接

介绍&#xff1a; opencvsharp进行图像拼一般有2种方式&#xff1a;一种是传统方法将2个图片上下或者左右拼接&#xff0c;还有一个方法就是融合拼接&#xff0c;stitch拼接就是一种非常好的算法。opencv里面已经有stitch拼接算法因此我们很容易进行拼接。 效果&#xff1a; …

PayPal账户被封是因为什么?如何解决?

Paypal作为跨境出海玩家最常用的付款工具之一&#xff0c;同时也是最容易出现冻结封号现象。保障PP账号安全非常重要&#xff0c;只有支付渠道安全&#xff0c;才不会“白费力气”&#xff0c;那么最重要的就是要了解它的封号原因以做好规避。 一、Paypal账号被封原因 1、账号…

FreeRTOS列表与列表项相关知识总结以及列表项的插入与删除实战

1.列表与列表项概念及结构体介绍 1.1列表项简介 列表相当于链表&#xff0c;列表项相当于节点&#xff0c;FreeRTOS 中的列表是一个双向环形链表 1.2 列表、列表项、迷你列表项结构体 1&#xff09;列表结构体 typedef struct xLIST { listFIRST_LIST_INTEGRITY_CHECK_VAL…

List常见方法和遍历操作

List集合的特点 有序&#xff1a; 存和取的元素顺序一致有索引&#xff1a;可以通过索引操作元素可重复&#xff1a;存储的元素可以重复 List集合的特有方法 Collection的方法List都继承了List集合因为有索引&#xff0c;所以有了很多操作索引的方法 ublic static void main…

SpringBoot如何优雅的处理免登录接口

在项目开发过程中&#xff0c;会有很多API接口不需要登录就能直接访问&#xff0c;比如公开数据查询之类的 ~ 常规处理方法基本是 使用拦截器或过滤器&#xff0c;拦截需要认证的请求路径。在拦截器中判断session或token信息&#xff0c;如果存在则放行&#xff0c;否则跳转到…

挑战 ChatGPT 和 Google Bard 的防御

到目前为止&#xff0c;科学家已经创建了基于人工智能的聊天机器人&#xff0c;可以帮助内容生成。我们还看到人工智能被用来创建像 WormGPT 这样的恶意软件&#xff0c;尽管地下社区对此并不满意。但现在正在创建聊天机器人&#xff0c;可以使用生成人工智能通过即时注入活动来…

编程笔记 html5cssjs 014 网页布局框架

编程笔记 html5&css&js 014 网页布局框架 一、Bootstrap简介二、使用Bootstrap布局 网页布局不只用HTML&#xff0c;还要用CSS和JAVASCRIPT等技术完成,这里暂时简单了解一下Bootstrap。 一、Bootstrap简介 这是一个开源的前端框架&#xff0c;由Twitter的前端工程师Ma…

OpenHarmony之分布式软总线

背景概述 从之前的文档(OpenHarmony之内核层)可知 分布式软总线是多设备终端的统一基座&#xff0c;为设备间的无缝互联提供了统一的分布式通信能力&#xff0c;能够快速发现并连接设备&#xff0c;高效地传输任务和数据。 分布式软总线实现近场设备间统一的分布式通信管理能…

代码随想录刷题第三十四天| 1005.K次取反后最大化的数组和 ● 134. 加油站 ● 135. 分发糖果

代码随想录刷题第三十四天 K次取反后最大化的数组和 (LC 1005) 题目思路&#xff1a; 代码实现&#xff1a; class Solution:def largestSumAfterKNegations(self, nums: List[int], k: int) -> int:nums.sort(keylambda x: abs(x), reverseTrue)for i in range(len(nums…

Mongodb聚合操作$isNumber

又是mongodb集合的不强制文档具有相同一致的结构产生的问题。Mongodb这种特点&#xff0c;确实带来了灵活强大的优势&#xff0c;但Mongodb的一些操作符和特性看起来在为这种灵活的结构买单。 这次有两个问题。某一个气温监控系统&#xff0c;采用了不同的传感器厂家生产的系统…

8868体育助力意甲罗马俱乐部 迪巴拉有望付出

8868体育助力意甲罗马俱乐部 迪巴拉有望付出 意甲罗马俱乐部是8868体育合作球队之一&#xff0c;本赛季&#xff0c;在意甲第14轮的比赛中&#xff0c;罗马客场2-1战胜萨索洛&#xff0c;积分上升到意甲第4位。 有报道称&#xff0c;迪巴拉在对阵佛罗伦萨的比赛中受伤&#xff…