docker 构建应用

docker 应用程序开发手册

开发 docker 镜像

Dockerfile

  • 非常容易定义镜像内容
  • 由一系列指令和参数构成的脚本文件
  • 每一条指令构建一层
  • 一个 Dockerfile 文件包含了构建镜像的一套完整指令
  • 指令不区分大小写,但是一般建议都是大写
  • 从头到尾按顺序执行指令
  • 必须以 FROM 指令开头,其实也是允许这个之前定义变量
  • # 是注释,但是要以这个开头的才是。行中其他位置被视为参数的一部分
  • 可以自定义转义字符:escape=

构建镜像的基本方法

通过:docker build

原理:通过 Dockerfile 文件和构建上下文(build context)构建镜像

构建上下文

上下文是由文件路径或者一个 URL 定义的一组文件

构建上下文以递归方式处理,本地路径包括其中的任何子目录,URL 包括仓库及其子模块

示例

使用当前目录作为上下文的构建语句:docker build -t 镜像标识 .

在这里插入图片描述

镜像构建过程

  • 整个构建过程是由 docker 守护进程运行的
  • 构建过程从上到下递归发给守护进程执行
  • 最好是一个项目一个目录进行构建,以这个目录作为上下文

在这里插入图片描述

Dockerfile 常用指令

这边以centos的镜像作为构建基础

FROM

设置基础镜像

FROM <image> [AS name]
  • image 参数指定任何有效的镜像,多种写法,也可以从公有注册中心拉取
  • 可以多次出现,以创建多个镜像层
  • 设置别名,对构建阶段指定一个名称,这个名称后续的 FROM 和 COPY --from=<name|index> 指令引用此阶段构建的镜像
  • 也支持由 ARG 指令申明的变量,但是这个变量要在第一条 FROM 指令前,在 FROM 指令前,就意味这个这个变量没有进入构建阶段

示例

在这里插入图片描述

RUN

运行命令

RUN <command>
RUN ["exec","param1","param2"]
  • shell 格式,命令在 shell 环境中运行,默认是 /bin/sh -c
  • exec 格式,不会启用 shell 环境执行
  • 可以使用反斜杠将单个 RUN 指令延续到下一行

示例

RUN ["/bin/bash", "-c", "echo hello,world"]

在这里插入图片描述

在这里插入图片描述

CMD

指定容器启动时默认执行的命令

  • 一个文件只能由一个 CMD 指令,就算有多个 CMD 指令,只有最后一个 CMD 有效
CMD ["exec","param1","param2"]	## 首选
CMD ["param1","param2"]		## 提供给 ENTRYPOINT 指令的默认参数
CMD command param1 param2	## shell 格式

示例

在这里插入图片描述

LABEL

向镜像添加元数据信息

  • 其中如果有空格,要加引号和反斜杠
  • 可以有多个标记,多个标记合并到单个标记可以减少层数
LABEL kye=value kye=value kye=value...

示例

在这里插入图片描述

在这里插入图片描述

EXPOSE

声明容器运行时监听的端口

  • 可以指定TCP或者UDP,默认是TCP
  • 它不会发布真实的端口,只是声明一下,
EXPOSE <port>

在这里插入图片描述

ENV

指定环境变量

  • 键值对形式
  • 构建镜像阶段的所有后续指令的环境中,也可以被运行时指定的环境变量替换
  • 引号和反斜杠可以作为值中包含空格
ENV key value  ### 单个环境变量
ENV key=value key=value key=value  ### 多个环境变量

示例

ARG version=7
FROM centos:$version
LABEL name=whale mail=565616251@qq.com info="then is a test"
COPY index.html /home/html/
EXPOSE 80/tcp 8088/udp
ENV var1=hello var2=world var3="hello world"
RUN ["/bin/bash","-c","echo ${var1}"]
RUN ["/bin/bash","-c","echo hello,world"]
CMD ["/bin/bash","-c","echo ${var1},${var2}"]

在这里插入图片描述

在这里插入图片描述

COPY

将源文件复制到容器内

  • 一些通配符:*代表任何内容,?代表单个字符
  • 源路径必须位于构建的上下文
  • 如果源是目录,则复制整个目录的内容
  • 指定多个源的话,目的路径必须是目录,必须以 / 结尾
  • 如果目的路径不以/ 结尾,被视为常规文件,源内容将写入目录路径
  • 如果目的路径不存在,则会与其路径中所有缺少的目录一起创建
