I\'m trying to build a Docker image for a Ruby project. The problem is the project has some gem dependencies that need to build native extensions. My understanding is that I
I use option 3 all the time, the goal being to end up with an image which has only what I need to run (not to compile)
For example, here I build and install Apache first, before using the resulting image as a base image for my (patched and recompiled) Apache setup.
Build:
if [ "$(docker images -q apache.deb 2> /dev/null)" = "" ]; then
docker build -t apache.deb -f Dockerfile.build . || exit 1
fi
The Dockerfile.build declares a volume which contains the resulting Apache recompiled (in a deb file)
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
Installation:
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
Here I install the deb using another image (in my case 'openldap') as a base image:
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
Finally I have a regular Dockerfile starting from the image I just committed.
FROM apache.inst:latest
psmith points out in the comments to Building Minimal Docker Image for Rails App from Jari Kolehmainen.
For a ruby application, you can remove the part needed for the build easily with:
bundle install --without development test && \
apk del build-dependencies
Since ruby is needed to run the application anyway, that works great in this case.
I my case, I still need a separate image for building, as gcc
is not needed to run Apache (and it is quite large, comes with multiple dependencies, some of them needed by Apache at runtime, some not...)