当前位置: 首页 > news >正文

在一套Dockerfile中完成编译和运行环境部署

大纲

  • 解释型语言
  • 编译环境
  • 解释环境
  • 编译型语言
    • 编译环境
    • 运行环境
  • 方法
    • 编译环境
      • 安装系统
      • 安装编译依赖
      • 下载代码
      • 特殊处理(可以忽略)
      • 编译准备(可以忽略)
      • 编译
      • 打包依赖(编译结果)
    • 运行环境
      • 安装操作系统
      • 安装运行时依赖
      • 复制编译结果和依赖
      • 暴露端口(非必须)
      • 重整目录
      • 运行时命令
    • 打包命令和运行命令
  • 效果
  • 参考资料

对于像C、C++这类编译型语言,编译器会直接将代码编译成二进制,然后在操作系统上执行。而像Java这类解释型语言,编译器(Java编译器是Java写的)会将代码编译成中间码,然后在虚拟机上执行,而虚拟机(Java虚拟机是C++写的,最后编译成二进制码)是在操作系统上执行的。
在这里插入图片描述
不管是编译型语言还是解释型语言,我们都可以把上述过程拆解为两部分

解释型语言

编译环境

在这里插入图片描述

解释环境

在这里插入图片描述
只是去除了Java代码和编译器,并不会让Docker产出的镜像小多少。

编译型语言

编译环境

在这里插入图片描述

运行环境

在这里插入图片描述
C、C++这类语言编译时期往往需要大量的资源,比如本文案例中,编译环境的镜像是2个多G,而运行环境这是1百多M,减少了93%的大小。

方法

我们可以在一套Dockerfile中,将编译环境的产出放置到运行环境,并且抛弃编译环境,只留下运行环境的镜像。

FROM ubuntu:22.04 as builder
RUN apt-get update && apt-get install -y binutils-dev uuid-dev libssl-dev python3 python3-pip cmake git zip
RUN pip3 install gil
RUN mkdir source
WORKDIR /source
RUN git clone https://github.com/chronoxor/CppServer.git
WORKDIR /source/CppServer/examples
COPY http_server_diff.patch ./http_server_diff.patch
RUN patch -p0 < http_server_diff.patch
WORKDIR /source/CppServer
RUN gil update
WORKDIR /source/CppServer/build
COPY unix_diff.patch ./unix_diff.patch
RUN patch -p0 < unix_diff.patch
RUN ./unix.sh
WORKDIR /source/CppServer
RUN zip -r www.zip www/FROM ubuntu:22.04 as runner
RUN apt-get update && apt-get install -y libbinutils unzip
COPY --from=builder /source/CppServer/bin/cppserver-example-http_server /usr/local/bin/cppserver-example-http_server
COPY --from=builder /source/CppServer/www.zip /usr/local/bin/www.zip
EXPOSE 8080
WORKDIR /cppserver
RUN unzip /usr/local/bin/www.zip -d /cppserver
RUN apt remove -y unzip
RUN rm /usr/local/bin/www.zip
WORKDIR /cppserver/bin
RUN mv /usr/local/bin/cppserver-example-http_server ./cppserver-example-http_server
CMD ["cppserver-example-http_server"]

这段Dockerfile分为两部分

编译环境

安装系统

首先选择ubuntu 22作为基础系统。我们要保证运行环境和编译环境的操作系统版本是一致的。
as builder是标识我们要将其当做编译环境使用。在运行环境的Dockerfile中我们需要借此标识引用编译环境,来导出二进制编译结果等在运行环境中需要数据。

FROM ubuntu:22.04 as builder

安装编译依赖

安装好系统后,我们更新系统中包装管理软件(apt),以及安装编译代码时需要用的软件以及依赖(这一步,不同软件会需要不同的依赖)。

RUN apt-get update && apt-get install -y binutils-dev uuid-dev libssl-dev python3 python3-pip cmake git zip
RUN pip3 install gil

下载代码

准备好基础环境后,就可以下载代码了

RUN mkdir source
WORKDIR /source
RUN git clone https://github.com/chronoxor/CppServer.git

特殊处理(可以忽略)

