degica / dockerfiles

Dockerfile collection
1 stars 1 forks source link

Add rails-buildpack #4

Closed k2nr closed 5 years ago

k2nr commented 5 years ago

This image is based on the official ruby:2.4 (and 2.6) image and installs many packages required for rails app CI to run. The idea is to install whatever dependencies we might need to install in the build process. This is basically the rails version of the official buildpack-deps image https://hub.docker.com/_/buildpack-deps/

Why do we need this image

With Travis, (most of) those packages are pre-installed by travis but with GitLab, we need to specify job docker image so we need to have a image that includes all deps otherwise jobs need to install the deps everytime they run.

buildpack image for multi stage build

Another idea for using the buildpack image is docker's multi-stage build feature. Now that our GitLab runner caches docker layers, we can use this buildpack image for building our production rails app image using docker multi-stage build to speedup build time and make the result image size (much) smaller.

k2nr commented 5 years ago

I omitted 2.5 since we don't have a plan to use 2.5

degicat commented 5 years ago

@AlessandroMinali please review this

degicat commented 5 years ago

@olingern please review this

olingern commented 5 years ago

I think multi-stage builds would interesting, but I wonder how much size reduction / build speed it would increase our current build.

Since Rails depends on Node, I think we could build from node alpine and then our rails base later in the Dockerfile. I'm sure there are other things like Node we could follow the same pattern with.

k2nr commented 5 years ago

multi-stage build is not the primary purpose of this PR. this image is mainly for our GitLab CI to work. With my test, our current production image is 1.33GB whereas multi-stage version is 630MB so roughly 50% reduction.

Also, rails runtime doesn't depend on Node. It is only required when build time to build assets.

k2nr commented 5 years ago

@olingern I'm not sure I understand your suggestion. Do you mean this rails-buildpack image can be based from the officieal node alpine image?

olingern commented 5 years ago

@k2nr Right, so we depend on node and per the docs, this is a good use-case for multi stage build https://docs.docker.com/develop/develop-images/multistage-build/

With multi-stage builds, you use multiple FROM statements in your Dockerfile. Each FROM instruction can use a different base, and each of them begins a new stage of the build. You can selectively copy artifacts from one stage to another, leaving behind everything you don’t want in the final image.

Here are two different implementations:

I guess you don't need a "base" node layer as neither of these Rails images do, but I thought it could be interesting to:

  1. Install node
  2. Install node_modules outside of the WORKDIR
  3. Copy node_modules, package.json, yarn.lock into WORKDIR during the Rails build phase as "artifacts"

I haven't used multi-stage builds much, but this was my thinking.

k2nr commented 5 years ago

Thanks for your review!