12 Dockerfile详解

news2024/11/18 0:16:00

目录

1. Dockerfile

2. Dockerfile构建过程

2.1. Dockerfile编写规则:

2.2. Docker执行Dockerfile的大致流程

2.3. 总结

3. Dockerfile指令

3.1. FROM

3.2. MAINTAINER

3.3. RUN

3.4. EXPOSE

3.5. WORKDIR

3.6. USER

3.7. ENV

3.8. VOLUME

3.9. ADD

3.10. COPY

3.11. CMD

3.12. ENTRYPOINT

4. dockerfile文件的命名

4.1. 默认名称

4.2. 自定义名称

4.3. 命名惯例

5. docker build

5.1. 基本语法

5.2. 常用选项

5.3. 构建上下文

6. Demo

6.1. 自定义镜像centosjava8

6.2. 自定义ubuntu

7. 虚悬镜像


官网参考:https://docs.docker.com/engine/reference/builder/

1. Dockerfile

Dockerfile是用来构建Docker镜像的文本文件,是由一条条构建镜像所需的指令和参数构成的脚本。

构建步骤:

  1. 编写Dockerfile文件
  2. docker build命令构建镜像
  3. docker run依据镜像运行容器实例

docker commit 在容器内操作

Dockerfile在容器外操作


2. Dockerfile构建过程

2.1. Dockerfile编写规则:
  • 每条保留字指令都必须为大写字母,且后面要跟随至少一个参数
  • 指令按照从上到下顺序执行
  • #表示注释
  • 每条指令都会创建一个新的镜像层并对镜像进行提交
2.2. Docker执行Dockerfile的大致流程
  1. docker从基础镜像运行一个容器
  2. 执行一条指令并对容器做出修改
  3. 执行类似docker commit的操作提交一个新的镜像层
  4. docker再基于刚提交的镜像运行一个新容器
  5. 执行Dockerfile中的下一条指令,直到所有指令都执行完成
2.3. 总结

从应用软件的角度来看,Dockerfile、Docker镜像与Docker容器分别代表软件的三个不同阶段,

  • Dockerfile是软件的原材料
  • Docker镜像是软件的交付品
  • Docker容器则可以认为是软件镜像的运行态,也即依照镜像运行的容器实例

Dockerfile面向开发,Docker镜像成为交付标准,Docker容器则涉及部署与运维,三者缺一不可,合力充当Docker体系的基石。

  1. Dockerfile,需要定义一个Dockerfile,Dockerfile定义了进程需要的一切东西。Dockerfile涉及的内容包括执行代码或者是文件、环境变量、依赖包、运行时环境、动态链接库、操作系统的发行版、服务进程和内核进程(当应用进程需要和系统服务和内核进程打交道,这时需要考虑如何设计namespace的权限控制)等等;
  2. Docker镜像,在用Dockerfile定义一个文件之后,docker build时会产生一个Docker镜像,当运行 Docker镜像时会真正开始提供服务;
  3. Docker容器,容器是直接提供服务的。

3. Dockerfile指令

参考参考tomcat8的dockerfile入门 https://github.com/docker-library/tomcat

3.1. FROM

基础镜像,当前新镜像是基于哪个镜像的,指定一个已经存在的镜像作为模板。Dockerfile第一条必须是FROM

# FROM 镜像名
FROM hub.c.163.com/library/tomcat
3.2. MAINTAINER

镜像维护者的姓名和邮箱地址

# 非必须
MAINTAINER ZhangSan zs@163.com
3.3. RUN

容器构建时需要运行的命令。

有两种格式:

  • shell格式
格式:RUN <命令行命令>
# <命令行命令>等同于在终端操作的shell命令
RUN yum -y install vim
  • exec格式
# 格式:RUN ["可执行文件" , "参数1", "参数2"]
RUN ["./test.php", "dev", "offline"]  # 等价于 RUN ./test.php dev offline

RUN是在docker build时运行

3.4. EXPOSE

当前容器对外暴露出的端口。

# EXPOSE 要暴露的端口
# EXPOSE <port>[/<protocol] ....
EXPOSE 3306 33060
3.5. WORKDIR

