Docker 【通过Dockerfile构建镜像】【docker容器与镜像的关系】

news2024/11/14 8:30:24

文章目录

  • 前言
  • 一、前期的准备工作
  • 二、上手构建一个简单的镜像
  • 三、DcokerFile
    • 1 指令总览
    • 2 指令详情
  • 四、Dockerfile文件规范
  • 五、docker运行build时发生了什么?
  • 六、调试手段
    • 1. 修改镜像打包后,如何验证新内容已更新至镜像
  • 七、Dockerfile优化方案


前言

docker构建镜像有三种方式 Dockerfile文件名首字母约定要大写。大多数工具(包括Docker CLI和Docker Compose)都会默认查找名为"Dockerfile"的文件来构建镜像。

  • 使用命令行构建
    适合临时构建,一般就是在项目开发初期,环境没有搭建完善,这时候临时需要一个镜像包,可以直接通过命令打给他。
  • 使用Dockerfile文件
    官方推荐这种方式,配置好dockerfile文件之后,docker根据Dockerfile文件构建
  • 使用脚本调用docker 的 api构建
    一般在CI/CD的时候都会使用脚本,调用Docker api配合dockerfile文件实现一键部署,这种方式比较灵活可以配合脚本文件自由实现自己的定制操作,但前期准备工作比较大
  • 容器构建
    通过在容器中执行commit命令构建

一、前期的准备工作

  1. 一台contos操作机器
    cat /etc/os-release # 查看操作系统的版本信息
    
    # out system info
    NAME="OpenCloudOS" # 这个是腾讯的兼容contos8操作系统,可以看作contos8
    VERSION="8.8"
    ID="opencloudos"
    
  2. 安装好docker,这里我的docker版本为
    Docker version 25.0.4, build 1a576c5
    
    如果你还不了解如何安装docker,我的这篇文章可能会对你有帮助

二、上手构建一个简单的镜像

  1. 初始化一个docker项目

    mkdir /demo
    cd /demo
    npm init -y
    

    初始化项目结构

    demo
    |-src
    |  |-index.js
    |-Dockerfile
    |-package.json
    
  2. index.js 内容

    const { createServer } = require("http");
    const server = createServer();
    server.listen(8080, () => {
      console.log("启动成功!");
    });
    
  3. Dockerfile文件内容

    FROM node
    WORKDIR /src
    COPY . .
    RUN npm install --production
    CMD ["node", "src/index.js"]
    
  4. 执行命令打包

    # 进入目录 dockerfile同级目录
    cd /demo
    
    # 执行构建镜像
    docker build -t "cs:1.0.0" . # -t:为镜像打上标签 cs:为镜像名 .:为当前目录
    
  5. 查看打包结果

    docker images
    

    在这里插入图片描述


三、DcokerFile

Dockerfile是本质来讲是一个文本文件,内部包含了一条条指令,能够使docker根据上面的指令定制构建镜像(Image)

1 指令总览