COPY [--chown=<user>:<group>] <src>...<dest>  #### chown只用于linux容器
COPY [--chown=<user>:<group>] ["<src>",..."<dest>"]  #### 路径如果有空格字符,要用这种形式

示例

ARG version=7
FROM centos:$version
LABEL name=whale mail=565616251@qq.com info="then is a test"
COPY ind* /home/html/
EXPOSE 80/tcp 8088/udp
ENV var1=hello var2=world
CMD ["/bin/bash","-c","cat /home/html/index.html"]

在这里插入图片描述

ADD

将源文件复制到容器

ADD [--chown=<user>:<group>] <src>...<dest>  #### chown只用于linux容器
ADD [--chown=<user>:<group>] ["<src>",..."<dest>"]  #### 路径如果有空格字符,要用这种形式
  • 源可以使用 URL 指定
  • 归档文件在复制过程中能够被自动解压缩,URL 的资源除外
ENTRYPOINT

配置容器的默认入口

ENTRYPOINT ["exec","param1","param2"]		#### 首选exec格式
ENTRYPOINT command  param1 param2			#### shell 格式
VOLUME

创建挂载点

VOLUME ["/data"]
  • 创建具有指定名称的挂载点,并将其标记为从本机主机或其他容器保留外部挂载的卷

示例

ARG version=7
FROM centos:$version
LABEL name=whale mail=565616251@qq.com info="then is a test"
COPY index.html /home/html/
EXPOSE 80/tcp 8088/udp
ENV var1=hello var2=world
VOLUME ["/home/html/"]
CMD ["/bin/bash","-c","cat /home/html/index.html"]

在这里插入图片描述

在这里插入图片描述

在这里插入图片描述

WORKDIR

配置工作目录

WORKDIR /path/xxx/xxxx
  • 该指令后的 RUN 、CMD、COPY、ADD、ENTRYPOINT 指令设置工作目录,如果目录不存在,就会被创建
  • 可以多次使用这个指令,当时最终的路径是基于先前 WORKDIR 指令的路径

示例

ARG version=7
FROM centos:$version
LABEL name=whale mail=565616251@qq.com info="then is a test"
WORKDIR /
RUN pwd
COPY index.html /home/html/
EXPOSE 80/tcp 8088/udp
ENV var1=hello var2=world
VOLUME ["/home/html/"]
WORKDIR /home/html
CMD ["/bin/bash","-c","cat index.html"]

在这里插入图片描述

USER

设置运行镜像时使用的用户名

USER <user>:<group>
  • RUN、CMD、ENTRYPOINT 指令都会使用这个指定的身份
  • 如果没有设置, root 组身份运行

示例

ARG version=7
FROM centos:$version
LABEL name=whale mail=565616251@qq.com info="then is a test"
RUN useradd whale
USER whale:whale
COPY index.html /home/html/
EXPOSE 80/tcp 8088/udp
ENV var1=hello var2=world
VOLUME ["/home/html/"]
WORKDIR /home/html
CMD ["/bin/bash","-c","id"]

在这里插入图片描述

ARG

定义构建时候的变量

ARG <name>[=<value>]
  • 构建时候也可以使用命令进行传递:–build-arg =,但是如果这个参数没有在文件中定义,就会报错
SHELL

指定命令的 shell 格式

SHELL ["exec","parameters"]
  • 用于指定命令的shell格式来覆盖默认的 shell,Linux 系统默认的shell是 /bin/sh -c 的形式,windows 是 cmd /S /C
  • 可以多次出现,但是会被覆盖
exec、shell 格式方法

RUN、CMD、ENTRYPOINT

这些指令都会用到 exec 和 shell 两种格式

#### exec的一般写法:直接调用命令,不会被shell进行解析,也识别不了ENV指令的环境变量,除非是 shell 执行的
<指令> ["exec", "param1", "param2" ,......]
ENTRYPOINT ["/bin/echo", "Hello,World"]

#### shell 的一般写法:底层直接调用的是/bin/sh -c 来执行的
<指令> <command>
  • CMD、ENTRYPOINT 首先 exec 格式,可读性强,容易理解
  • RUN 两种都可以