指定在创建容器后, 终端默认登录进来的工作目录。(终端默认登陆的进来工作目录,一个落脚点)

ENV CATALINA_HOME /usr/local/tomcat
WORKDIR $CATALINA_HOME

ENV环境变量

3.6. USER

指定该镜像以什么样的用户去执行,如果不指定,默认是root。(一般不修改该配置)

# USER <user>[:<group>]
USER patrick
3.7. ENV

用来在构建镜像过程中设置环境变量。

这个环境变量可以在后续的任何RUN指令或其他指令中使用。这就如同在命令前面指定了环境变量前缀一样;

也可以在其它指令中直接使用这些环境变量,

比如:WORKDIR $MY_PATH

# 格式 ENV 环境变量名 环境变量值
# 或者 ENV 环境变量名=值
ENV MY_PATH /usr/mytest

# 使用环境变量
WORKDIR $MY_PATH
3.8. VOLUME

容器数据卷,用于数据保存和持久化工作。类似于 docker run-v参数。

# VOLUME 挂载点
# 挂载点可以是一个路径,也可以是数组(数组中的每一项必须用双引号)
VOLUME /var/lib/mysql
3.9. ADD

将宿主机目录下(或远程文件)的文件拷贝进镜像,且会自动处理URL和解压tar压缩包。

ADD jdk-8u171-linux-x64.tar.gz /usr/local/java/
3.10. COPY

类似ADD,拷贝文件和目录到镜像中。

将从构建上下文目录中<源路径>的文件目录复制到新的一层镜像内的<目标路径>位置。

COPY src dest
COPY ["src", "dest"]
# <src源路径>:源文件或者源目录
# <dest目标路径>:容器内的指定路径,该路径不用事先建好。如果不存在会自动创建
3.11. CMD

指定容器启动时默认执行的命令,通常用于提供默认的可执行文件或参数。CMD指令在Dockerfile中只能有一个,如果定义了多个,只有最后一个会生效。

CMD指令有三种形式:

    1. Shell 形式:CMD <command>
    2. Exec 形式:CMD ["executable", "param1", "param2"]
    3. 参数形式:CMD ["param1", "param2"]

shell格式

  • 使用默认的Shell(例如/bin/sh)来执行命令 。 在这种形式下,CMD指令中的命令将通过Shell解析。这意味着可以使用Shell的功能,如环境变量、命令替换等。
格式:CMD <命令>
---------------------------------------------------
CMD echo "Hello, World!"

exec格式

  • 推荐的形式,因为它更明确,并且不依赖Shell 。 这种形式将命令和参数作为JSON数组传递给exec,直接执行命令而不通过Shell。
格式:CMD ["可执行文件/命令", "参数1", "参数2" ...]
---------------------------------------------------
CMD ["catalina.sh", "run"]
或者
CMD ["echo", "Hello, World!"]

参数列表格式

  • 参数形式主要用于与ENTRYPOINT指令结合使用。可以提供默认参数,而可执行文件则由ENTRYPOINT指定。
格式:CMD ["参数1", "参数2" ....],与ENTRYPOINT指令配合使用
---------------------------------------------------
ENTRYPOINT ["echo"]
CMD ["Hello, World!"]
#CMD提供了echo命令的默认参数。如果运行容器时没有指定其他参数,echo Hello, World!将被执行。

Dockerfile中如果出现多个CMD指令,只有最后一个生效。CMD会被docker run之后的参数替换。

demo:对于tomcat镜像,执行以下命令会有不同的效果:

# 因为tomcat的Dockerfile中指定了 CMD ["catalina.sh", "run"]
# 所以直接docker run 时,容器启动后会自动执行 catalina.sh run
docker run -it -p 8080:8080 tomcat

# 指定容器启动后执行 /bin/bash
# 此时指定的/bin/bash会覆盖掉Dockerfile中指定的 CMD ["catalina.sh", "run"]
docker run -it -p 8080:8080 tomcat /bin/bash
#最终会导致原来能够访问的tomcat不能访问

CMD是在docker run时运行,而 RUN是在docker build时运行。

