The distribution of Ruby applications can be considered an unsolved problem. By itself, Ruby does not provide a consistent and easy method for setting up and running a running application. Distributing Ruby applications to inexperienced end users or end users who are not Ruby programmers is problematic. Users must first install Ruby, use RubyGems, and set up an environment to create their extensions. Even if they already have everything installed, they can still run into problems, for example, due to the wrong version of Ruby. Developers can handle all these issues by providing great documentation that purports to handle cases, but unfortunately, there are an infinite number of ways to break things down.
A straightforward approach is to create installation packages for all target operating systems and environments. While this approach normally works, it has at least two disadvantages:
Legacy tools and techniques
Several tools have been developed to address the challenges described above:
Travelling ruby
Travelling ruby tool provides standalone tar.gz/zip packages for each platform (Linux, MacOS, Windows), which already include a pre-compiled platform-specific Ruby interpreter (provided by the traveling ruby project), as well as all the gems that the application depends on. While traveling ruby provides a much easier way to build distribution packages, it still has significant drawbacks:
- The application developer is not free to use either the version of Ruby of their choice or Gems with native extensions of his/her choice but must rely on the selection and versions supported by traveling ruby.
- Set-up of application packaging still requires a lot of manual work.
OCRA (One-Click Ruby Application)
OCRA (One-Click Ruby Application) is a tool that builds Windows executables from Ruby source code. The executable is a self-extracting executable (package) that contains the Ruby interpreter, application source code, and any additionally needed ruby libraries or components. When the package is started Ruby and application files are extracted to a pristine environment which is used for the execution. OCRA is very similar in spirit to traveling ruby but is free from its drawbacks. It can, at least theoretically, package any version of Ruby and any selection of Gems with native extensions, and the packaging process is fully automated.
However, OCRA has a significant limitation: it is a Windows-only tool, and the underlying technology is not portable (although can be replaced with similar albeit not equal Linux features).
Ruby-packer
Ruby-packer is a tool that is capable to package Ruby applications for Linux, macOS, and Windows platforms. The package created by ruby-packer is a patched, statically linked Ruby interpreter with embedded squashfs filesystem that contains application source code including pre-build native extensions and other gem dependencies. Ruby patches implement a direct squashfs access layer that eliminates the need for fuse drivers or any other support from the operating system.
While ruby-packer supports multiple operating systems and can be ported to any platform that has Ruby, it has its limitation: application developer has to use the version of Ruby bundled with ruby packer.
Development and support status
Ruby packaging technologies were in active development several years ago but all three projects mentioned above (traveling ruby, OCRA, ruby-packer) are not supported anymore.
Consideration regarding container environments
Today it is increasingly popular to distribute applications as self-contained container environments like Docker images. It may explain why the development of customized packaging products was abandoned.
Although container environments provide a unified and standardized approach for application distributions, custom packages may have advantages in some environments:
- Tools like OCRA or ruby-packer will almost certainly produce a smaller distribution than container-based applications. This is because normally containers contain a lot of extra content that isn’t needed by the executables within.
- An executable packager also does not require a container execution environment. Not every user has the capability to run certain container formats. However, nearly every user can run an executable.
- A packaged application is a native binary and doesn’t have to go through any additional execution layers. Contrast this with Docker, which uses HTTP requests to create containers, set up temporary filesystems and networks for the container, etc. Spawning a process in a new Docker container can take hundreds of milliseconds or more. This overhead can be prohibitive for low-latency applications like CLI tools. This overhead does not exist for packaged applications.
Conclusions
While the distribution of Ruby applications is a challenge, there is no product in active development targeting this problem. Several promising technologies have been developed in the past but none of them is currently supported.
The only viable solution is Docker or similar container technology which can be applied to Ruby application but have some disadvantages compared to custom packagers.