RUN、CMD、ENTRYPOINT 区别
  • RUN 指令执行命令并创建新的镜像层,经常用来安装应用程序和依赖包
  • CMD 指令为运行容器提供默认值,默认执行的命令及其参数,如果容器启动时候手动指定,CMD 指令就会被覆盖,如果省略了可执行文件,就必须指定 ENTRYPOINT 指令,CMD 指令可为提供额外的默认参数
  • ENTRYPOINT 指令配置容器启动时运行的命令,CMD 指令提供额外参数,并且 ENTRYPOINT 在容器启动一定会运行,不会被覆盖的
ARG version=7
FROM centos:$version
LABEL name=whale mail=565616251@qq.com info="then is a test"
ENTRYPOINT  ["/bin/echo", "hello"]
CMD [" world"]

在这里插入图片描述

构建镜像的基本步骤

  1. 准备构建 Dockerfile 上下文
  2. 编写 Dockerfile
  3. 执行构建命令
  4. 基于构建镜像启动进行测试

注意点

  1. 构建缓存问题
  2. 创建基础镜像(可以通过 scratch 构建最简单的父镜像)

多阶段构建

docker 17.05以上才支持

不用多阶段构建的解决方案

  1. 传统解决方案使用 shell 技巧和其他逻辑尽可能减少层的大小
  2. 还有一些先创建一个容器,然后运行,在复制出来需要的文件,再构建一次,需要shell脚本的配合来完成构建,麻烦地

使用多阶段构建

  1. 就是一个 Dockerfile 中有多个 FROM 指令,每个指令使用不同的基础镜像,并且各自分别开始一个新的构建阶段
  2. 可以选择将构建从一个阶段复制到另一个阶段,并在最终镜像中排除不需要的内容
#### 
ARG version=7
FROM centos:$version 
LABEL name=whale mail=565616251@qq.com info="then is a test"
COPY index.html /home/html/

FROM centos:6
COPY --from=0 /home/html/index.html /home/			### 从前一阶段复制到新的阶段
CMD ["/bin/bash","-c","cat /home/index.html"]

在这里插入图片描述

为每个构建阶段命名

这里使用c语言环境进行构建演示

FROM gcc:latest as builder
WORKDIR /app
COPY myapp.c /vim app
RUN gcc -o myapp myapp.c

FROM centos:7
WORKDIR /
COPY --from=builder /app/myapp .
CMD ["./myapp"]

在这里插入图片描述

Dockerfile 编写建议

  1. 创造短生命周期的容器:容器以无状态运行,可以被停止和销毁,可以使用最小的设置和配置进行重建和替换
  2. 可以使用标准输入管道化来构建(就不用保存 Dockerfile 文件了)
  3. 它的特殊参数 - 就是用来从标准输入读取 Dockerfile 内容的,直到遇到EOF/分界符
  4. 使用.dockerignore文件排除与构建无关的文件,类似于git那种,构建上下文发送给守护进程前,就会排除掉这些文件
  5. 使用多阶段构建
  6. 不安装不必要的包
  7. 解耦应用程序:一个容器只解决一个问题
  8. 使镜像层数最少
  9. 对多行参数排序
  10. 利用构建缓存
echo -e "FROM xxx \nRUN xxxx" | docker build -

在这里插入图片描述

在这里插入图片描述

Docker 的应用程序开发准则

减少镜像大小

  1. 选择合适的基础镜像:比如需要 JDK,考虑官方的 openjdk,而不是从通用的 ubuntu 镜像去构建JDK环境
  2. 多阶段构建:jave应用使用maven,使用多阶段构建,最终镜像就可以不用包含构建时需要引入的所有库和依赖
  3. 创建自己的基础镜像
  4. 生产镜像作为基础镜像
  5. 不依赖自动产生的 latest 标签

持久化应用程序数据

  1. 避免应用程序数据存储在容器的可写成,会降低IO和增加容器的大小
  2. 尽可能使用卷来存储数据
  3. 生产环境,使用 secrets 存储服务需要的敏感程序数据,使用配置数据 configs 存储配置文件

尽可能使用 swarm 集群服务

  • 即使单节点,swarm 带来的收益也比 docker run 要优秀

应用程序 Docker 化

基本流程

选择基础镜像

几乎所有开发技术都有自己的基础镜像,比如:java、python、node.js等,如果不直接使用这些镜像,就需要从基础操作系统镜像开始安装所有的依赖,最常见的就是 ubuntu 操作系统作为基础镜像

安装必要的软件

如果有必要,需要针对构建、调试和开发环境创建不同的 Dockerfile

添加自定义文件

定义容器运行时的用户权限

尽可能避免使用 root 权限运行

定义要对外暴露的端口

