我正在尝试为Ruby项目构建Docker镜像。问题是项目有一些需要构建本机扩展的gem依赖项。我的理解是我有几个选择:
bundle install
之前,将构建工具安装为Dockerfile中的一个步骤。1& 2似乎要求生成的图像包含构建本机扩展所需的构建工具。出于安全原因,我试图避免这种情况。 3很麻烦,但可行,并且可以实现我想要的目标。
我有什么选择吗?或者我误解了什么?
答案 0 :(得分:2)
我一直使用选项3,目标是最终得到的图像只有我需要运行(不编译)
例如,here I build and install Apache first,然后将生成的图像用作我的(修补和重新编译)Apache设置的基本映像。
构建
if [ "$(docker images -q apache.deb 2> /dev/null)" = "" ]; then
docker build -t apache.deb -f Dockerfile.build . || exit 1
fi
Dockerfile.build声明一个卷,其中包含重新编译的结果(在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
最后,我从我刚提交的图片开始有一个regular Dockerfile。
FROM apache.inst:latest
psmith从Building Minimal Docker Image for Rails App对Jari Kolehmainen的评论中指出 对于ruby应用程序,您可以使用以下命令轻松删除构建所需的部件:
bundle install --without development test && \
apk del build-dependencies
由于运行应用程序需要ruby,因此在这种情况下效果很好。
我的情况,我仍然需要一个单独的图像来构建,因为运行Apache不需要gcc
(并且它非常大,带有多个依赖项,其中一些是Apache在运行时需要的,一些不...)