3.12. ENTRYPOINT

ENTRYPOINT指定要运行的可执行文件/运行的命令

类似于CMD命令,但是ENTRYPOINT不会被docker run后面的命令覆盖,这些命令参数会被当做参数送给ENTRYPOINT指令指定的程序。

ENTRYPOINT可以和CMD一起用,一般是可变参数才会使用CMD,这里的CMD等于是在给ENTRYPOINT传参。

当指定了ENTRYPOINT后,CMD的含义就发生了变化,不再是直接运行期命令,而是将CMD的内容作为参数传递给ENTRYPOINT指令,它们两个组合会变成 <ENTRYPOINT> "<CMD>"

在一个Dockerfile中只能有一个有效的ENTRYPOINT指令。如果在Dockerfile中定义了多个ENTRYPOINT指令,只有最后一个ENTRYPOINT指令会生效,前面的所有ENTRYPOINT指令都会被忽略。

demo:

FROM nginx

ENTRYPOINT ["nginx", "-c"]  # 定参
CMD ["/etc/nginx/nginx.conf"] # 变参

对于此Dockerfile,构建成镜像 nginx:test后,如果执行;

  • docker run nginx:test,则容器启动后,会执行 nginx -c /etc/nginx/nginx.conf
  • docker run nginx:test /app/nginx/new.conf,则容器启动后,会执行 nginx -c /app/nginx/new.conf
FROM ubuntu
ENTRYPOINT ["python"]
CMD ["app.py"]
容器启动时默认执行python app.py,但用户可以覆盖CMD参数。例如:
docker run myimage script.py
容器将运行python script.py

4. dockerfile文件的命名

4.1. 默认名称
  • Dockerfile: 默认情况下,Docker期望构建上下文目录中有一个名为 Dockerfile 的文件。如果文件名是 Dockerfile,则在运行 docker build 命令时无需指定文件名。例如:
docker build -t myimage .
4.2. 自定义名称
  • 自定义Dockerfile名称: 如果需要使用不同的文件名,可以在 docker build 命令中使用 -f 选项来指定Dockerfile的路径和名称。例如:
docker build -t myimage -f MyDockerfile .
4.3. 命名惯例
  • 区分用途: 在大型项目中,可能需要多个Dockerfile来构建不同的环境或镜像。在这种情况下,可以使用描述性名称来区分不同的Dockerfile。例如:

使用描述性名称可以帮助团队成员更清晰地理解每个Dockerfile的用途,并避免混淆。

    • Dockerfile.dev:用于开发环境的Dockerfile。
    • Dockerfile.prod:用于生产环境的Dockerfile。
    • Dockerfile.test:用于测试环境的Dockerfile。

5. docker build

5.1. 基本语法
docker build [OPTIONS] PATH | URL | -
  • PATH:本地目录的路径,包含Dockerfile和所有需要的文件。
  • URL:远程Git仓库URL,Docker引擎将从这个URL拉取Dockerfile和相关文件。
  • -:从标准输入读取Dockerfile内容
5.2. 常用选项
  1. -t, --tag
    • 用于为构建的镜像指定标签(名称)<repository>:<tag>
docker build -t myapp:latest .
  1. -f, --file
    • 指定Dockerfile的路径(默认是当前目录下的Dockerfile)
docker build -f ./path/to/Dockerfile -t myapp:latest .
  1. --build-arg
    • 传递构建时的参数,用于在Dockerfile中替换ARG指令。
docker build --build-arg VERSION=1.0 -t myapp:latest .
  1. --no-cache
    • 禁用构建缓存,每次构建都会重新执行所有指令。
docker build --no-cache -t myapp:latest .
  1. --pull
    • 总是尝试从注册表中拉取最新的基础镜像。
docker build --pull -t myapp:latest .
  1. --rm
    • 构建成功后移除中间容器(默认行为)
docker build --rm -t myapp:latest .
  1. --quiet, -q
    • 只输出最终的镜像ID
docker build -q -t myapp:latest .
5.3. 构建上下文

docker build -t 新镜像名字:TAG .

