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

文章目录

  • 前言
  • 一、前期的准备工作
  • 二、上手构建一个简单的镜像
  • 三、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.mfbz.cn/a/474359.html

如若内容造成侵权/违法违规/事实不符,请联系我们进行投诉反馈qq邮箱809451989@qq.com,一经查实,立即删除!

相关文章

【Spark编程基础】实验三RDD 编程初级实践(附源代码)

目录 一、实验目的二、实验平台三、实验内容1.spark-shell 交互式编程2.编写独立应用程序实现数据去重3.编写独立应用程序实现求平均值问题 一、实验目的 1、熟悉 Spark 的 RDD 基本操作及键值对操作&#xff1b; 2、熟悉使用 RDD 编程解决实际具体问题的方法 二、实验平台 …

burpsuit教程汉化+Repeater(非常详细),从零基础入门到精通,看完这一篇就够了

前言&#xff1a;释疑解惑 《BP使用教程一》发布后&#xff0c;后台收到了许多小伙伴的私信问BP是怎么汉化的&#xff0c;在这里统一为大家解答一下。 BP的汉化依赖于汉化jar包&#xff0c;在启动时引入汉化包即可&#xff0c;废话不多说&#xff0c;直接上命令&#xff1a; …

MySQL:基础篇

一、数据库概述 基本概念 RDBMS&#xff08;关系型数据库&#xff09;和非DBMS对比 RDBMS 实质&#xff1a; 优势&#xff1a; 非DBMS 介绍&#xff1a; 类型&#xff1a; RDBMS设计规则 表、字段、记录 表之间的关联关系 1、一对一 2、一对多 3、多对多 4、自我引用 二、…

Linux网络编程: TCP协议首部与可选项简述

一、TCP/IP五层模型 物理层&#xff08;Physical Layer&#xff09;&#xff1a;物理层是最底层&#xff0c;负责传输比特流&#xff08;bitstream&#xff09;以及物理介质的传输方式。它定义了如何在物理媒介上传输原始的比特流&#xff0c;例如通过电缆、光纤或无线传输等。…

蓝桥杯 第3217题 简单的异或难题 C++ Java Python

题目 思路和解题方法 计算给定数组中子数组异或和的问题。它采用了前缀异或的方法来预处理数组&#xff0c;然后对于每个查询&#xff0c;通过异或操作计算子数组的异或和。 读取输入的数组&#xff0c;并计算每个位置的前缀异或和。对于每个查询&#xff0c;读取查询的左右边界…

有哪些好用的客户管理软件?这5款系统好在哪里?

问题链接&#xff1a;有哪些客户管理比较好的软件&#xff1f; - 知乎 从题主的描述来看&#xff0c;问题主要聚集在客户信息管理、销售流程管理、客户优先级管理这几大方面&#xff0c;再回答这个问题之前&#xff0c;我们要先明确几个问题。比如&#xff0c;客户对企业的重要…

蓝桥杯--错误票据

求解答&#xff0c;不知道出现什么问题(虽然知道自己写的挺麻烦的&#xff0c;但是孩子能写出来就不容易了&#xff09; public class top2 {//错误票据public static void main(String[] args){Scanner scannernew Scanner(System.in);int wscanner.nextInt();String []snew S…

uniapp 开发微信小程序 出现启用组件按需注入问题如何解决

问题描述 在使用uniapp 开发微信小程序&#xff0c;进行上架发布时 代码质量栏 出现启用组件按需注入问题。 虽然现实代码上传成功&#xff0c;但是作为一个吹毛求疵的老猿人&#xff0c;肯定是无法容忍的。那么如何解决呢&#xff1f; 问题解决方案 在uniapp端&#xff0c…

GDB界面调试CGDB快速上手

什么是 CGDB&#xff1f; CGDB 是一个基于 GNU Debugger&#xff08;GDB&#xff09;的 Curses&#xff08;字符用户界面&#xff09;前端。它提供了一个类似于文本编辑器的界面&#xff0c;可以帮助用户更轻松地执行调试操作&#xff0c;而无需离开终端。 安装 CGDB 首先&a…

【鸿蒙HarmonyOS开发笔记】通知模块之发布进度条类型通知

概述 进度条通知也是常见的通知类型&#xff0c;主要应用于文件下载、事务处理进度显示。HarmonyOS提供了进度条模板&#xff0c;发布通知应用设置好进度条模板的属性值&#xff0c;如模板名、模板数据&#xff0c;通过通知子系统发送到通知栏显示。 目前系统模板仅支持进度条…