因为我们使用的开源库,在设计上不太符合我们要求,导致一运行就会退出。于是我们对源码打了Patch。这块知识可以参考《代码打补丁的利器——diff和patch》

WORKDIR /source/CppServer/examples
COPY http_server_diff.patch ./http_server_diff.patch
RUN patch -p0 < http_server_diff.patch

http_server_diff.patch文件如下。它不再判断getline的返回值,而根据输入字母来决定是否退出还是重启。

--- http_server.cpp     2024-04-04 13:23:38.519576917 +0000
+++ http_server_bak.cpp 2024-04-04 13:52:57.483416162 +0000
@@ -221,17 +221,18 @@ int main(int argc, char** argv)server->Start();std::cout << "Done!" << std::endl;-    std::cout << "Press Enter to stop the server or '!' to restart the server..." << std::endl;
+    std::cout << "Press 'q' to stop the server or 'r' to restart the server..." << std::endl;// Perform text inputstd::string line;
-    while (getline(std::cin, line))
+    while (true){
-        if (line.empty())
+       getline(std::cin, line);
+        if (line == "q")break;// Restart the server
-        if (line == "!")
+        if (line == "r"){std::cout << "Server restarting...";server->Restart();

这一段具有特异性,算是针对该项目的一个补丁。一般项目不太需要这个步骤。

编译准备(可以忽略)

这一步是该编译项目需要做的前置动作,不具有普遍性。

WORKDIR /source/CppServer
RUN gil update
WORKDIR /source/CppServer/build
COPY unix_diff.patch ./unix_diff.patch
RUN patch -p0 < unix_diff.patch

因为上一步我们修改了代码,导致这个开源项目的原始自动化测试不通过。上述补丁我们就是将自动化测试从流程中去除。
unix_diff.patch文件如下。

--- unix.sh     2024-04-04 14:01:10.668521739 +0000
+++ unix_bak.sh 2024-04-04 14:06:59.667047513 +0000
@@ -3,7 +3,6 @@ set -ecd Unix./01-generate.sh./02-build.sh
-./03-tests.sh./04-install.shif [[ "$doxygen" ]]; then./05-doxygen.sh

编译

每个软件的编译指令不同。下面的指令只针对我们例子中的工程。

RUN ./unix.sh

打包依赖(编译结果)

因为我们这个工程是http服务器,它会用到www目录下的一些网页文件,所以我们需要用zip指令对它们进行打包,以方便后续统一搬运到运行环境。

WORKDIR /source/CppServer
RUN zip -r www.zip www/

运行环境

运行环境的命令和编译环境的命令是在一个Dockerfile中的。

安装操作系统

我们使用和编译环境一样的操作系统以及版本。

FROM ubuntu:22.04 as runner

安装运行时依赖

这一步我们安装的依赖就减少很多,主要是libbinutils 。它主要提供一些动态链接库,这些都是在运行时软件需要加载的公共库。
安装unzip是为了解压之前压缩的文件,后续我们会卸载它。

RUN apt-get update && apt-get install -y libbinutils unzip

复制编译结果和依赖

这一步我们将编译环境的编译结果cppserver-example-http_server拷贝到运行时环境,同时拷贝它依赖的一些文件。

COPY --from=builder /source/CppServer/bin/cppserver-example-http_server /usr/local/bin/cppserver-example-http_server
COPY --from=builder /source/CppServer/www.zip /usr/local/bin/www.zip

暴露端口(非必须)

cppserver-example-http_server 需要运行在8080端口上。

EXPOSE 8080

重整目录

这一步,我们会将之前复制过来的文件按照软件的要求重新部署目录结构。
另外我们卸载了为了搬运方便而安装的unzip软件。

WORKDIR /cppserver
RUN unzip /usr/local/bin/www.zip -d /cppserver
RUN apt remove -y unzip
RUN rm /usr/local/bin/www.zip
WORKDIR /cppserver/bin
RUN mv /usr/local/bin/cppserver-example-http_server cppserver-example-http_server

运行时命令

CMD ["./cppserver-example-http_server"]

打包命令和运行命令

docker build --pull --rm -f "Dockerfile" -t cppserver:latest "." 
docker container run -d -p 8080:8080 --name cppserver cppserver:latest cppserver-example-http_server

效果

在这里插入图片描述
我们删除了运行时Dockerfile,生成的镜像cppserver-builder,然后对比下它和运行时镜像的大小。
在这里插入图片描述

参考资料

  • 《代码打补丁的利器——diff和patch》

相关文章:

在一套Dockerfile中完成编译和运行环境部署

大纲 解释型语言编译环境解释环境编译型语言编译环境运行环境 方法编译环境安装系统安装编译依赖下载代码特殊处理&#xff08;可以忽略&#xff09;编译准备&#xff08;可以忽略&#xff09;编译打包依赖&#xff08;编译结果&#xff09; 运行环境安装操作系统安装运行时依赖…...

ubuntu系统里克隆github代码到本地,提示fatal: unable to connect to github.com的解决方案

打开命令行终端生成一个新的SSH密钥对。如果你还没有SSH密钥或者想创建一个新的&#xff0c;可以使用以下命令&#xff1a; ssh-keygen -t rsa -b 4096 -C "your_emailexample.com"当系统提示你“Enter a file in which to save the key”&#xff0c;时&#xff0c;…...

常见docker使用命令

#搭建镜像 “”" sudo docker build -t es_refresh:V1.20230303 . “”" #启动容器 “”" docker run -d --namepara_classify -v /etc/localtime:/etc/localtime -v /data/chenhw/multi_label_classification:/edb2vec -p 8066:8066 --gpus ‘“device0”’…...

Ubuntu系统中设置中文输入法的教程

1、Ubuntu介绍&#xff1a; &#xff08;https://cn.ubuntu.com/&#xff09; &#xff08;Ubuntu | 全球领先的用于个人电脑、平板及手机的操作系统&#xff09; Ubuntu是一款基于Debian的开源Linux操作系统&#xff0c;由英国Canonical公司赞助支持的全球性社区共同开发。U…...

练习14 Web [极客大挑战 2019]Upload

phtml格式绕过&#xff0c;burp修改content-type绕过&#xff0c;常见的文件上传存放目录名 题目就叫upload&#xff0c;打开靶机 直接上传一个图片格式的一句话木马&#xff0c;返回如下&#xff1a; 提交练习5和9中的两种可以执行图片格式php代码的文件&#xff0c;修改con…...

3.6k star, 免费开源跨平台的数据库管理工具 dbgate

3.6k star, 免费开源跨平台的数据库管理工具 dbgate 分类 开源分享 项目名: dbgate -- 免费开源跨平台的数据库管理工具 Github 开源地址&#xff1a; GitHub - dbgate/dbgate: Database manager for MySQL, PostgreSQL, SQL Server, MongoDB, SQLite and others. Runs under…...

2024.3.2力扣每日一题——受限条件下可到达节点的数目

2024.3.2 题目来源我的题解方法一 深度优先搜索方法二 并查集 题目来源 力扣每日一题&#xff1b;题序&#xff1a;2368 我的题解 方法一 深度优先搜索 使用深度优先搜索实现&#xff0c;在搜索过程中根据restricted进行截停。 时间复杂度&#xff1a;O(n) 空间复杂度&#…...

在云端遇见雨云:一位服务器寻觅者的指南

引言&#xff1a;寻觅一座云端归宿 当我踏入数字世界的边缘&#xff0c;带着对网络的探索与期待&#xff0c;我迫切需要一座安全可靠的数字栖息地。云计算技术正如一场魔法般的变革&#xff0c;而在这片广袤的云端中&#xff0c;雨云就像是一位友善的向导&#xff0c;引领我穿越…...

Pygame基础10-物理模拟

PyMunk PyMunk是一个模拟物理的库。 注意&#xff0c;PyMunk只是进行物理模拟&#xff0c;不包含可视化的功能。如果需要可视化&#xff0c;可使用pygame等库。 可用pip安装pymunk pip install pymunk pymunk中的概念&#xff1a; space&#xff1a; 物理空间。 包含gravity 模…...

蓝桥杯 --- 日期问题模板

目录 1.如何判断闰年 2.如何遍历当前年份的每一天 3.如果想要输出某一年某一天到某一年某一天之间一共有多少天。 4.精确到具体周几到周几的问题分析 5.如何直接通过一层for循环枚举年月日 习题&#xff1a; 蓝桥杯竞赛特别喜欢考日期问题&#xff0c;今天给大家分享一下…...

Java 处理Mysql获取树形的数据

Mysql数据&#xff1a; 代码如下&#xff1a; Entity&#xff1a; Data Accessors(chain true) public class Region {private BigInteger id;//名称private String name;//父idprivate BigInteger parentId;private List<Region> children;private Integer createTim…...

前端三剑客 —— CSS ( 坐标问题 、定位问题和图片居中 )

前期内容回顾&#xff1a; 1.常见样式 text-shadow x轴 y轴 阴影的模糊程度 阴影的颜色 box-shadow border-radio 实现圆角 margin 内边距 padding 外边距 background 2.特殊样式 媒体查询&#xff1a;media 自定义字体&#xff1a;font-face { font-family:自定义名称&#…...

向量数据库 | AI时代的航道灯塔

向量数据库 | AI时代的航道灯塔 什么是向量检索服务拍照搜商品 你使用过向量数据库吗&#xff1f;使用体验&#xff1f;为什么向量数据库能借由大模型引起众多关注向量数据库在当前AI热潮中是昙花一现&#xff0c;还是未来AI时代的航道灯塔&#xff1f; 今天的话题主要是讨论向…...

Linux中的conntrack命令深入解析

在Linux网络管理和监控领域&#xff0c;conntrack命令是一个强大的工具&#xff0c;它提供了对netfilter连接跟踪系统的直接访问&#x1f50d;。这篇文章将深入探讨conntrack的由来、底层原理、参数意义&#xff0c;以及其常见用法&#xff0c;并对返回结果的每个字段进行详细解…...

反截屏控制技术如何防止信息通过手机拍照泄漏?

反截屏控制技术为企业数据安全提供了重要的防护措施。通过以下几点&#xff0c;有效阻止了信息通过拍照等方式的泄漏&#xff1a; 反截屏控制开启&#xff0c;用户启动截屏操作时&#xff0c;允许非涉密内容截屏操作&#xff0c;但所有涉密内容窗口会自动隐藏&#xff0c;防止涉…...

0.k8s简介

目录 k8s是什么 k8s不是什么 云原生 微服务 整体式架构与微服务架构 微服务的特性 微服务的优势 k8s是什么 Kubernetes 是一个可移植、可扩展的开源平台&#xff0c;用于管理容器化的工作负载和服务&#xff0c;可促进声明式配置和自动化。 Kubernetes 拥有一个庞大且快…...

VScode 集成终端设置默认打开当前文件夹 mac系统

一.快捷键设置 搜索 openInIntegratedTerminal 如图&#xff1a; 二.设置cmd 默认打开位置 点击设置 搜索 ntegrated:cwd 如下图&#xff1a; 三.查看ip 快捷指令&#xff1a; ipconfig getifaddr en0...

HDLbits 刷题 -- Alwaysblock2

学习&#xff1a; For hardware synthesis, there are two types of always blocks that are relevant: Combinational: always (*)Clocked: always (posedge clk) Clocked always blocks create a blob of combinational logic just like combinational always blocks, but…...

一、Docker部署GitLab(详细步骤)

Docker部署GitLab&#xff08;详细步骤&#xff09; 一、拉取镜像二、启动容器三、修改配置四、修改密码五、浏览器访问 一、拉取镜像 docker安装教程&#xff1a;https://qingsi.blog.csdn.net/article/details/131270071 docker pull gitlab/gitlab-ce:latest二、启动容器 …...

Vue3 Ajax(axios)

Vue 版本推荐使用 axios 来完成 ajax 请求。 安装方法 使用 cdn: <script src"https://unpkg.com/axios/dist/axios.min.js"></script> 使用 npm: $ npm install axios GET 方法 我们可以简单的读取 JSON 数据&#xff1a; const app {data() {r…...

ICEM高效建模技巧:从快捷键到多点创建模式

1. ICEM快捷键&#xff1a;让你的建模效率翻倍 刚开始用ICEM建模那会儿&#xff0c;我总被繁琐的鼠标操作折磨得够呛。直到有天发现隔壁工位的同事建模速度比我快三倍&#xff0c;偷师学艺才知道——原来快捷键才是真正的生产力神器。这里分享几个我每天必用的核心快捷键组合&a…...

AI智能体应用工程师:少数人掌握的高薪未来,你离入场还有多远

AI智能体应用工程师 — 国家战略人才项目|企业刚需资质—国务院发布关于实施“人工智能”行动。文中指出:到2027年&#xff0c;率先实现人工智能与6大重点领域广泛深度融合&#xff0c;新一代智能体终端、智能体等应用普及率超过70%。 各地省政府于2025年市级“A1产业”专项基金…...

Kafka Connect集群管理可视化界面:高效实现多环境连接器配置实战指南

Kafka Connect集群管理可视化界面&#xff1a;高效实现多环境连接器配置实战指南 【免费下载链接】kafka-connect-ui Web tool for Kafka Connect | 项目地址: https://gitcode.com/gh_mirrors/ka/kafka-connect-ui 在Kafka生态系统中&#xff0c;连接器管理一直是数据…...

2025年具身智能创业指南:从芯片选型到场景落地的完整避坑手册

2025年具身智能创业指南&#xff1a;从芯片选型到场景落地的完整避坑手册 当波士顿动力的Atlas机器人完成一套流畅的后空翻动作时&#xff0c;全世界都意识到——具身智能的时代已经到来。2025年的今天&#xff0c;具身智能正从实验室走向产业化&#xff0c;创业者们面临的不再…...

为什么Stable Diffusion选择VQ-GAN?深入解析LDM背后的图像压缩技术

为什么Stable Diffusion选择VQ-GAN&#xff1f;深入解析LDM背后的图像压缩技术 在生成式AI领域&#xff0c;Stable Diffusion凭借其出色的图像生成质量和开源特性迅速成为行业标杆。但很少有人注意到&#xff0c;这个强大模型的核心竞争力之一&#xff0c;其实隐藏在它的第一阶…...

JavaScript快速入门:10个基础概念让你轻松掌握编程核心

JavaScript快速入门&#xff1a;10个基础概念让你轻松掌握编程核心 【免费下载链接】You-Dont-Know-JS &#x1f4d7;&#x1f4d2; (PT-Br translation) JS Book Series. 项目地址: https://gitcode.com/gh_mirrors/you/You-Dont-Know-JS JavaScript作为现代Web开发的基…...

AudioSeal小白入门:无需代码,用90年代复古界面快速加密你的音频

AudioSeal小白入门&#xff1a;无需代码&#xff0c;用90年代复古界面快速加密你的音频 1. 什么是AudioSeal&#xff1f; AudioSeal是Meta公司开发的一款前沿音频水印技术&#xff0c;它能在不影响音质的前提下&#xff0c;将数字签名"隐形"嵌入到音频文件中。想象…...

工业Python网关配置不是写代码,是做工程!揭秘ISO/IEC 62443合规配置清单(仅限首批200家制造企业内部流出)

第一章&#xff1a;工业Python网关配置不是写代码&#xff0c;是做工程&#xff01;在工业现场&#xff0c;Python网关绝非“跑个脚本就能连PLC”的玩具级工具——它是一套融合协议适配、资源约束、故障自愈与长期稳定运行的系统工程。配置的本质&#xff0c;是定义设备生命周期…...

SegFormer源码解读:从注意力机制到特征融合的实现细节

SegFormer源码解读&#xff1a;从注意力机制到特征融合的实现细节 【免费下载链接】SegFormer Official PyTorch implementation of SegFormer 项目地址: https://gitcode.com/gh_mirrors/se/SegFormer SegFormer是一个基于Transformer的语义分割模型&#xff0c;它通过…...

TNTSearch 实战案例:构建电商产品搜索系统的完整流程

TNTSearch 实战案例&#xff1a;构建电商产品搜索系统的完整流程 【免费下载链接】tntsearch A fully featured full text search engine written in PHP 项目地址: https://gitcode.com/gh_mirrors/tn/tntsearch TNTSearch 是一个功能强大的 PHP 全文搜索引擎&#xff…...