方正网站制作,网站建设七个步骤,秦皇岛市海港区建设局网站,网站域名注册免费大纲 解释型语言编译环境解释环境编译型语言编译环境运行环境 方法编译环境安装系统安装编译依赖下载代码特殊处理#xff08;可以忽略#xff09;编译准备#xff08;可以忽略#xff09;编译打包依赖#xff08;编译结果#xff09; 运行环境安装操作系统安装运行时依赖… 大纲 解释型语言编译环境解释环境编译型语言编译环境运行环境 方法编译环境安装系统安装编译依赖下载代码特殊处理可以忽略编译准备可以忽略编译打包依赖编译结果 运行环境安装操作系统安装运行时依赖复制编译结果和依赖暴露端口非必须重整目录运行时命令 打包命令和运行命令 效果参考资料 对于像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 --frombuilder /source/CppServer/bin/cppserver-example-http_server /usr/local/bin/cppserver-example-http_server
COPY --frombuilder /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.patchhttp_server_diff.patch文件如下。它不再判断getline的返回值而根据输入字母来决定是否退出还是重启。
--- http_server.cpp 2024-04-04 13:23:38.519576917 0000http_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 0000unix_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 --frombuilder /source/CppServer/bin/cppserver-example-http_server /usr/local/bin/cppserver-example-http_server
COPY --frombuilder /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》