. 当前目录构建上下文。构建上下文是指 Docker 引擎在构建镜像时需要访问的所有文件和目录的集合

指定其他路径作为构建上下文

docker build -t mynodeapp:latest /path/to/myapp

注意:

  • 尽量保持构建上下文精简:构建上下文中的文件越多,打包和传输给 Docker 守护进程的时间越长。可以使用 .dockerignore 文件来排除不需要的文件和目录
  • .dockerignore 文件:类似于 .gitignore,你可以在构建上下文目录中创建 .dockerignore 文件,列出要排除的文件和目录
# 忽略 node_modules 目录
node_modules
# 忽略日志文件
*.log
# 忽略 Git 目录
.git
# 忽略 Dockerfile 中定义的所有缓存和临时文件
tmp
cache
*.tmp
# 忽略构建输出目录
dist
build

6. Demo

6.1. 自定义镜像centosjava8

需求:Centos7镜像具备vim+ifconfig+jdk8

JDK下载地址:Java Downloads | Oracle

前置准备:jdk-8u411-linux-x64.tar.gz centos:7

 docker pull centos:7

创建名称为Dockerfile(大写字母D)的文件,示例:

FROM centos:7

LABEL maintainer="fujiang <fujiang@qq.com>"

ENV MYPATH=/usr/local
WORKDIR $MYPATH

# 替换 CentOS 源为阿里云源
RUN mv /etc/yum.repos.d/CentOS-Base.repo /etc/yum.repos.d/CentOS-Base.repo.bak && \
    curl -o /etc/yum.repos.d/CentOS-Base.repo http://mirrors.aliyun.com/repo/Centos-7.repo && \
    yum clean all && yum makecache

RUN yum install -y vim
RUN yum install -y net-tools
RUN yum install -y glibc.i686

RUN mkdir /usr/local/java
ADD jdk-8u411-linux-x64.tar.gz /usr/local/java

ENV JAVA_HOME=/usr/local/java/jdk1.8.0_171
ENV JRE_HOME=$JAVA_HOME/jre
ENV CLASSPATH=$JAVA_HOME/lib/dt.jar:$JAVA_HOME/lib/tools.jar:$JRE_HOME/lib
ENV PATH=$JAVA_HOME/bin:$PATH

EXPOSE 80

CMD ["/bin/bash"]

编写完成之后,将其构建成docker镜像。

命令:

docker build -t centosjava8:1.5 .
[root@rockylinux Centos7_jdk8]# docker run -it centosjava8:1.5
[root@84b89218c171 local]# pwd
/usr/local
6.2. 自定义ubuntu
[root@rockylinux myubuntu]# pwd
/app/myubuntu
[root@rockylinux myubuntu]# cat Dockerfile
FROM ubuntu
MAINTAINER fujiang <fujiang@qq.com>
ENV MYPATH /usr/local
WORKDIR $MYPATH
RUN apt-get update
RUN apt-get install -y net-tools
RUN apt-get install -y tcpdump
RUN apt-get install -y vim
EXPOSE 80
CMD echo $MYPATH
CMD echo "install inconfig cmd into ubuntu success--------------ok"
CMD /bin/bash
[root@rockylinux myubuntu]#docker build -t myubuntu:v1 .
---------------------------------------------------------------------
[root@rockylinux Centos7_jdk8]# docker run -it myubuntu:v1
root@4f2fe7366a33:/usr/local#

7. 虚悬镜像

虚悬镜像:仓库名、标签名都是 <none>的镜像,称为 dangling images(虚悬镜像)。

在构建或者删除镜像时可能由于一些错误导致出现虚悬镜像。

例如:

# 构建时候没有镜像名、tag
docker build .

列出docker中的虚悬镜像:

docker image ls -f dangling=true

“Dangling” 的中文翻译是 “悬挂的” 或 “悬而未决的”

虚悬镜像一般是因为一些错误而出现的,没有存在价值,可以删除:

# 删除所有的虚悬镜像
docker image prune

"Prune" 的中文翻译是 "修剪" 或 "删除"

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

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

相关文章

CVE-2023-30212(xss漏洞)

