From c2173e038bd6d39fb03a02dbe3ea1855db85ab4e Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Michal=20=C5=A0oltis?= Date: Tue, 1 Oct 2024 11:08:48 +0200 Subject: [PATCH] bundler: Add upstream documentation MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit - update main README.md - add new document for bundler Signed-off-by: Michal Ĺ oltis --- README.md | 16 +++++- docs/bundler.md | 136 ++++++++++++++++++++++++++++++++++++++++++++++++ 2 files changed, 151 insertions(+), 1 deletion(-) create mode 100644 docs/bundler.md diff --git a/README.md b/README.md index bd3597c9e..bb8226cd9 100644 --- a/README.md +++ b/README.md @@ -135,12 +135,12 @@ Supported: * [pip](#pip) * [npm](#npm) * [yarn](#yarn) +* [bundler](#bundler) Planned: * dnf * cargo -* bundler *Based on the [supported package managers](https://github.com/containerbuildsystem/cachito#package-managers) in the original Cachito.* @@ -223,6 +223,20 @@ prior to pointing cachi2 to your project. See [docs/yarn.md](docs/yarn.md) for more details. +### bundler + + + +Cachi2 supports bundler by parsing [Gemfile.lock](https://bundler.io/guides/using_bundler_in_applications.html#gemfilelock) +file present in the source repository and downloading the declared dependencies. + +To generate a lockfile or to make sure the file is up to date, you can use +for example the `bundle lock` command, which will generate `Gemfile.lock` file based +on the dependencies specified in the [Gemfile](https://bundler.io/v2.5/man/gemfile.5.html). +Both files must be present in the source repository so you should check them into your git repository. + +See [docs/bundler.md](docs/bundler.md) for more details. + ## Project status Cachi2 was derived (but is not a direct fork) from [Cachito](https://github.com/containerbuildsystem/cachito) and is diff --git a/docs/bundler.md b/docs/bundler.md new file mode 100644 index 000000000..7788093db --- /dev/null +++ b/docs/bundler.md @@ -0,0 +1,136 @@ +# bundler + + + +## Prerequisites + +To use Cachi2 with Bundler locally, ensure you have Ruby and Bundler installed +on your system. + +```bash +sudo dnf install rubygem-bundler +``` + +Or use the official Ruby image for example from Docker Hub: + +```bash +podman run --rm -it docker.io/library/ruby:latest bash +``` + +Then ensure you have both, **Gemfile** and **Gemfile.lock** in your project +directory. Anything outside of the **Gemfile.lock** will be ignored. We parse +the **Gemfile.lock** to pre-fetch all dependencies specified in that file. +Please note, that we don't use any Bundler commands to pre-fetch dependencies. +Instead, we use native mechanisms from the Ruby standard library to parse +the **Gemfile.lock** and download the dependencies to the specified output +directory. + +## Usage + +Run the following command in your terminal to pre-fetch your project's +dependencies. The command will download all dependencies specified in the +**Gemfile.lock** to the specified output directory. + +```bash +cachi2 fetch-deps --source ./path-to-your-ruby-project --output ./cachi2-output bundler +``` + +In addition, it will prepare necessary environment variables and configuration +files for the build phase. See the following section for more information. + +### Configuration + +Bundler uses an unorthodox system when dealing with configuration options. +The highest precedence is given to the config file, and then to the environment +variables. See the official documentation: +> + +The order of precedence for Bundler configuration options is as follows: + +1. Local config (`/.bundle/config or $BUNDLE_APP_CONFIG/config`) +2. Environment variables (ENV) +3. Global config (`~/.bundle/config`) +4. Bundler default config + +Since the local configuration takes higher precedence than the environment +variables (except `BUNDLE_APP_CONFIG`), we need to set a few Bundler +configuration options to make the build work by copying the configuration file +and setting the environment variables below. Then, we change the +`BUNDLE_APP_CONFIG` environment variable to point to the copied/updated +configuration file. + +This is an unfortunate limitation of Bundler, and we hope that Bundler will +change this behavior in the future. It may be a problem if you have multiple +packages in your repository with different settings. In that case, you may have +to adjust the build phase accordingly. + +**BUNDLE_CACHE_PATH**: The directory that Bundler will place cached gems +inwhen running `bundle package`, and that Bundler will look in when installing +gems. Defaults to `vendor/cache`. + +**BUNDLE_DEPLOYMENT**: Disallow changes to the **Gemfile**. When the +**Gemfile** is changed and the lockfile has not been updated, running Bundler +commands will be blocked. + +**BUNDLE_NO_PRUNE**: Whether Bundler should leave outdated gems unpruned when caching. + +To create the configuration file, run the following command. + +```bash +cachi2 inject-files --for-output-dir /tmp/cachi2-output cachi2-output +``` + +You should see a log message that the file was created successfully. +Lastly, you need to set the `BUNDLE_APP_CONFIG` environment variable to point +to the copied configuration file. + +```bash +cachi2 generate-env --output ./cachi2.env --for-output-dir /tmp/cachi2-output ./cachi2-output +``` + +```bash +# cat cachi2.env +export BUNDLE_APP_CONFIG=/tmp/cachi2-output/bundler/config_override +``` + +The generated environment file should be sourced before running any Bundler command. + +### Hermetic build + +After using the `fetch-deps`, `inject-files`, and `generate-env` commands +to set up the directory, building the Dockerfile will produce a container with +the application fully compiled without any network access. The build will be +hermetic and reproducible. + +```Dockerfile +FROM docker.io/library/ruby:latest + +WORKDIR /app + +COPY Gemfile . +COPY Gemfile.lock . + +COPY . . + +RUN . /tmp/cachi2.env && bundle install + +... +``` + +Assuming `cachi2-output` and `cachi2.env` are in the same directory as the +Dockerfile, build the image with the following command: + +```bash +podman build . \ + --volume "$(realpath ./cachi2-output)":/tmp/cachi2-output:Z \ + --volume "$(realpath ./cachi2.env)":/tmp/cachi2.env:Z \ + --network none \ + --tag my-ruby-app +``` + +## Unsupported features + +- checksum validation (blocked by pending official support) +- downloading the Bundler version specified in the **Gemfile.lock** +- reporting development dependencies +- plugins