定义应用程序的入口点

entrypoint,比较简单的就是直接运行可执行文件,更专业的方法创建一个专门的shell脚本:entrypoint.sh,通过环境变量配置容器的入口点

定义一种配置方式

应用程序如果需要参数,可以使用应用程序特定的配置文件,也可以使用操作系统的环境变量

持久化应用数据

这些数据最好存储到卷或者绑定挂载上,不要将他们保存到容器本身的可写层

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

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

相关文章

大型语言模型 (LLM)全解读

一、大型语言模型&#xff08;Large Language Model&#xff09;定义 大型语言模型 是一种深度学习算法&#xff0c;可以执行各种自然语言处理 (NLP) 任务。 大型语言模型底层使用多个转换器模型&#xff0c; 底层转换器是一组神经网络。 大型语言模型是使用海量数据集进行训练…

P1042 [NOIP2003 普及组] 乒乓球 Java版最简单题解!

为什么说最简单&#xff0c;因为本人就是一个算法小白&#xff0c;只学过一点数据结构&#xff0c;打算备战蓝桥杯的&#xff0c;网上说备战蓝桥杯就去刷洛谷&#xff0c;早有听闻洛谷很难&#xff0c;今天一看算是真的被打醒了&#xff0c;对于小白是真的太难了。(;༎ຶД༎ຶ…

uni-app 微信小程序之红包雨活动

文章目录 1. 页面效果2. 页面样式代码 1. 页面效果 GIF录屏有点卡&#xff0c;实际比较丝滑 每0.5s掉落一个红包控制4s后自动移除红包点击红包消除红包&#xff08;或者自行1&#xff0c;或者弹窗需求&#xff09; 2. 页面样式代码 <!-- 红包雨活动 --> <template>…

拦截器的简单使用

拦截器的简单使用 拦截器的使用创建拦截器preHandle 目标方法执行前执行postHandle 目标方法执行后执行afterCompletion 视图渲染后执行 拦截器使用场景返回值注册拦截器运用拦截器 拦截器的使用 创建拦截器 首先,我们需要创建一个拦截器器的类,并且需要继承自HandlerIntercep…

Linux系统优化要义

这里不敢说 linux优化奥义&#xff0c;主要是本文比较浅显&#xff0c;适合普通开发相关人员去读 linux作为服务器系统的王者&#xff0c;以稳定性著称&#xff0c;但对于不同的“应用场景”&#xff0c;相关配置还需调整&#xff0c;才能保证业务稳定性。以下是相关总结 IO优…

快快销ShopMatrix 分销商城多端uniapp可编译5端-代理商收益管理:差价奖励和销售额统计

代理商收益管理是一种针对代理商的利润分配模式&#xff0c;主要通过差价奖励和销售额统计来实现。这种模式的核心思想是通过激励代理商的销售行为&#xff0c;提高代理商的积极性和销售效率&#xff0c;从而实现整个销售网络的增长。 差价奖励是代理商收益管理中的一种常见方…

兄弟DCP-7057黑白激光多功能一体机加粉后清零方法

硒鼓加粉机器上清零&#xff0c;方法如下&#xff1a; 打开安装硒鼓的前盖。按“清除”键&#xff0c;显示“更换硒鼓”。不用管提示&#xff0c;接着按“启用Start”&#xff0c;再按“”&#xff0c;屏幕上显示“01”。继续按“”&#xff0c;直到屏幕上显示“11”。按“OK”…

E5071C 是德科技网络分析仪

181/2461/8938产品概述&#xff1a; E5071C ENA 矢量网络分析仪&#xff0c;9 kHz 至 20 GHz&#xff0c;配有增强型 TDR 测量选件。 E5071C 是大规模无源元器件测试的理想解决方案。 它具有出色的测量性能&#xff0c;有助于提高测试吞吐量&#xff0c;尤其是与 E5092A 多端…

Discuz论坛搭建:Linux宝塔面板一键部署,固定地址畅享公网访问

&#x1f308;个人主页&#xff1a;聆风吟 &#x1f525;系列专栏&#xff1a;网络奇遇记、Cpolar杂谈 &#x1f516;少年有梦不应止于心动&#xff0c;更要付诸行动。 文章目录 &#x1f4cb;前言一. 安装基础环境二. 一键部署Discuz三. 安装cpolar工具四. 配置域名访问Discuz…

【小白教程】幻兽帕鲁服务器一键搭建 | 支持更新 | 自定义配置

