在一套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中完成编译和运行环境部署
大纲 解释型语言编译环境解释环境编译型语言编译环境运行环境 方法编译环境安装系统安装编译依赖下载代码特殊处理(可以忽略)编译准备(可以忽略)编译打包依赖(编译结果) 运行环境安装操作系统安装运行时依赖…...
ubuntu系统里克隆github代码到本地,提示fatal: unable to connect to github.com的解决方案
打开命令行终端生成一个新的SSH密钥对。如果你还没有SSH密钥或者想创建一个新的,可以使用以下命令: ssh-keygen -t rsa -b 4096 -C "your_emailexample.com"当系统提示你“Enter a file in which to save the key”,时,…...
常见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介绍: (https://cn.ubuntu.com/) (Ubuntu | 全球领先的用于个人电脑、平板及手机的操作系统) Ubuntu是一款基于Debian的开源Linux操作系统,由英国Canonical公司赞助支持的全球性社区共同开发。U…...
练习14 Web [极客大挑战 2019]Upload
phtml格式绕过,burp修改content-type绕过,常见的文件上传存放目录名 题目就叫upload,打开靶机 直接上传一个图片格式的一句话木马,返回如下: 提交练习5和9中的两种可以执行图片格式php代码的文件,修改con…...
3.6k star, 免费开源跨平台的数据库管理工具 dbgate
3.6k star, 免费开源跨平台的数据库管理工具 dbgate 分类 开源分享 项目名: dbgate -- 免费开源跨平台的数据库管理工具 Github 开源地址: GitHub - dbgate/dbgate: Database manager for MySQL, PostgreSQL, SQL Server, MongoDB, SQLite and others. Runs under…...
2024.3.2力扣每日一题——受限条件下可到达节点的数目
2024.3.2 题目来源我的题解方法一 深度优先搜索方法二 并查集 题目来源 力扣每日一题;题序:2368 我的题解 方法一 深度优先搜索 使用深度优先搜索实现,在搜索过程中根据restricted进行截停。 时间复杂度:O(n) 空间复杂度&#…...
在云端遇见雨云:一位服务器寻觅者的指南
引言:寻觅一座云端归宿 当我踏入数字世界的边缘,带着对网络的探索与期待,我迫切需要一座安全可靠的数字栖息地。云计算技术正如一场魔法般的变革,而在这片广袤的云端中,雨云就像是一位友善的向导,引领我穿越…...
Pygame基础10-物理模拟
PyMunk PyMunk是一个模拟物理的库。 注意,PyMunk只是进行物理模拟,不包含可视化的功能。如果需要可视化,可使用pygame等库。 可用pip安装pymunk pip install pymunk pymunk中的概念: space: 物理空间。 包含gravity 模…...
蓝桥杯 --- 日期问题模板
目录 1.如何判断闰年 2.如何遍历当前年份的每一天 3.如果想要输出某一年某一天到某一年某一天之间一共有多少天。 4.精确到具体周几到周几的问题分析 5.如何直接通过一层for循环枚举年月日 习题: 蓝桥杯竞赛特别喜欢考日期问题,今天给大家分享一下…...
Java 处理Mysql获取树形的数据
Mysql数据: 代码如下: Entity: Data Accessors(chain true) public class Region {private BigInteger id;//名称private String name;//父idprivate BigInteger parentId;private List<Region> children;private Integer createTim…...
前端三剑客 —— CSS ( 坐标问题 、定位问题和图片居中 )
前期内容回顾: 1.常见样式 text-shadow x轴 y轴 阴影的模糊程度 阴影的颜色 box-shadow border-radio 实现圆角 margin 内边距 padding 外边距 background 2.特殊样式 媒体查询:media 自定义字体:font-face { font-family:自定义名称&#…...
向量数据库 | AI时代的航道灯塔
向量数据库 | AI时代的航道灯塔 什么是向量检索服务拍照搜商品 你使用过向量数据库吗?使用体验?为什么向量数据库能借由大模型引起众多关注向量数据库在当前AI热潮中是昙花一现,还是未来AI时代的航道灯塔? 今天的话题主要是讨论向…...
Linux中的conntrack命令深入解析
在Linux网络管理和监控领域,conntrack命令是一个强大的工具,它提供了对netfilter连接跟踪系统的直接访问🔍。这篇文章将深入探讨conntrack的由来、底层原理、参数意义,以及其常见用法,并对返回结果的每个字段进行详细解…...
反截屏控制技术如何防止信息通过手机拍照泄漏?
反截屏控制技术为企业数据安全提供了重要的防护措施。通过以下几点,有效阻止了信息通过拍照等方式的泄漏: 反截屏控制开启,用户启动截屏操作时,允许非涉密内容截屏操作,但所有涉密内容窗口会自动隐藏,防止涉…...
0.k8s简介
目录 k8s是什么 k8s不是什么 云原生 微服务 整体式架构与微服务架构 微服务的特性 微服务的优势 k8s是什么 Kubernetes 是一个可移植、可扩展的开源平台,用于管理容器化的工作负载和服务,可促进声明式配置和自动化。 Kubernetes 拥有一个庞大且快…...
VScode 集成终端设置默认打开当前文件夹 mac系统
一.快捷键设置 搜索 openInIntegratedTerminal 如图: 二.设置cmd 默认打开位置 点击设置 搜索 ntegrated:cwd 如下图: 三.查看ip 快捷指令: ipconfig getifaddr en0...
HDLbits 刷题 -- Alwaysblock2
学习: 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(详细步骤) 一、拉取镜像二、启动容器三、修改配置四、修改密码五、浏览器访问 一、拉取镜像 docker安装教程: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 数据: const app {data() {r…...
网络六边形受到攻击
大家读完觉得有帮助记得关注和点赞!!! 抽象 现代智能交通系统 (ITS) 的一个关键要求是能够以安全、可靠和匿名的方式从互联车辆和移动设备收集地理参考数据。Nexagon 协议建立在 IETF 定位器/ID 分离协议 (…...
深入理解JavaScript设计模式之单例模式
目录 什么是单例模式为什么需要单例模式常见应用场景包括 单例模式实现透明单例模式实现不透明单例模式用代理实现单例模式javaScript中的单例模式使用命名空间使用闭包封装私有变量 惰性单例通用的惰性单例 结语 什么是单例模式 单例模式(Singleton Pattern&#…...
Frozen-Flask :将 Flask 应用“冻结”为静态文件
Frozen-Flask 是一个用于将 Flask 应用“冻结”为静态文件的 Python 扩展。它的核心用途是:将一个 Flask Web 应用生成成纯静态 HTML 文件,从而可以部署到静态网站托管服务上,如 GitHub Pages、Netlify 或任何支持静态文件的网站服务器。 &am…...
第一篇:Agent2Agent (A2A) 协议——协作式人工智能的黎明
AI 领域的快速发展正在催生一个新时代,智能代理(agents)不再是孤立的个体,而是能够像一个数字团队一样协作。然而,当前 AI 生态系统的碎片化阻碍了这一愿景的实现,导致了“AI 巴别塔问题”——不同代理之间…...
c#开发AI模型对话
AI模型 前面已经介绍了一般AI模型本地部署,直接调用现成的模型数据。这里主要讲述讲接口集成到我们自己的程序中使用方式。 微软提供了ML.NET来开发和使用AI模型,但是目前国内可能使用不多,至少实践例子很少看见。开发训练模型就不介绍了&am…...
【无标题】路径问题的革命性重构:基于二维拓扑收缩色动力学模型的零点隧穿理论
路径问题的革命性重构:基于二维拓扑收缩色动力学模型的零点隧穿理论 一、传统路径模型的根本缺陷 在经典正方形路径问题中(图1): mermaid graph LR A((A)) --- B((B)) B --- C((C)) C --- D((D)) D --- A A -.- C[无直接路径] B -…...
iview框架主题色的应用
1.下载 less要使用3.0.0以下的版本 npm install less2.7.3 npm install less-loader4.0.52./src/config/theme.js文件 module.exports {yellow: {theme-color: #FDCE04},blue: {theme-color: #547CE7} }在sass中使用theme配置的颜色主题,无需引入,直接可…...
在鸿蒙HarmonyOS 5中使用DevEco Studio实现企业微信功能
1. 开发环境准备 安装DevEco Studio 3.1: 从华为开发者官网下载最新版DevEco Studio安装HarmonyOS 5.0 SDK 项目配置: // module.json5 {"module": {"requestPermissions": [{"name": "ohos.permis…...
MacOS下Homebrew国内镜像加速指南(2025最新国内镜像加速)
macos brew国内镜像加速方法 brew install 加速formula.jws.json下载慢加速 🍺 最新版brew安装慢到怀疑人生?别怕,教你轻松起飞! 最近Homebrew更新至最新版,每次执行 brew 命令时都会自动从官方地址 https://formulae.…...
mac:大模型系列测试
0 MAC 前几天经过学生优惠以及国补17K入手了mac studio,然后这两天亲自测试其模型行运用能力如何,是否支持微调、推理速度等能力。下面进入正文。 1 mac 与 unsloth 按照下面的进行安装以及测试,是可以跑通文章里面的代码。训练速度也是很快的。 注意…...