简介 OURPHP版本<7.2.0存在XSS漏洞&#xff0c;攻击路径为/client/manage/ourphp_out.php。 过程 打开靶场 访问攻击路径/client/manage/ourphp_out.php 得到flag{354c7c41-cc23-4de5-be73-79cbbf384aba}

Hasleo Backup Suite 一款专为Windows操作系统设计的免费数据备份与恢复软件,支持备份、恢复和克隆功能

数据安全是每位计算机用户都关心的重要问题。在日常使用中&#xff0c;我们经常面临文件丢失、系统崩溃或病毒感染等风险。为了解决这些问题&#xff0c;我们需要可靠且高效的数据备份与恢复工具。本文将介绍一款优秀的备份软件&#xff1a;Hasleo Backup Suite&#xff0c;它为…

Python数据分析案例49——基于机器学习的垃圾邮件分类系统构建(朴素贝叶斯,支持向量机)

案例背景 trec06c是非常经典的邮件分类的数据&#xff0c;还是难能可贵的中文数据集。 这个数据集从一堆txt压缩包里面提取出来整理为excel文件还真不容不易&#xff0c;肯定要做一下文本分类。 虽然现在文本分类基本都是深度学习了&#xff0c;但是传统的机器学习也能做。本案…

Python字符串处理常用的30种操作

我们平时编写代码时&#xff0c;经常需要对字符串进行处理&#xff0c;本文详细介绍Python处理字符串常用的30种操作&#xff0c;并给出了对应的代码。 分割 使用split()方法将字符串按照指定的分隔符进行分割。 s "Hello,World" result s.split(","…

解决分布式环境下session共享问题

在分布式环境下&#xff0c;session会存在两个问题 第一个问题:不同域名下&#xff0c;浏览器存储的jsessionid是没有存储的。比如登录时认证服务auth.gulimall.com存储了session&#xff0c;但是搜索服务search.gulimall.com是没有这个session的&#xff1b; 第二个问题&…

hdu物联网硬件实验2 GPIO亮灯

学院 班级 学号 姓名 日期 成绩 实验题目 GPIO亮灯 实验目的 点亮三个灯闪烁频率为一秒 硬件原理 无 关键代码及注释 const int ledPin1 GREEN_LED; // the number of the LED pin const int ledPin2 YELLOW_LED; const int ledPin3 RED…

E4.【C语言】练习:while和getchar的理解

#include <stdio.h> int main() {int ch 0;while ((ch getchar()) ! EOF){if (ch < 0 || ch>9)continue;putchar(ch);}return 0; } 理解上述代码 0-->48 9-->57 if行判断是否为数字&#xff0c;打印数字&#xff0c;不打印非数字

干冰运输与存储中的温度监测:确保药品安全与合规性

在制药行业&#xff0c;干冰对于运输和储存对温度敏感的药品&#xff0c;如原料药API、疫苗、冻干物质和人体组织样本等至关重要。虹科ELPRO LIBERO系列干冰温度记录仪&#xff0c;能够为您提供专业的解决方案&#xff0c;定期监测和记录干冰运输和存储过程中的温度&#xff0c…

字节码编程javassist之定义各种属性

写在前面 源码 。 本文看下如何使用javassist来定义属性。 1&#xff1a;程序 package com.dahuyou.javassist.generateFieldAndMethod;import javassist.*;import java.lang.reflect.Method;public class JustDoIt111 {public static void main(String[] args) throws Exce…

使用京东云主机搭建幻兽帕鲁游戏联机服务器全流程,0基础教程

使用京东云服务器搭建幻兽帕鲁Palworld游戏联机服务器教程&#xff0c;非常简单&#xff0c;京东云推出幻兽帕鲁镜像系统&#xff0c;镜像直接选择幻兽帕鲁镜像即可一键自动部署&#xff0c;不需要手动操作&#xff0c;真正的新手0基础部署幻兽帕鲁&#xff0c;阿腾云整理基于京…

Docker在windows上使用vscode远程连接容器

