.gitignore for Ruby on Rails

/tmp/* /.bundle/ /log/* !/log/.keep !/tmp/.keep /storage/* /public/assets/ /app/assets/builds/* /config/master.key

A Rails .gitignore empties log/, tmp/ and storage/ but keeps their .keep files, ignores compiled assets in public/assets/ and app/assets/builds/, Bundler’s local .bundle/, and config/master.key, the key to your encrypted credentials. Those are the key lines of the tool’s Ruby and Ruby on Rails templates picked together, 36 lines in all.

What the blocks ignore

  • Ruby: built *.gem files, /.bundle/ and /vendor/bundle/, /coverage/, test reports and /tmp/*.
  • Runtime files: /log/*, /tmp/* with /tmp/pids/*, and /storage/*, where Active Storage and development SQLite databases live.
  • Assets: /public/assets/ from assets:precompile, the old Webpacker /public/packs/, and /app/assets/builds/*, written by cssbundling-rails, jsbundling-rails and tailwindcss-rails.
  • Keys: /config/master.key and /config/credentials/*.key.

In a scratch repository with this file, git check-ignore -v -n --no-index names the line that matched each path, or prints :: when none did:

.gitignore:47:/config/master.key	config/master.key
::	config/credentials.yml.enc
::	Gemfile.lock
.gitignore:26:/log/*	log/development.log
.gitignore:27:!/log/.keep	log/.keep
.gitignore:28:!/tmp/.keep	tmp/.keep
.gitignore:30:/tmp/pids/*	tmp/pids/server.pid
.gitignore:32:!/tmp/pids/.keep	tmp/pids/.keep
.gitignore:44:/app/assets/builds/*	app/assets/builds/application.css
::	.env

Commit the encrypted file, never the key

config/credentials.yml.enc is encrypted and meant to be committed; config/master.key decrypts it and must not be. In production, Rails reads the key from RAILS_MASTER_KEY instead. Commit Gemfile.lock too. The template doesn’t ignore .env: if you use dotenv, add it as a custom line.

Why /tmp/* and not /tmp/

The log, tmp and storage lines end in /* on purpose. /tmp/ would exclude the folder itself, and Git never looks inside an excluded folder, so !/tmp/.keep couldn’t work. With the Ruby line written as /tmp/ instead:

.gitignore:14:/tmp/	tmp/.keep
.gitignore:14:/tmp/	tmp/pids/.keep

tmp/pids/ needs one more step for the same reason: /tmp/* excludes it as a folder, so !/tmp/pids/ re-includes it before !/tmp/pids/.keep can apply.

The leading slash means “next to this file”

Each line is anchored to the folder the .gitignore sits in. If the app lives in api/ inside a larger repository, a root file leaves api/log/development.log and even api/config/master.key unmatched (::); put this file in api/.

Committed master.key or logs?

.gitignore only affects untracked files. Untrack them, keeping them on disk, then add the folders back, which brings back only the .keep files, and commit:

git rm -r --cached config/master.key log tmp
git add log tmp
git commit -m "Stop tracking the key and runtime files"

A key that was ever pushed stays in the history: treat it as leaked and replace it.

Editor and OS files

.idea/, .vscode/ and .DS_Store come from your machine. Keep them in a global ignore file:

git config --global core.excludesFile ~/.gitignore_global

Try it in the Gitignore Generator

In the file: Ruby, Ruby on Rails

.gitignore

2 templates · 36 pattern lines · 3 duplicates dropped
# Ruby
# Packages written by gem build
*.gem
*.rbc
/.config
/coverage/
/InstalledFiles
/pkg/
/spec/reports/
/spec/examples.txt
/test/tmp/
/test/version_tmp/
# What's in tmp/, not the folder itself, so Rails can keep its tmp/.keep files
/tmp/*
# The debugger's command history, which repeats what you typed
.byebug_history
# Gems installed into the project rather than the system
/vendor/bundle/
/.bundle/
/lib/bundler/man/
.rake_tasks~
.rvmrc

# Ruby on Rails
# Logs, with the .keep file that holds the directory open
/log/*
!/log/.keep
!/tmp/.keep
# Pid files go, but the directory stays: Git only looks inside a directory it has re-included
/tmp/pids/*
!/tmp/pids/
!/tmp/pids/.keep
# Active Storage files, written at runtime
/storage/*
!/storage/.keep
/tmp/storage/*
!/tmp/storage/
!/tmp/storage/.keep
# Precompiled assets; rebuild them with rails assets:precompile
/public/assets/
/public/packs/
/public/packs-test/
# CSS and JavaScript built by cssbundling-rails, jsbundling-rails or tailwindcss-rails
/app/assets/builds/*
!/app/assets/builds/.keep
# The key that decrypts config/credentials.yml.enc
/config/master.key
/config/credentials/*.key
capybara-email.log
  • ✓Not ignored: no line in this file matches "/config/credentials.yml.enc".

Lines are applied top to bottom, and the last one that matches wins — which is why a line of your own can overrule a template.

Runs in your browser. Nothing you enter is sent anywhere.