HarmonyOS定时器与定时任务

HarmonyOS 的 ArkTS 说白了 就是 TS和JS混合 加了一些新特性的语言 定时任务 就还是用 js代码就OK了 我们代码这样写 Entry Component struct Twox {build() {Row() {Column(){Button("触发定时任务").onClick(()>{setTimeout(()> {console.log(执行)},2000…

【毕设级项目】基于ESP8266的家庭灯光与火情智能监测系统——文末源码及PPT

目录 系统介绍 硬件配置 硬件连接图 系统分析与总体设计 系统硬件设计 ESP8266 WIFI开发板 人体红外传感器模块 光敏电阻传感器模块 火焰传感器模块 可燃气体传感器模块 温湿度传感器模块 OLED显示屏模块 系统软件设计 温湿度检测模块 报警模块 OLED显示模块 …

LoRa模块在野外科研与环境保护中的角色:科技守护自然之宝

随着科技的不断发展&#xff0c;LoRa&#xff08;低功耗广域网&#xff09;模块在野外科研与环境保护中正发挥着越来越重要的作用。其卓越的通信能力、低功耗特性以及良好的穿透能力&#xff0c;为科学家和环保人士提供了一种先进的技术手段&#xff0c;有助于更深入、更全面地…

MAC IntelliJ IDEA搭建Doris Fe

目录 版本信息 安装环境依赖 拉取源码 下载 Doris 编译依赖 修改系统最大文件句柄数 编译 Doris 配置 Debug 环境 生成 FE 代码 FE模块代码导入 配置 Debug FE 启动 FE 报错问题 版本信息 本次安装的doris版本信息为doris-2.1.0-rc11 IntelliJ IDEA 配置jdk17、m…

优雅的 Markdown

Markdown浅尝 一、勾选框 注意[]前后都要有空格 - [x] 干的漂亮 - [x] 吃饭 - [x] 写代码 - [ ] 睡觉 干的漂亮 吃饭 写代码 睡觉 二、列表 #无序列列表 * 换成 - 也行 * 你 * 你好 * 你好呀 - 你很好啊 你你好你好呀你很好啊 #有序列表 . 后面有个空格 1. 我 2. 是我 3.…

Spring MVC开发小练习

1. 加法计算器 需求&#xff1a;输入两个整数&#xff0c;计算和 约定前后端交互接口&#xff1a; 在开发项目前&#xff0c;根据需求先约定好前后端交互接口&#xff0c;双方按照接口文档进行开发&#xff0c;接口文档一旦写好&#xff0c;尽量不要轻易改变&#xff0c;如果…

python大学生健身爱好者交流网站flask-django-nodejs-php

任何系统都要遵循系统设计的基本流程&#xff0c;本系统也不例外&#xff0c;同样需要经过市场调研&#xff0c;需求分析&#xff0c;概要设计&#xff0c;详细设计&#xff0c;编码&#xff0c;测试这些步骤&#xff0c;基于python技术、django/flask框架、B/S机构、Mysql数据…

全面:vue.config.js 的完整配置

vue.config.js是Vue项目的配置文件&#xff0c;用于配置项目的构建、打包和开发环境等。 在Vue CLI 3.0之后&#xff0c;项目的配置文件从原来的build和config目录下的多个配置文件&#xff0c;合并成了一个vue.config.js文件。这个文件可以放在项目的根目录下&#xff0c;用于…

借还款管理神器,高效记录借还款信息,让财务明细不再遗漏

在快节奏的现代生活中&#xff0c;借还款管理成为我们日常财务处理的重要一环。无论是个人生活还是企业运营&#xff0c;都需要一个高效、准确、便捷的方式来记录和追踪借还款信息。传统的记账方式往往容易出错、繁琐且耗时&#xff0c;难以满足现代人的需求。现在&#xff0c;…

HarmonyOS应用开发实战 - Api9 拍照、拍视频、选择图片、选择视频、选择文件工具类

鸿蒙开发过程中&#xff0c;经常会进行系统调用&#xff0c;拍照、拍视频、选择图库图片、选择图库视频、选择文件。今天就给大家分享一个工具类。 1.话不多说&#xff0c;先展示样式 2.设计思路 根据官方提供的指南开发工具类&#xff0c;基础的拍照、拍视频、图库选照片、选…