幻兽帕鲁刚上线就百万在线人数&#xff0c;官方服务器的又经常不稳定&#xff0c;所以这里给大家带来最快捷的搭建教程&#xff0c;废话不多说直接开始。 步骤一&#xff1a;准备服务器 服务器建议 Linux 系统&#xff0c;资源占用低&#xff0c;而且一键脚本只需要一条命令&am…

架构篇27:如何设计计算高可用架构?

文章目录 主备主从集群小结计算高可用的主要设计目标是:当出现部分硬件损坏时,计算任务能够继续正常运行。因此计算高可用的本质是通过冗余来规避部分故障的风险,单台服务器是无论如何都达不到这个目标的。所以计算高可用的设计思想很简单:通过增加更多服务器来达到计算高可…

AI大模型开发架构设计(5)——人人能学会的Llama-2大模型微调

文章目录 人人能学会的Llama-2大模型微调1 什么是Llama-2以及关键特性分析什么是Llama-2?Llama-2关键特性分析2 Llama-2微调全流程剖析为什么要微调Llama-2?Llama-2微调全流程3 基于Llama-2微调3个应用案例案例1:电子游戏评价数据生成文本数据集合案例2:利用Llama-2微调模型…

Android如何通过按钮实现页面跳转方法

Hello大家好&#xff01;我是咕噜铁蛋&#xff01;在Android应用开发中&#xff0c;页面跳转是一项基本且常见的功能。通过按钮实现页面跳转可以为用户提供更好的交互体验&#xff0c;使应用更加灵活和易用。本文将介绍Android Studio中如何通过按钮实现页面跳转的方法&#xf…

OJ_日期问题

基础&#xff1a;已知某天的日期求下一天的日期 #define _CRT_SECURE_NO_WARNINGS #include<stdio.h> #include<string.h> using namespace std;void NextDay(int &year, int &month, int &day) {//存储一下 月份和天数的对应关系int dayOfMonth[] {…

Linux:命名管道及其实现原理

文章目录 命名管道指令级命名管道代码级命名管道 本篇要引入的内容是命名管道 命名管道 前面的总结中已经搞定了匿名管道&#xff0c;但是匿名管道有一个很严重的问题&#xff0c;它只允许具有血缘关系的进程进行通信&#xff0c;那如果是两个不相关的进程进行通信&#xff0…

C# Graphics对象学习

Graphics对象用于进行绘制&#xff1b; 从哪个对象获取的Graphics&#xff0c;然后进行绘制&#xff0c;就绘制到该对象上&#xff1b; 从位图获取Graphics&#xff0c;然后进行绘制&#xff0c;绘制到该位图上&#xff1b; 从某个控件获取Graphics&#xff0c;然后绘制&…

el-tree基础的树形节点设置节点不能选中高亮出来,对已经选中的节点设置disabled,对当前节点刚选中后设置禁用disabled

一、 el-tree基础的树形节点设置节点不能选中高亮出来 需求 我们使用element-ui或者element-plus的时候会遇到树形控件的使用&#xff0c;我们使用树形控件会限制有的节点不让选中和高亮出来&#xff0c;这个时候需要我们做限制。在实现中我们发现了element-ui和element-plus…

基于C语言的趣味游戏之五子棋

目录 趣味五子棋游戏 第一步 text.c文件 第二步 game.h文件 第三步 初始化 打印棋盘 玩家输入 电脑输入 判断输赢 game.c 趣味五子棋游戏 第一步 先写菜单&#xff0c;然后在主函数里调用&#xff0c;由于这是一个可以重复的游戏所以将do while循环里调用menu函数。…

《WebKit技术内幕》学习之十五(2):Web前端的未来

2 嵌入式应用模式 2.1 嵌入式模式 读者可能会奇怪本章重点表达的是Web应用和Web运行平台&#xff0c;为什么会介绍嵌入式模式&#xff08;Embedded Mode&#xff09;呢&#xff1f;这是因为很多Web运行平台是基于嵌入式模式的接口开发出来的&#xff0c;所以这里先解释一下什…

keepalived+nginx双主热备(有问题私信)

keepalivednginx双主热备 前言keepalivednginx双主热备keepalivednginx双主热备部署安装nginx安装keepalived修改master节点的keepalived配置文件 修改backup节点的keeepalived配置文件配置keepalived主备配置keepalived双主热备 前言 有关keepalived和nginx的一些工作原理&am…