docker - 在没有巨大容器大小的 Docker 容器内编译
问题描述
我正在为我的大学创建一个自动测试服务。我需要获取学生代码,将其放入项目目录,然后运行测试。
这需要以可扩展的方式为多种不同的语言完成。
我最初的计划:
- 每种语言都有一个“基础映像”(即在 上安装语言运行时
buildpack-deps:stretch
) - 获取用户文件和预制项目结构
- 将用户文件放入项目中的正确位置
- 构建扩展基础镜像的项目镜像
- 运行容器。它将编译项目并运行测试。
- 将测试结果保存到数据库,停止和删除图像
- 每次提交都重复冲洗
手动测试时,图像尺寸很大!将近1.5GB的大小!我正在为一种语言安装运行时,并且我正在使用 Hello World 进行测试 - 所以项目也不大。
这“有效”,但感觉非常低效。我对 Docker 也很陌生——有没有更好的方法来做到这一点?
干杯
解决方案
在这个特定的应用程序中,我可能会在容器内编译程序,而不是从中构建映像(因为您会立即将其丢弃,而编译和测试是重要的部分,而且通常情况下,您不会之后的任何事情都需要构建的程序)。
如果您假设输入文件以某种方式进入容器,那么您可以编写一个执行构建和测试的脚本:
#!/bin/sh
cd /project/src/student
tar xzf "/app/$1"
cd ../..
make
...
curl ??? # send the test results somewhere
然后你的 Dockerfile 只是将它构建成一个图像,其中没有任何特定的学生代码
FROM buildpack-deps:stretch
RUN apt-get update && apt-get install ...
RUN adduser user
COPY build_and_test.sh /usr/local/bin
USER user
ADD project-structure.tar.gz /project
然后当你真正去运行它时,你可以使用docker run -v
选项来注入提交的代码。
docker run --rm -v $HOME/submissions:/app theimage \
build_and_test.sh student_name.tar.gz
在您的原始解决方案中,请注意最大的东西可能是语言运行时、C 工具链和相关的头文件,因此当您获得一个明显巨大的图像时,所有这些东西都来自基础图像中的层,因此在各个构建之间共享(它占用的空间并不像您想象的那么多)。
推荐阅读
- json - 登录后如何从 Django 返回 Json 中的 User()?
- java - GWT 应用程序在 Windows 上运行,而不是在具有相同配置的 Linux 上运行
- flutter - Flutter 如何识别 Flutter android 应用程序已安装并在 BlueStacks windows 应用程序 - PC 中使用?
- windows - git commit 在 Windows 10 上对包含空格字符的目录名称失败
- tensorflow-federated - 调用函数 tff.learning.build_federated_averaging_process 时的学习率设置
- javascript - 如何在 iframe 中使用 clearInterval 来停止父 html 的 setInterval 的滴答声
- r - Apollo R:apollo_estimate 中的错误(apollo_beta,apollo_fixed,apollo_probabilities,:未进行估计
- javascript - 我如何开玩笑地模拟对构造函数的调用
- symfony - 在 Laravel/Lumen 中找不到类“Symfony\Component\EventDispatcher\Event”
- python - 你可以在 python 的子包中隐藏导入的模块吗?