命令列子
FROM指定镜像的依赖
可以有多条。但多个相连的FROM指令只会执行最后一个。详情在#指令详情中说明
RUN指定运行命令 RUN ls ./相当于在镜像构建目录下的shell窗口中执行ls ./ 命令
COPY将本地文件copy到镜像
支持正则表达式拷贝(COPY /local? .)所有匹配local?的文件目录都会拷贝
ADD同COPY一样,但是更强大(支持更多的文件类型的拷贝
如网络文件的下载后拷贝,ADD http://xxxx/test.tar.gz /test/
拷贝归档文件(.tar .gz等)文件会在复制到镜像的过程中自动解压
USER指定Dockerfile后续命令使用哪个用户身份执行,默认root。
WORKDIR目录切换指令,类似shell的cd
ENV指定运行容器时的环境变量
CMD用来指定由镜像创建的容器启动后执行的命令,比如你想让容器启动服务,就可以通过它设置
只能有一条出现多条则最后一条生效
ENTRYPOINT作用CMD类似,但与CMD同时使用时可能会将CMD的值最为参数

2 指令详情

  • FROM
    当遇到FROM指令时,docker会在本地库寻找对应的镜像库
    如果没有发现,则通过docker pull拉取,如果存在则使用本地下载的镜像库
    版本号不一致的镜像是不同的node:16.16.20node:18.18.1 是两个不同镜像

    FROM  node; # 当前镜像依赖node镜像
    

    FROM可以多条使用,但不能连续使用。多条使用一般用于Docker多阶段构建

    # 第一阶段
    FROM node:14 AS build # 使用node:14镜像 设置构建阶段别名提供给COPY --from 访问
    WORKDIR /app
    COPY . .
    RUN npm install
    RUN npm run build # 操作完成产生打包结果文件
    
    # 第二阶段
    FROM node:14-alpine # 使用node:14-alpine镜像此时将会替换掉之前node:14镜像
    WORKDIR /app
    COPY --from=build /app . # 复制 build构建阶段下的/app目录到镜像目录
    CMD ["node", "index.js"]
    

    连续使用,只有最后一条生效

    FROM node:16.16.1
    FROM node:18.18.1 # 此条生效
    

  • RUN
    设置镜像执行命令

    RUN npm i # 相当于在镜像目录的shell窗口中执行npm i
    

  • COPY
    将本地文件活目录拷贝至镜像目录

    • 只能将本地文件拷贝到镜像,不能将镜像文件拷贝到本地
    • 拷贝的源路径只能处在当前构建镜像的上下文的目录下,通过docker build命令的url参数指定构建上下文
    • 语法:COPY [--chown=<user>:<group>] <源路径>... <目标路径>
     COPY /local /app # 将本地/local 下的所有文件、目录拷贝到镜像/app目录下
     COPY /local1 /local2 /app # 可以由多个源路径,它会将本地/local1 和 /local2下的所有文件、目录拷贝到镜像/app下
     COPY /local* /app # 支持通配符,将本地/local1 /local2 /local3 /local...等符合匹配规则的路径复制到镜像/app下
     COPY --chown=user1:group1 /local /app # 本地文件复制到镜像后,将它归属设置为user1用户和group1组
    

  • ADD
    也是用于将本地文件拷贝到镜像中,但是它与COP有些不同

    • 可以COPY远程文件,类似于 自动下载远程文件-》移动至镜像
    • 在拷贝归档文件(.tar等压缩文件)时会在拷贝至镜像的过程中自动解压
    ADD http://www.test.com/test.tar . # 会自动自动解压到镜像文件
    

    请注意!即便ADD命令能够自动解压tar等压缩文件,官方的Dockerfile使用规范仍推荐使用COPY复制压缩文件,配合解压命令解压。这样在语法上更加明确

    // Dockerfile
    COPY test.tar .
    RUN tar -vxf ./test.tar # 执行tar -vxf解压
    

  • USER

    USER [用户名]:[用户组]
    

  • WORKDIR
    修改镜像当前上下文目录,类似linux cd命令。

    WORKDIR ./src # 之后的指令上下文都是./src
    RUN ls ./ 
    

  • CMDENTRYPOINT
    CMD和ENTRYPOINT指令都是用来指定镜像创建的容器启动时执行的指令,相当于在容器启动时开启了一个shell窗口,然后运行CMD和ENTRYPOINT的指令参数。

    它们有相同的语法:

    # CMD <shell 命令> 
    CMD echo 11;// 容器启动执行 echo 11
    ENTRYPOINT echo 11; // 同上
    
    # CMD ["<可执行文件或命令>","<param1>","<param2>",...] 
    
    CMD ["node","-inspect","index.js"] # 相当于shell窗口执行 node -inspect index.js
    ENTRYPONT ["node","-inspect","index.js"] // 同上
    

    如果CMDENTRYPONT同时使用

    1. ENTRYPONT是数组
      CMD ["--inspect","index.js"]
      # or
      CMD echo 11
      
      ENTRYPONT ["node"]
      
      CMD会作为ENTRYPONT的参数,相当于容器启动时执行
      node --inspect index.js
      # or
      node echo 11
      
    2. ENTRYPONT不是数组,ENTRYPONT无法接受参数最终只执行ENTRYPONT
      CMD echo 或者 CMD ["hello"]
      ENTRYPONT echo 
      
      最终容器执行
      echo
      

  • ENV
    定义环境变量,定义之后就可以在后面的任何命令中使用。
    并且连续多次定义ENV的话,它将会叠加而不是覆盖,下面的例子可以访问3个环境变量

    ENV $var1 value1; # 定义单个
    ENV $var2=value2 $var3=$value3 # 定义多个
    
    RUN echo $var1
    COPY $var1 /app
    ADD ./src/$var1 /app
    CMD echo $var1
    WORKDIR $var1
    

    它会在容器内部存在,你可以在代码中访问环境变量

    console.log(process.env.$var1);
    

四、Dockerfile文件规范

  • Dockerfile文件名首字母最好约定大写,因为大多数工具(包括Docker CLI和Docker Compose)都会默认查找名为"Dockerfile"的文件来构建镜像。如果你想指定文件名
    docker build -f myDockerfile -t my-image .
    
  • Dockerfile指令不区分大小写,但是为方便和参数做区分,通常指令使用大写字母。
    from node # 这样也可以
    
    FROM node # 这样更清晰
    
  • Dockerfile中指令按顺序从上至下依次执行。
  • Dockerfile中第一个非注释行必须是FROM指令,用来指定制作当前镜像依据的是哪个基础镜像。
  • Dockerfile中需要调用的文件必须跟Dockerfile文件在同一目录下,或者在其子目录下,父目录或者其它路径无效

五、docker运行build时发生了什么?

当你运行docker build命令构建Docker镜像时,Docker会执行以下步骤:

  • 读取Dockerfile:Docker首先读取Dockerfile,解析其中的指令。

  • 加载构建上下文:Docker将Dockerfile所在的目录(或者你在docker build命令中指定的其他目录)作为构建上下文,将其所有文件和目录发送到Docker守护进程。

  • 执行Dockerfile中的指令:Docker按照Dockerfile中的顺序,一条一条地执行指令。每执行一条指令,Docker都会创建一个新的容器,运行指令,然后提交这个容器为一个新的镜像层。这个过程会重复,直到所有指令都被执行。

  • 对于FROM指令,Docker会加载指定的基础镜像。如果基础镜像不存在,Docker会尝试从Docker Hub或其他配置的镜像仓库下载它。

  • 对于RUN指令,Docker会在当前的镜像上启动一个新的容器,然后在这个容器中运行指令。完成后,Docker会提交这个容器为一个新的镜像层。

  • 对于COPY和ADD指令,Docker会从构建上下文中复制文件或目录到镜像中。完成后,Docker会创建一个新的镜像层。

  • 对于CMD和ENTRYPOINT指令,Docker会设置镜像的默认命令和/或入口点。这些指令不会创建新的镜像层。
    保存最终的镜像:当所有指令都被执行后,Docker会保存最终的镜像。如果你在docker build命令中指定了镜像的标签,Docker会将这个标签应用到最终的镜像。

以上就是docker build命令构建Docker镜像的基本过程。这个过程可能会根据你的Dockerfile和构建上下文的具体内容有所不同。


六、调试手段

1. 修改镜像打包后,如何验证新内容已更新至镜像

通过镜像创建容器

$ docker create --name containerName imageName

进入容器

docker exec -it containerName /bin/bash # 请注意是容器名不是容器id

在容器内部查看对应的目录结构是否存在

ls ./ # 检查更新的相应的目录结构是否存在

七、Dockerfile优化方案

  • Dockerfile中的指令没执行一条就会多构建一个镜像,所以尽量合并执行的执行(run、copy比较多)
    RUN npm i;
    RUN npm run dev;
    # MERGE
    RUN npm i && npm run dev
    

  • 多阶段构建,最后生成的镜像包会比较小
    # 阶段1:构建阶段
    FROM node:14 AS build
    WORKDIR /app
    COPY package*.json ./
    RUN npm install
    COPY . .
    RUN npm run build
    
    # 阶段2:运行阶段
    FROM node:14-alpine
    WORKDIR /app
    COPY --from=build /app/dist ./dist
    COPY package*.json ./
    RUN npm install --only=production
    CMD ["node", "dist/index.js"]
    
    最后的镜像包中只包含node:14-alpone镜像

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

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

相关文章

优化选址问题 | 基于鹈鹕算法求解基站选址问题含Matlab源码

目录 问题代码问题 鹈鹕算法(Pelican Optimization Algorithm, POA)是一种相对较新的启发式优化算法,模拟了鹈鹕鸟觅食的行为。这种算法通常用于解决复杂的优化问题,如函数优化、路径规划、调度问题等。基站选址问题通常是一个复杂的优化问题,需要考虑覆盖范围、干扰、成…

AI修复老照片的一些参数设置

很久没更新CSDN文章了&#xff0c;这次给粉丝带来老照片修复流程 1>用ps修图 图章工具 笔刷 画笔修复 2>高清放大 3>lineattile 重绘 4>上色 具体可参考我的B站视频。 下面是一些笔记。 best quality,masterpiece,photorealistic,8k,ultra high res,solo,ext…

Fabric Measurement

Fabric Measurement 布料测量

通信网络设计[PTA]

文章目录 题目描述思路AC代码 题目描述 输入样例1 6 10 1 2 6 1 5 10 1 6 12 2 4 5 2 6 8 2 3 3 3 4 7 4 5 9 4 6 11 5 6 16 输出样例1 YES! Total cost:31输入样例2 5 4 1 2 3 1 3 11 2 3 8 4 5 9 输出样例2 NO! 1 part:1 2 3 2 part:4 5思路 最小生成树–kruskal算法 具体做法…

RbbitMQ使用教程

RabbitMQ 是一个可靠且成熟的消息传递和流代理&#xff0c;易于部署在云环境、本地和本地计算机上。它目前被全球数百万人使用。通过确认消息传递和跨集群复制消息的功能&#xff0c;您可以使用 RabbitMQ 确保您的消息是安全的。 RabbitMQ安装 推荐使用docker安装部署&#xf…

VMware Workstation Pro 17虚拟机超级详细搭建(含redis,nacos,docker)(一)

今天从零搭建一下虚拟机的环境&#xff0c;把nacos&#xff0c;redis等微服务组件还有数据库搭建到里面&#xff0c;首先看到的是我们最开始下载VMware Workstation Pro 17 之后的样子&#xff0c;总共一起应该有三部分因为篇幅太长了 下载地址 : VMware - Delivering a Digit…

pytest全局配置+前后只固件配置

pytest全局配置前后只固件配置 通过读取pytest.ini配置文件运行通过读取pytest.ini配置文件运行无条件跳过pytest.initest_mashang.pyrun.py 有条件跳过test_mashang.py pytest框架实现的一些前后置&#xff08;固件、夹具&#xff09;处理方法一&#xff08;封装&#xff09;方…

VUE3.0(一):vue3.0简介

Vue 3 入门指南 什么是vue Vue (发音为 /vjuː/&#xff0c;类似 view) 是一款用于构建用户界面的 JavaScript 框架。它基于标准 HTML、CSS 和JavaScript 构建&#xff0c;并提供了一套声明式的、组件化的编程模型&#xff0c;帮助你高效地开发用户界面。无论是简单还是复杂的界…

[ C++ ] STL---仿函数与priority_queue

目录 仿函数 示例一&#xff1a; 示例二 : 常见的仿函数 priority_queue简介 priority_queue的常用接口 priority_queue的模拟实现 基础接口 push() 堆的向上调整算法 堆的插入 pop() 堆的向下调整算法 堆的删除 priority_queue最终实现 仿函数 仿函数&#xff…

数据结构 - 二叉树非递归遍历

文章目录 前言一、前序二、中序三、后序 前言 本文实现二叉树的前中后的非递归遍历&#xff0c;使用栈来模拟递归。 文字有点简略&#xff0c;需要看图和代码理解 树节点&#xff1a; typedef char DATA; //树节点 typedef struct Node {DATA data; //数据struct Node* left…

MySQL进阶-----Linux系统安装MySQL

目录 前言 一、准备工作 1. 准备一台Linux服务器 2. 下载Linux版MySQL安装包 3. 上传MySQL安装包 二、安装操作指令 1. 创建目录,并解压 2.安装mysql的安装包 三、开启mysql与密码修改 1.启动MySQL服务 2. 查询自动生成的root用户密码 3.修改root用户密码 四、创…

【LeetCode】升级打怪之路 Day 26:回溯算法 — 集合划分问题

今日题目&#xff1a; 698. 划分为k个相等的子集 | LeetCode473. 火柴拼正方形 | LeetCode 参考文章&#xff1a; 经典回溯算法&#xff1a;集合划分问题 目录 LC 698. 划分为k个相等的子集 【classic&#xff0c;有难度】数据预处理&#xff1a;计算 target基本回溯优化 1&…

限时免费!Unity 资源商店威尔房间精品资源等你来领!

Unity 资源商店威尔房间精品资源分享 资源介绍资源特色免费领取 Unity 商店资源&#xff1a;Will’s Room Environment, Dormitory Room Environment 免费获取。 资源介绍 好消息来啦&#xff01;Unity 资源商店的威尔房间精品资源正在限时免费中&#xff01;这是一个非常受欢迎…

一维前缀和一维差分(下篇讲解二维前缀和二维差分)(超详细,python版,其他语言也很轻松能看懂)

本篇博客讲解一维前缀和&#xff0c;一维差分&#xff0c;还会给出一维差分的模板题&#xff0c;下篇博客讲解 二维前缀和&二维差分。 一维前缀和&#xff1a; 接触过算法的小伙伴应该都了解前缀和&#xff0c;前缀和在算法中应用很广&#xff0c;不了解也没有关系&#…

【算法】小强爱数学(迭代公式+数论取模)

文章目录 1. 问题2. 输入3. 输出4. 示例5. 分析6. 思路7. 数论&#xff0c;取模相关公式8. 数论&#xff0c;同余定理9. 代码 1. 问题 小强发现当已知 x y B xyB xyB以及 x y A xyA xyA时,能很轻易的算出 x n x_ {n} xn​ y n y_ {n} yn​ 的值.但小强想请你在已知A和B的…

【No.16】蓝桥杯动态规划下|线性DP装箱问题|计数DP0/1背包的方案数|过河卒|完全背包小明的背包2|最长公共子序列|蓝桥骑士|推荐练习题(C++)

线性DP&#xff0c;0/1背包简化版&#xff0c;装箱问题 【题目描述】有一个箱子容量为V(正整数&#xff0c; 0 ≤ V ≤ 20000 0 \le V \le 20000 0≤V≤20000)&#xff0c;同时有n个物品( 0 < n ≤ 30 0 < n \le 30 0<n≤30)&#xff0c;每个物品有一个体积(正整数)。…

ubuntu20.04安裝輸入法

文章目录 前言一、操作過程1、安装fcitx-googlepinyin2、配置language support 前言 參考文獻 一、操作過程 1、安装fcitx-googlepinyin sudo apt-get install fcitx-googlepinyin2、配置language support 第一次點擊進去&#xff0c;會讓你安裝 點擊ctrl和空格切換中英文…

Gin入门指南:从零开始快速掌握Go Web框架Gin

官网:https://gin-gonic.com/ GitHub:https://github.com/gin-gonic 了解 Gin Gin 是一个使用 Go 语言开发的 Web 框架,它非常轻量级且具有高性能。Gin 提供了快速构建 Web 应用程序所需的基本功能和丰富的中间件支持。 以下是 Gin 框架的一些特点和功能: 快速而高效:…

000_coolprop_in_matlab在Matlab中使用CoolProp

在Matlab中使用CoolProp 简介 CoolProp是一个开源的热力学性质库&#xff0c;可以计算多种流体的热力学性质。CoolProp支持多种编程语言&#xff0c;包括Python、C、Matlab等。本文将介绍如何在Matlab中使用CoolProp。 CoolProp官网 本文所使用的Matlab版本为R2021a。 在Ma…

Zabbix与Prometheus区别简述

Zabbix与Prometheus区别简述 历史沿革 一、监控工具简介 1、Zabbix https://www.zabbix.com/cn/download Zabbix是传统的监控系统&#xff0c;出现比云原生早&#xff0c;使用的是SQL关系型数据库&#xff1b;开源监控软件&#xff0c;遵守 GPLv2开源协议&#xff0c;起源于…