18

When using Rails inside a Docker container several posts, (including one on docker.com) use the following pattern:

  1. In Dockerfile do ADD Gemfile and ADD Gemfile.lock, then RUN bundle install.
  2. Create a new Rails app with docker-compose run web rails new.

Since we RUN bundle install to build the image, it seems appropriate to docker-compose build web after updating the Gemfile.

This works insomuch as the gemset will be updated inside the image, but:

The Gemfile.lock on the Docker host will not be updated to reflect the changes to the Gemfile. This is a problem because:

  1. Gemfile.lock should be in your repository, and:

  2. It should be consistent with your current Gemfile.


So:

How can one update the Gemfile.lock on the host, so it may be checked in to version control?

Community
  • 1
  • 1
davetapley
  • 17,000
  • 12
  • 60
  • 86

4 Answers4

19

Executing the bundle inside run does update the Gemfile.lock on the host:

docker-compose run web bundle

However: You must still also build the image again.

davetapley
  • 17,000
  • 12
  • 60
  • 86
  • 1
    Given this requires two separate commands to be run, I hope there's an alternative answer. – davetapley Jun 28 '16 at 17:31
  • 1
    Yeah, this is the best (only) practical solution I've found as well. I think I'm going to create yet another abstraction by combining `docker-compose build` and `docker-compose run web bundle` in a script file. Hooray abstractions, haha – unforgiven1987 Feb 17 '18 at 21:23
  • This works as long as your Dockerfile follows the format here: https://docs.docker.com/compose/rails/ unlike my Dockerfile, which was using a temp `Gemfile` it had stored in `/tmp` - you can check for this issue by running `bundle env` to see where it's getting the Gemfile from. – mltsy Mar 02 '18 at 21:51
6

Just to be clear, the commands to run are:

docker-compose run web bundle
docker-compose up --build

where web is the name of your Dockerized Rails app.

DaniG2k
  • 4,772
  • 36
  • 77
  • To update the gemfile.lock i.e to update my gems I need to run `docker-compose run --rm web bundle update` and then `docker-compose up --build` – Brent Greeff Mar 03 '20 at 18:27
4

TL;DR - make the changes on the container, run bundle on the container and restart for good measure. Locally these changes will be reflected in your app and are ready to test/push out to git, and your production server will use it to rebuild.

Long; Read:

  1. docker exec -it name_of_app_1 bash

  2. vim Gemfile and put something like gem 'sorcery', '0.9.0' I feel this ensures you get the version you're looking for

  3. bundle to get just this version in the current container's Gemfile and Gemfile.lock

This has been semi normal "Rails" type stuff here, just you are doing it on the container that is running. Now you don't have to worry about git and getting these changes onto. your git repo because these changes are all happening on your local copy. So like, open a terminal tab and go into your app and less Gemfile and you should see the changes.

  1. Now you can restart your running container. Your Dockerfile will get rebuilt (in my case by docker-compose up locally, tests should pass. Browser test at will.

Commit your changes to git and use your deploy process to check it out on staging.

Notes:

Check that Dockerfile like the OP's links say. I'm assuming that you have some kind of bundle or bundle install line in your Dockerfile

pjammer
  • 9,489
  • 5
  • 46
  • 56
1

Run bundle update inside the container, then rebuild.

$ docker-compose run web bundle update
$ docker-compose build
Ken Ratanachai S.
  • 3,307
  • 34
  • 43