We've already seen the standard way to configure Kuby's Docker component (i.e. the
docker do ... end section), but there's a lot more you can do.
Installing Additional Packages
Kuby officially supports the Debian and Alpine distros of Linux for Docker images.
Let's install imagemagick as an example. First, we'll need to register the imagemagick package with Kuby. It just so happens both the Debian and Alpine Linux distros use the same name for their imagemagick package, meaning we can define using just its name.
Next, we tell Kuby to install imagemagick in the
docker section of our Kuby config:
If the package we want to install has a different name under each of the Linux distros, register it using a hash instead. Let's say we want to install the
dig command-line utility. In Debian, we'd need to install the
dnsutils package, but in Alpine we'd need
Finally, some packages are more complicated to install. In such cases, define a Ruby class that responds to
install_on_alpine, and register it with Kuby.
Custom Build Phases
Kuby builds Docker images in 7 build phases:
- Setup phase: Defines the Docker base image (eg. ruby:2.6.3, ruby:2.6.3-alpine, etc), sets the working directory, and defines the
- Package phase: Installs packages via the operating system's package manager, eg.
yum, etc. Popular packages include things like database drivers (eg. libmysqldev, sqlite3-dev), and image processing libraries (eg. imagemagick, graphicsmagick).
- Bundler phase: Runs
bundle install, which installs all the Ruby dependencies listed in your app's Gemfile.
- Yarn phase: Runs
- Copy phase: Copies your app's source code into the image.
- Assets phase: Compiles assets managed by both the asset pipeline and webpacker.
- Webserver phase: Instructs the Docker image to use a webserver to run your app. Currently only the Rails default, Puma, is supported (including puma in your Gemfile is all you need to do - no other configuration is necessary).
Phases are just Ruby classes that respond to the
apply_to(dockerfile) method. It's possible to define your own custom phases and insert them into the build process. To do so, create a Ruby class and define the appropriate method. Then, insert your new phase. For example, let's define a phase that writes a file into the image that contains the current git commit ID (it can be handy to know which version of your code your image contains). We assume the current git commit is passed as a Docker build argument, since it won't be available to Docker otherwise (in other words, the .git folder won't and shouldn't be copied into the image).
Kuby::Docker::Dockerfile objects respond to the following methods, which are mapped 1:1 to Dockerfile instructions:
from(image_url, as: nil)
copy(source, dest, from: nil)