如何在没有构build工具的情况下为Ruby项目构buildDocker镜像?

我正在尝试为Ruby项目构build一个Docker镜像。 问题是该项目有一些需要build立原生扩展的gem依赖项。 我的理解是,我有几个select:

  1. 从已经安装了构build工具的基础映像开始。
  2. 在没有构build工具的情况下使用基本映像,在运行bundle install之前,将构build工具作为Dockerfile中的一个步骤bundle install
  3. 在主机上预编译本机扩展,供应商gem,并简单地将生成的包复制到图像中。

1和2似乎要求生成的图像包含构build本机扩展所需的构build工具。 我试图避免这种情况出于安全原因。 3是繁琐的,但可行的,并会完成我想要的。

有什么我失踪的select,或者我误解了什么?

我始终使用选项3,目标是以只有我需要运行 (不编译)的图像结束,

例如, 在这里我首先构build并安装Apache ,然后将生成的图像作为我的(修补和重新编译的)Apache设置的基础映像。

build立:

 if [ "$(docker images -q apache.deb 2> /dev/null)" = "" ]; then docker build -t apache.deb -f Dockerfile.build . || exit 1 fi 

Dockerfile.build声明一个包含重新编译的结果的Apache的卷(在deb文件中)

 RUN checkinstall --pkgname=apache2-4 --pkgversion="2.4.10" --backup=no --deldoc=yes --fstrans=no --default RUN mkdir $HOME/deb && mv *.deb $HOME/deb VOLUME /root/deb 

安装:

 if [ "$(docker images -q apache.inst 2> /dev/null)" = "" ]; then docker inspect apache.deb.cont > /dev/null 2>&1 || docker run -d -t --name=apache.deb.cont apache.deb docker inspect apache.inst.cont > /dev/null 2>&1 || docker run -u root -it --name=apache.inst.cont --volumes-from apache.deb.cont --entrypoint "/bin/sh" openldap -c "dpkg -i /root/deb/apache2-4_2.4.10-1_amd64.deb" docker commit apache.inst.cont apache.inst docker rm apache.deb.cont apache.inst.cont fi 

在这里,我使用另一个图像(在我的例子中是“openldap”)安装deb作为基本映像:

 docker run -u root -it --name=apache.inst.cont --volumes-from apache.deb.cont --entrypoint "/bin/sh" openldap -c "dpkg -i /root/deb/apache2-4_2.4.10-1_amd64.deb" docker commit apache.inst.cont apache.inst 

最后,我从我刚刚提交的图像开始,有一个常规的Dockerfile 。

 FROM apache.inst:latest 

psmith在评论中指出,来自Jari Kolehmainen的 Rails应用程序构build最小docker图像 。
对于一个ruby应用程序,您可以轻松地删除构build所需的部分:

 bundle install --without development test && \ apk del build-dependencies 

由于无论如何都需要使用ruby来运行应用程序,所以在这种情况下,这非常有效。

我的情况,我仍然需要一个单独的图像进行构build,因为运行Apache不需要gcc (它非常大,有多个依赖关系,其中一些在运行时需要Apache,有些则不需要)