What is the difference between Gemfile and Gemfile.lock in Ruby on Rails
The Gemfile
is where you specify which gems you want to use, and lets you specify which versions.
The Gemfile.lock
file is where Bundler records the exact versions that were installed. This way, when the same library/project is loaded on another machine, running bundle install
will look at the Gemfile.lock
and install the exact same versions, rather than just using the Gemfile
and installing the most recent versions. (Running different versions on different machines could lead to broken tests, etc.) You shouldn't ever have to directly edit the lock file.
Check out Bundler's Purpose and Rationale, specifically the Checking Your Code into Version Control section.
The Gemfile.lock
When you run bundle install, Bundler will persist the full names and versions of all gems that you used (including dependencies of the gems specified in the Gemfile(5)) into a file called Gemfile.lock.
Bundler uses this file in all subsequent calls to bundle install, which guarantees that you always use the same exact code, even as your application moves across machines.
Because of the way dependency resolution works, even a seemingly small change (for instance, an update to a point-release of a dependency of a gem in your Gemfile(5)) can result in radically different gems being needed to satisfy all dependencies.
As a result, you SHOULD check your Gemfile.lock into version control. If you do not, every machine that checks out your repository (including your production server) will resolve all dependencies again, which will result in different versions of third-party code being used if any of the gems in the Gemfile(5) or any of their dependencies have been updated.
Usually we write dependencies in Gemfile as:
gem "nokogiri", "~> 1.4.4"
gem 'bcrypt-ruby', '~> 3.0.0'
gem 'uglifier', '>= 1.2.3'
..
Here you basically say: "I want nokogiri as long as it’s greater than version 1.4.4", etc. Now suppose that I have set up my Gemfile
8 months ago and I successful setup my app with this requirement. 8 months ago nokogiri version was 1.4.4. My rails apps was running perfectly without any problems with this version.
Now think I'm trying to build with the same Gemfile
. But if we look at nokogiri versions we see that the current stable version has changed to 1.4.9. That means if we try to build, bundler will install version 1.4.9 of nokogiri (suppose we don't have Gemfile.lock
).
What does it mean ?
As you see if you don't have any Gemfile.lock
and run:
bundle install
then the currently used gems can be different at any time. Your app used the version 1.4.4 and it works 8 months ago without any problems, but if you try to build it now you get the version 1.4.9. Maybe it's broken with the latest version of nokogiri
, the awesome feature you used with 1.4.4 is not more available, etc..
To prevent this kind of problem Gemfile.lock
is used. In Gemfile.lock
only the exact versions are written and thus only these will be installed. That means if you distribute your app with a Gemfile.lock
, every machine will have the same gems installed and most important they all get the same version. This will give you a stable and common deployment stack.
How is Gemfile.lock created?
It is automatically created with the first:
bundle install
command. After that everytime you run bundle install
, bundle will first look up Gemfile.lock
and install the gems specified there. It's an habit to distribute this file among your projects to provide consistently and stability.
How to update Gemfile.lock?
If you're happy with the the latest version of your apps than you can update Gemfile.lock
. Just reflect your changes to Gemfile
. That means change the dependencies to the new exact versions in Gemfile
. After that run:
bundle install
This will update you Gemfile.lock
with your newest version of apps.