-
Notifications
You must be signed in to change notification settings - Fork 18
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Add bundler cache feature #48
Conversation
Hi @patriciomacadden Thanks for the PR! This is actually a feature I have had in mind as well and played with a bit but didn't come up with an implementation I liked, and I have been meaning to come back to it. At first glance this looks good. I want to do some testing with it on my end but I probably won't have time to get to that until sometime next week. I will get back to you once I have had time to take a closer look =) |
hey @andrewn617 awesome. Let me know if you think we can improve it! |
"description": "Creates a volume for persisting the installed gems across different containers", | ||
"containerEnv": { | ||
"BUNDLE_PATH": "/bundle/vendor" | ||
}, |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
perhaps also add this?
}, | |
}, | |
"installsAfter": [ | |
"ghcr.io/rails/devcontainer/features/ruby" | |
], |
I'm not sure if it makes sense though
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I don't think it's necessary. The ruby feature should not install any gems.
"name": "Bundler cache", | ||
"description": "Creates a volume for persisting the installed gems across different containers", | ||
"containerEnv": { | ||
"BUNDLE_PATH": "/bundle/vendor" |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I noticed that once you're in the container, if you run rails c
(or any other executable in your Gemfile) you'll get a "command not found" error.
to solve this, we can add these env vars:
"BUNDLE_PATH": "/bundle/vendor" | |
"BUNDLE_PATH": "/bundle/vendor", | |
"BUNDLE_BIN": "/bundle/bin", | |
"PATH": "/bundle/bin:$PATH" |
BUNDLE_BIN
tells bundler to install the bins in the specified dir, and then we'll prepend this dir in the PATH
.
By default, the BUNDLE_BIN
would be something like /bundle/vendor/ruby/COMPATIBILITY_VERSION/bin
. And compatibility version is not always the same ruby version you're running (for example i'm testing with 3.3.4 and the compat version is 3.3.0 - This is not trivial to get, so changing the BUNDLE_BIN
makes sense..
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I don't think we should add the bundle bin to the path like that. Instead people should do bundle exec rails c
or bin/rails c
. I expect global gems to be in the path but not bundled gems.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
@patriciomacadden Sorry it took me a bit of time to get to testing this. This looks good and is working for me. Thank you for the contribution =)
hey @andrewn617, don't worry about it. Thanks for merging! Looking forward to contribute a bit more! |
…lled Ruby dependencies. Cache the installed Ruby dependencies into a docker volume, making the `devcontainer up` and `docker compose up` process faster. Before: ```bash == Installing dependencies == https://github.com/rails/rails.git (at main@99a6365) is not yet checked out. Run `bundle install` first. Bundler 2.5.11 is running, but your lockfile was generated with 2.5.17. Installing Bundler 2.5.17 and restarting using that version. Fetching gem metadata from https://rubygems.org/. Fetching bundler 2.5.17 Installing bundler 2.5.17 Fetching https://github.com/rails/rails.git Fetching gem metadata from https://rubygems.org/.......... Fetching rake 13.2.1 ``` After: ```bash == Installing dependencies == The Gemfile's dependencies are satisfied ``` See also feature rails/devcontainer#48, which will not work with `docker compose`.
…lled Ruby dependencies. Cache the installed Ruby dependencies into a docker volume, making the `devcontainer up` and `docker compose up` process faster. Before: ```bash == Installing dependencies == https://github.com/rails/rails.git (at main@99a6365) is not yet checked out. Run `bundle install` first. Bundler 2.5.11 is running, but your lockfile was generated with 2.5.17. Installing Bundler 2.5.17 and restarting using that version. Fetching gem metadata from https://rubygems.org/. Fetching bundler 2.5.17 Installing bundler 2.5.17 Fetching https://github.com/rails/rails.git Fetching gem metadata from https://rubygems.org/.......... Fetching rake 13.2.1 ``` After: ```bash == Installing dependencies == The Gemfile's dependencies are satisfied ``` See also feature rails/devcontainer#48, which will not work with `docker compose`.
Hello!
I've been using docker and docker compose for years to run my rails apps in development. The way I used docker + docker compose was to run a single process and remove the container after it's done (eg
docker compose run --rm ...
, or justdocker compose up
and them removing the container, etc). And when you're adding gems, trying things out, etc. it's super useful to have a volume for the installed gems so you can rundocker compose run web bundle
and have the new gems available rather than having to rebuild the image over and over.Devcontainers approach, ie developing inside of the container, is really interesting but there's something that slows down the whole thing of bringing the container up and that is to install gems every time (if you remove containers after a period of time obviously, if you don't you're fine).
This feature could've been in its own repo but I thought this is a good place to be as people like me might find useful.
This feature just creates a volume that gets mounted in
/bundle
and adds theBUNDLE_PATH
env var to/vendor/bundle
. This way you might remove the container and when you bring it up again it will use the gems you already have installed, making the whole process faster. The reason why there's a postCreateCommand is that the mounted volume needs to be owned by the vscode user, as the devcontainer doesn't run as root. I couldn't find a different way editing the compose.yaml or devcontainer.json. Apologies if there's another way!