Skip to content

Commit

Permalink
bundler: Add upstream documentation
Browse files Browse the repository at this point in the history
- update main README.md
- add new document for bundler

Signed-off-by: Michal Šoltis <[email protected]>
  • Loading branch information
slimreaper35 committed Oct 8, 2024
1 parent 5c6b472 commit c2173e0
Show file tree
Hide file tree
Showing 2 changed files with 151 additions and 1 deletion.
16 changes: 15 additions & 1 deletion README.md
Original file line number Diff line number Diff line change
Expand Up @@ -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.*
Expand Down Expand Up @@ -223,6 +223,20 @@ prior to pointing cachi2 to your project.

See [docs/yarn.md](docs/yarn.md) for more details.

### bundler

<https://bundler.io/>

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
Expand Down
136 changes: 136 additions & 0 deletions docs/bundler.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,136 @@
# bundler

<https://bundler.io/>

## 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:
<https://bundler.io/v2.5/man/bundle-config.1.html#DESCRIPTION>>

The order of precedence for Bundler configuration options is as follows:

1. Local config (`<project_root>/.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

0 comments on commit c2173e0

Please sign in to comment.