目录 一、提前准备&#xff1a; 二、vscode连接docker容器 三、构建好的docker容器直接连接vscode 四、Windows下的可视化出linux的ui界面 在日常的开发中&#xff0c;不想windows和linux两个系统之间来回切换&#xff0c;笔者最近打算所有的环境均在一个系统上完成。为了交…

罗剑锋的C++实战笔记学习(二):容器、算法库、多线程

4、容器 1&#xff09;、容器的通用特性 所有容器都具有的一个基本特性&#xff1a;它保存元素采用的是值&#xff08;value&#xff09;语义&#xff0c;也就是说&#xff0c;容器里存储的是元素的拷贝、副本&#xff0c;而不是引用 容器操作元素的很大一块成本就是值的拷贝…

ubuntu系统盘扩容

目录 1 介绍 2 步骤 2.1 关闭虚拟机 2.2 编辑虚拟机设置 2.3 设置扩展大小 2.4 打开虚拟机 2.5 找到磁盘管理 2.6 扩展 1 介绍 本部分主要记述怎么给ubuntu系统盘扩展存储容量&#xff0c;整个过程相对简单&#xff0c;扩容方式轻松、容易。 2 步骤 2.1 关闭虚拟机 2…

【音视频 | RTSP】RTSP协议详解 及 抓包例子解析(详细而不赘述)

&#x1f601;博客主页&#x1f601;&#xff1a;&#x1f680;https://blog.csdn.net/wkd_007&#x1f680; &#x1f911;博客内容&#x1f911;&#xff1a;&#x1f36d;嵌入式开发、Linux、C语言、C、数据结构、音视频&#x1f36d; &#x1f923;本文内容&#x1f923;&a…

【设计模式】工厂模式(定义 | 特点 | Demo入门讲解)

文章目录 定义简单工厂模式案例 | 代码Phone顶层接口设计Meizu品牌类Xiaomi品牌类PhoneFactory工厂类Customer 消费者类 工厂方法模式案例 | 代码PhoneFactory工厂类 Java高级特性---工厂模式与反射的高阶玩法方案&#xff1a;反射工厂模式 总结 其实工厂模式就是用一个代理类帮…

Pytorch(笔记7损失函数类型)

前言 损失函数&#xff08;Loss Function&#xff09;&#xff1a;是定义在单个样本上的&#xff0c;是指一个样本的误差&#xff0c;度量模型一次预测的好坏。 代价函数&#xff08;Cost Function&#xff09;成本函数经验风险&#xff1a;是定义在整个训练集上的&#xff0c…

【vue动态组件】VUE使用component :is 实现在多个组件间来回切换

VUE使用component :is 实现在多个组件间来回切换 component :is 动态父子组件传值 相关代码实现&#xff1a; <component:is"vuecomponent"></component>import componentA from xxx; import componentB from xxx; import componentC from xxx;switch(…

每日一题——Python实现PAT乙级1096 大美数(举一反三+思想解读+逐步优化)3千字好文

一个认为一切根源都是“自己不够强”的INTJ 个人主页&#xff1a;用哲学编程-CSDN博客专栏&#xff1a;每日一题——举一反三Python编程学习Python内置函数 Python-3.12.0文档解读 目录 我的写法 时间复杂度分析 空间复杂度分析 总结 哲学和编程思想 1. 抽象与具体化 …

2024亚太杯中文赛B题洪水灾害的数据分析与预测原创论文分享

大家好&#xff0c;从昨天肝到现在&#xff0c;终于完成了2024年第十四届 APMCM 亚太地区大学生数学建模竞赛B题洪水灾害的数据分析与预测的完整论文啦。 实在精力有限&#xff0c;具体的讲解大家可以去讲解视频&#xff1a; 2024亚太杯中文赛B题洪水灾害预测原创论文保姆级教…

Ad-hoc命令和模块简介

华子目录 Ad-hoc命令和模块简介1.概念2.格式3.Ansible命令常用参数4.模块类型4.1 三种模块类型4.2Ansible核心模块和附加模块 示例1示例2 Ad-hoc命令和模块简介 1.概念 Ansible提供两种方式去完成任务&#xff0c;一是ad-hoc命令&#xff0c;一是写Ansible playbook(剧本)Ad-…